paul@9 | 1 | # -*- coding: iso-8859-1 -*- |
paul@9 | 2 | """ |
paul@9 | 3 | MoinMoin - SharedUpdate Action |
paul@9 | 4 | |
paul@9 | 5 | @copyright: 2012 by Paul Boddie <paul@boddie.org.uk> |
paul@9 | 6 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@9 | 7 | """ |
paul@9 | 8 | |
paul@9 | 9 | from MoinMoin.action import ActionBase |
paul@9 | 10 | from MoinMoin import wikiutil |
paul@9 | 11 | from MoinShare import * |
paul@9 | 12 | |
paul@9 | 13 | Dependencies = ['pages'] |
paul@9 | 14 | |
paul@9 | 15 | # Action class and supporting functions. |
paul@9 | 16 | |
paul@9 | 17 | class SharedUpdate(ActionBase, ActionSupport): |
paul@9 | 18 | |
paul@9 | 19 | "A summary dialogue requesting various parameters." |
paul@9 | 20 | |
paul@9 | 21 | def get_form_html(self, buttons_html): |
paul@9 | 22 | _ = self._ |
paul@9 | 23 | request = self.request |
paul@9 | 24 | form = self.get_form() |
paul@9 | 25 | page = self.page |
paul@9 | 26 | |
paul@9 | 27 | pagename = form.get("pagename", [page.page_name])[0] |
paul@9 | 28 | fragment = form.get("fragment", [""])[0] |
paul@9 | 29 | mimetype = form.get("type", [""])[0] |
paul@9 | 30 | |
paul@9 | 31 | d = { |
paul@9 | 32 | "buttons_html" : buttons_html, |
paul@9 | 33 | "pagename_label" : escape(_("Page name for updates")), |
paul@9 | 34 | "pagename" : escattr(pagename), |
paul@9 | 35 | "fragment_label" : escape(_("Fragment to download")), |
paul@9 | 36 | "fragment" : escattr(fragment), |
paul@9 | 37 | "mimetype_label" : escape(_("Content/media type")), |
paul@9 | 38 | "mimetype" : escattr(mimetype), |
paul@9 | 39 | } |
paul@9 | 40 | |
paul@9 | 41 | return ''' |
paul@9 | 42 | <table> |
paul@9 | 43 | <tr> |
paul@9 | 44 | <td class="label"><label>%(pagename_label)s</label></td> |
paul@9 | 45 | <td class="content"> |
paul@9 | 46 | <input name="pagename" type="text" size="40" value="%(pagename)s" /> |
paul@9 | 47 | </td> |
paul@9 | 48 | </tr> |
paul@9 | 49 | <tr> |
paul@9 | 50 | <td class="label"><label>%(fragment_label)s</label></td> |
paul@9 | 51 | <td class="content"> |
paul@9 | 52 | <input name="fragment" type="text" size="40" value="%(fragment)s" /> |
paul@9 | 53 | </td> |
paul@9 | 54 | </tr> |
paul@9 | 55 | <tr> |
paul@9 | 56 | <td class="label"><label>%(mimetype_label)s</label></td> |
paul@9 | 57 | <td class="content"> |
paul@9 | 58 | <input name="type" type="text" size="40" value="%(mimetype)s" /> |
paul@9 | 59 | </td> |
paul@9 | 60 | </tr> |
paul@9 | 61 | <tr> |
paul@9 | 62 | <td></td> |
paul@9 | 63 | <td class="buttons"> |
paul@9 | 64 | %(buttons_html)s |
paul@9 | 65 | </td> |
paul@9 | 66 | </tr> |
paul@9 | 67 | </table> |
paul@9 | 68 | ''' % d |
paul@9 | 69 | |
paul@9 | 70 | def do_action(self): |
paul@9 | 71 | |
paul@9 | 72 | "Write the syndication resource." |
paul@9 | 73 | |
paul@9 | 74 | _ = self._ |
paul@9 | 75 | form = self.get_form() |
paul@9 | 76 | |
paul@9 | 77 | # If no fragment exists in the request, an error message is returned. |
paul@9 | 78 | |
paul@9 | 79 | fragment = form.get("fragment") |
paul@9 | 80 | |
paul@9 | 81 | if not fragment: |
paul@9 | 82 | return 0, _("No fragment to download specified.") |
paul@9 | 83 | |
paul@9 | 84 | write_resource(self.request) |
paul@9 | 85 | return 1, None |
paul@9 | 86 | |
paul@9 | 87 | def render_success(self, msg, msgtype=None): |
paul@9 | 88 | |
paul@9 | 89 | """ |
paul@9 | 90 | Render neither 'msg' nor 'msgtype' since a resource has already been |
paul@9 | 91 | produced. |
paul@9 | 92 | NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. |
paul@9 | 93 | """ |
paul@9 | 94 | |
paul@9 | 95 | pass |
paul@9 | 96 | |
paul@9 | 97 | def write_resource(request): |
paul@9 | 98 | |
paul@9 | 99 | """ |
paul@9 | 100 | For the given 'request', write the requested fragment with the specified |
paul@9 | 101 | content/media type (or use content negotiation to choose a media type). |
paul@9 | 102 | """ |
paul@9 | 103 | |
paul@9 | 104 | form = get_form(request) |
paul@9 | 105 | |
paul@9 | 106 | pagename = form.get("pagename", [request.page.page_name])[0] |
paul@9 | 107 | fragment = form.get("fragment", [None])[0] |
paul@9 | 108 | mimetype = form.get("type", [None])[0] |
paul@9 | 109 | |
paul@9 | 110 | page = Page(request, pagename) |
paul@9 | 111 | metadata = getMetadata(page) |
paul@9 | 112 | |
paul@9 | 113 | # Set the default error status. |
paul@9 | 114 | |
paul@9 | 115 | status = "404 Not Found" |
paul@9 | 116 | |
paul@9 | 117 | # Get the fragment regions for the page, trying to find the requested |
paul@9 | 118 | # fragment. |
paul@9 | 119 | |
paul@9 | 120 | for n, (format, attributes, body) in enumerate(getFragments(page.get_raw_body())): |
paul@9 | 121 | |
paul@9 | 122 | # Produce a fragment identifier. |
paul@9 | 123 | # NOTE: Choose a more robust identifier where none is explicitly given. |
paul@9 | 124 | |
paul@9 | 125 | region_fragment = attributes.get("fragment", str(n)) |
paul@9 | 126 | |
paul@9 | 127 | # Check the region's fragment identifier. |
paul@9 | 128 | |
paul@9 | 129 | if fragment != region_fragment: |
paul@9 | 130 | continue |
paul@9 | 131 | |
paul@9 | 132 | # Check the mimetype availability. |
paul@9 | 133 | |
paul@9 | 134 | mimetypes = getOutputTypes(request, format) |
paul@9 | 135 | |
paul@9 | 136 | # Perform content negotiation if no mimetype was specified. |
paul@9 | 137 | |
paul@9 | 138 | if mimetype is None: |
paul@10 | 139 | mimetypes = getPreferredOutputTypes(request, mimetypes) |
paul@10 | 140 | if mimetypes: |
paul@10 | 141 | mimetype = mimetypes[0] |
paul@9 | 142 | |
paul@9 | 143 | # Where no suitable mimetype is found, break out of the loop and return |
paul@9 | 144 | # an error. |
paul@9 | 145 | |
paul@10 | 146 | if not mimetypes or mimetype not in mimetypes: |
paul@9 | 147 | status = "406 Not Acceptable" |
paul@9 | 148 | break |
paul@9 | 149 | |
paul@9 | 150 | # Define headers. |
paul@9 | 151 | |
paul@9 | 152 | writeHeaders(request, mimetype, metadata) |
paul@9 | 153 | updated = getUpdatedTime(metadata) |
paul@9 | 154 | |
paul@9 | 155 | # Fragment output... |
paul@9 | 156 | |
paul@9 | 157 | parser_cls = getParserClass(request, format) |
paul@9 | 158 | parser = parser_cls(body, request) |
paul@9 | 159 | |
paul@9 | 160 | if hasattr(parser, "formatForOutputType"): |
paul@9 | 161 | parser.formatForOutputType(mimetype) |
paul@9 | 162 | else: |
paul@9 | 163 | fmt = request.html_formatter |
paul@9 | 164 | parser.format(fmt) |
paul@9 | 165 | |
paul@9 | 166 | return |
paul@9 | 167 | |
paul@9 | 168 | # Error output. |
paul@9 | 169 | |
paul@9 | 170 | writeHeaders(request, "text/plain", metadata, status) |
paul@9 | 171 | request.write("Sorry, but the specified fragment %s could not be provided as type %s." % (fragment, mimetype)) |
paul@9 | 172 | |
paul@9 | 173 | # Action function. |
paul@9 | 174 | |
paul@9 | 175 | def execute(pagename, request): |
paul@9 | 176 | SharedUpdate(pagename, request).render() |
paul@9 | 177 | |
paul@9 | 178 | # vim: tabstop=4 expandtab shiftwidth=4 |