1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/actions/SharedUpdates.py Sun Jun 17 01:31:39 2012 +0200
1.3 @@ -0,0 +1,186 @@
1.4 +# -*- coding: iso-8859-1 -*-
1.5 +"""
1.6 + MoinMoin - SharedUpdates Action
1.7 +
1.8 + @copyright: 2012 by Paul Boddie <paul@boddie.org.uk>
1.9 + @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.10 +"""
1.11 +
1.12 +from MoinMoin.action import ActionBase
1.13 +from MoinMoin import config
1.14 +from MoinMoin import wikiutil
1.15 +from MoinShare import *
1.16 +from DateSupport import getCurrentTime
1.17 +
1.18 +Dependencies = ['pages']
1.19 +
1.20 +# Action class and supporting functions.
1.21 +
1.22 +class SharedUpdates(ActionBase, ActionSupport):
1.23 +
1.24 + "A summary dialogue requesting various parameters."
1.25 +
1.26 + def get_form_html(self, buttons_html):
1.27 + _ = self._
1.28 + request = self.request
1.29 + form = self.get_form()
1.30 + page = self.page
1.31 +
1.32 + pagename = form.get("pagename", [page.page_name])[0]
1.33 +
1.34 + d = {
1.35 + "buttons_html" : buttons_html,
1.36 + "pagename_label" : escape(_("Page name for updates")),
1.37 + "pagename" : escattr(pagename),
1.38 + }
1.39 +
1.40 + return '''
1.41 +<table>
1.42 + <tr>
1.43 + <td class="label"><label>%(pagename_label)s</label></td>
1.44 + <td class="content">
1.45 + <input name="pagename" type="text" size="40" value="%(pagename)s" />
1.46 + </td>
1.47 + </tr>
1.48 + <tr>
1.49 + <td></td>
1.50 + <td class="buttons">
1.51 + %(buttons_html)s
1.52 + </td>
1.53 + </tr>
1.54 +</table>
1.55 +''' % d
1.56 +
1.57 + def do_action(self):
1.58 +
1.59 + "Write the syndication resource."
1.60 +
1.61 + _ = self._
1.62 + form = self.get_form()
1.63 +
1.64 + # If no page name exists in the request, an error message is returned.
1.65 +
1.66 + pagename = form.get("pagename", [])
1.67 +
1.68 + if not pagename:
1.69 + return 0, _("No page name for updates specified.")
1.70 +
1.71 + write_resource(self.request)
1.72 + return 1, None
1.73 +
1.74 + def render_success(self, msg, msgtype=None):
1.75 +
1.76 + """
1.77 + Render neither 'msg' nor 'msgtype' since a resource has already been
1.78 + produced.
1.79 + NOTE: msgtype is optional because MoinMoin 1.5.x does not support it.
1.80 + """
1.81 +
1.82 + pass
1.83 +
1.84 +def write_resource(request):
1.85 +
1.86 + """
1.87 + For the given 'request', write an Atom summary of updates found on the
1.88 + specified page.
1.89 + See: http://tools.ietf.org/html/rfc4287
1.90 + """
1.91 +
1.92 + form = get_form(request)
1.93 +
1.94 + pagename = form.get("pagename")[0]
1.95 +
1.96 + # Output summary data...
1.97 +
1.98 + send_headers = get_send_headers(request)
1.99 +
1.100 + # Define headers.
1.101 +
1.102 + headers = ["Content-Type: application/atom+xml; charset=%s" % config.charset]
1.103 +
1.104 + # Define the last modified time.
1.105 + # NOTE: We could get edits since a certain time and only process those.
1.106 +
1.107 + page = Page(request, pagename)
1.108 + metadata = getMetadata(page)
1.109 +
1.110 + if metadata.has_key("last-modified"):
1.111 + latest_timestamp = metadata["last-modified"]
1.112 + headers.append("Last-Modified: %s" % latest_timestamp.as_HTTP_datetime_string())
1.113 + updated = latest_timestamp.as_ISO8601_datetime_string()
1.114 + else:
1.115 + updated = getCurrentTime().as_ISO8601_datetime_string()
1.116 +
1.117 + send_headers(headers)
1.118 +
1.119 + # Atom output...
1.120 +
1.121 + # Using the page name and the page URL in the title, link and
1.122 + # subtitle.
1.123 +
1.124 + path_info = getPathInfo(request)
1.125 + link = "%s%s" % (request.getBaseURL(), path_info)
1.126 +
1.127 + d = {
1.128 + "title" : escape(path_info[1:]),
1.129 + "link" : escape(link),
1.130 + "href" : escattr(link),
1.131 + "updated" : escape(updated),
1.132 + }
1.133 +
1.134 + request.write('''\
1.135 +<?xml version="1.0" encoding="utf-8"?>\r
1.136 + <feed xmlns="http://www.w3.org/2005/Atom">\r
1.137 + <title type="text">%(title)s</title>\r
1.138 + <subtitle type="text">Shared updates published on %(link)s</subtitle>\r
1.139 + <link rel="self" href="%(href)s"/>\r
1.140 + <updated>%(updated)s</updated>\r
1.141 +''' % d)
1.142 +
1.143 + # Get the fragment regions for the page.
1.144 +
1.145 + for n, (format, attributes, body) in enumerate(getFragments(page.get_raw_body())):
1.146 +
1.147 + # Produce a fragment identifier.
1.148 + # NOTE: Choose a more robust identifier where none is explicitly given.
1.149 +
1.150 + fragment = attributes.get("fragment", str(n))
1.151 + summary = attributes.get("summary", "Update #%d" % n)
1.152 +
1.153 + # Get the URL that yields only the fragment.
1.154 +
1.155 + fragment_link = "%s?action=ShowUpdate&fragment=%s" % (link, fragment)
1.156 +
1.157 + request.write('<entry>\r\n')
1.158 + request.write('<title>%s</title>\r\n' % escape(summary))
1.159 + request.write('<id>%s</id>\r\n' % escape(fragment_link))
1.160 +
1.161 + # Get the types available for the fragment.
1.162 + # This uses an extended parser API method if available.
1.163 +
1.164 + parser = getParserClass(request, format)
1.165 + if hasattr(parser, "getOutputTypes"):
1.166 + mimetypes = parser.getOutputTypes()
1.167 + else:
1.168 + mimetypes = ["text/html"]
1.169 +
1.170 + for mimetype in mimetypes:
1.171 + specific_link = "%s&mimetype=%s" % (fragment_link, mimetype)
1.172 +
1.173 + request.write('<link rel="alternate" type="%s" href="%s"/>\r\n' % (
1.174 + escattr(mimetype), escattr(specific_link)))
1.175 +
1.176 + # NOTE: Could potentially get a summary for the fragment.
1.177 + # NOTE: The published and updated details would need to be deduced from
1.178 + # NOTE: the page history.
1.179 +
1.180 + request.write('</entry>\r\n')
1.181 +
1.182 + request.write('</feed>\r\n')
1.183 +
1.184 +# Action function.
1.185 +
1.186 +def execute(pagename, request):
1.187 + SharedUpdates(pagename, request).render()
1.188 +
1.189 +# vim: tabstop=4 expandtab shiftwidth=4