# HG changeset patch # User Paul Boddie # Date 1373472495 -7200 # Node ID b05b1aa058dec1105e445b202b0081e9e58c6605 # Parent 776eb45a27d78dedf99f61e8679109e00d910084 Moved various functions into the MoinShare library. Added explicit support for multipart/encrypted content. diff -r 776eb45a27d7 -r b05b1aa058de MoinShare.py --- a/MoinShare.py Tue Jul 09 18:44:27 2013 +0200 +++ b/MoinShare.py Wed Jul 10 18:08:15 2013 +0200 @@ -215,24 +215,29 @@ store = ItemStore(page, "messages", "message-locks") for n, message_text in enumerate(iter(store)): - - update = Update() - message = Parser().parse(StringIO(message_text)) - - # Produce a fragment identifier. - - update.fragment = update.updated = getDateTimeFromRFC2822(message.get("date")) - update.title = message.get("subject", "Update #%d" % n) - + update = getUpdateFromMessageText(message_text, n) update.page = page - update.message_number = n - - update.content, update.content_type, update.parts = getUpdateContentFromPart(message) - updates.append(update) return updates +def getUpdateFromMessageText(message_text, message_number): + + "Return an update for the given 'message_text' and 'message_number'." + + update = Update() + message = Parser().parse(StringIO(message_text)) + + # Produce a fragment identifier. + + update.fragment = update.updated = getDateTimeFromRFC2822(message.get("date")) + update.title = message.get("subject", "Update #%d" % message_number) + + update.message_number = message_number + + update.content, update.content_type, update.parts = getUpdateContentFromPart(message) + return update + def getUpdateContentFromPart(part): """ @@ -256,6 +261,11 @@ content, content_type = getPartContent(main_part) return content, content_type, [main_part] + # Encrypted content cannot be meaningfully separated. + + elif part.get_content_subtype() == "encrypted": + return part.as_string(), part.get_content_type(), None + # Otherwise, just obtain the parts for separate display. else: @@ -277,6 +287,122 @@ update.content, update.content_type, update.parts = getUpdateContentFromPart(part) return update +def getUpdatesForFormatting(update): + + "Get a list of updates for formatting given 'update'." + + updates = [] + + # Handle multipart/alternative and other non-related multiparts. + + if update.parts: + for n, part in enumerate(update.parts): + update_part = getUpdateFromPart(update, part, n) + updates += getUpdatesForFormatting(update_part) + else: + updates.append(update) + + return updates + +# Update formatting. + +def getFormattedUpdate(update, request, fmt): + + """ + Return the formatted form of the given 'update' using the given 'request' + and 'fmt'. + """ + + # NOTE: Some control over the HTML and XHTML should be exercised. + + if update.content: + if update.content_type == "text/html" and update.message_number is not None: + parsers = [get_make_parser(update.page, update.message_number)] + else: + parsers = getParsersForContentType(request.cfg, update.content_type) + + if parsers: + for parser_cls in parsers: + if hasattr(parser_cls, "formatForOutputType"): + return formatTextForOutputType(update.content, request, parser_cls, "text/html") + else: + return formatText(update.content, request, fmt, parser_cls=parser_cls) + break + else: + return None + else: + return None + +def formatUpdate(update, request, fmt): + + "Format the given 'update' using the given 'request' and 'fmt'." + + result = [] + append = result.append + + updates = getUpdatesForFormatting(update) + single = len(updates) == 1 + + # Format some navigation tabs. + + if not single: + append(fmt.div(on=1, css_class="moinshare-alternatives")) + + first = True + + for update_part in updates: + append(fmt.url(1, "#%s" % update_part.unique_id())) + append(fmt.text(update_part.content_type)) + append(fmt.url(0)) + + first = False + + append(fmt.div(on=0)) + + # Format the content. + + first = True + + for update_part in updates: + + # Encapsulate each alternative if many exist. + + if not single: + css_class = first and "moinshare-default" or "moinshare-other" + append(fmt.div(on=1, css_class="moinshare-alternative %s" % css_class, id=update_part.unique_id())) + + # Include the content. + + append(formatUpdatePart(update_part, request, fmt)) + + if not single: + append(fmt.div(on=0)) + + first = False + + return "".join(result) + +def formatUpdatePart(update, request, fmt): + + "Format the given 'update' using the given 'request' and 'fmt'." + + _ = request.getText + + result = [] + append = result.append + + # Encapsulate the content. + + append(fmt.div(on=1, css_class="moinshare-content")) + text = getFormattedUpdate(update, request, fmt) + if text: + append(text) + else: + append(fmt.text(_("Update cannot be shown for content of type %s.") % update.content_type)) + append(fmt.div(on=0)) + + return "".join(result) + # Source management. def getUpdateSources(pagename, request): diff -r 776eb45a27d7 -r b05b1aa058de macros/SharedContent.py --- a/macros/SharedContent.py Tue Jul 09 18:44:27 2013 +0200 +++ b/macros/SharedContent.py Wed Jul 10 18:08:15 2013 +0200 @@ -9,11 +9,10 @@ from DateSupport import getDateTimeFromISO8601, DateTime from MoinMoin.Page import Page from MoinRemoteSupport import * -from MoinSupport import parseMacroArguments, getParsersForContentType, \ - formatText, formatTextForOutputType +from MoinSupport import parseMacroArguments from MoinShare import getUpdateSources, getUpdatesFromPage, \ - getUpdatesFromStore, getUpdateFromPart, \ - Update, get_make_parser + getUpdatesFromStore, formatUpdate, \ + Update from email.utils import parsedate import xml.dom.pulldom @@ -208,122 +207,6 @@ return (feed_type, channel_title, channel_link), feed_updates -# Update formatting. - -def getUpdatesForFormatting(update): - - "Get a list of updates for formatting given 'update'." - - updates = [] - - # Handle multipart/alternative. - - if update.parts: - for n, part in enumerate(update.parts): - update_part = getUpdateFromPart(update, part, n) - updates += getUpdatesForFormatting(update_part) - else: - updates.append(update) - - return updates - -def getFormattedUpdate(update, request, fmt): - - """ - Return the formatted form of the given 'update' using the given 'request' - and 'fmt'. - """ - - # NOTE: Some control over the HTML and XHTML should be exercised. - - if update.content: - if update.content_type == "text/html" and update.message_number is not None: - parsers = [get_make_parser(update.page, update.message_number)] - else: - parsers = getParsersForContentType(request.cfg, update.content_type) - - if parsers: - for parser_cls in parsers: - if hasattr(parser_cls, "formatForOutputType"): - return formatTextForOutputType(update.content, request, parser_cls, "text/html") - else: - return formatText(update.content, request, fmt, parser_cls=parser_cls) - break - else: - return None - else: - return None - -def formatUpdate(update, request, fmt): - - "Format the given 'update' using the given 'request' and 'fmt'." - - result = [] - append = result.append - - updates = getUpdatesForFormatting(update) - single = len(updates) == 1 - - # Format some navigation tabs. - - if not single: - append(fmt.div(on=1, css_class="moinshare-alternatives")) - - first = True - - for update_part in updates: - append(fmt.url(1, "#%s" % update_part.unique_id())) - append(fmt.text(update_part.content_type)) - append(fmt.url(0)) - - first = False - - append(fmt.div(on=0)) - - # Format the content. - - first = True - - for update_part in updates: - - # Encapsulate each alternative if many exist. - - if not single: - css_class = first and "moinshare-default" or "moinshare-other" - append(fmt.div(on=1, css_class="moinshare-alternative %s" % css_class, id=update_part.unique_id())) - - # Include the content. - - append(formatUpdatePart(update_part, request, fmt)) - - if not single: - append(fmt.div(on=0)) - - first = False - - return "".join(result) - -def formatUpdatePart(update, request, fmt): - - "Format the given 'update' using the given 'request' and 'fmt'." - - _ = request.getText - - result = [] - append = result.append - - # Encapsulate the content. - - append(fmt.div(on=1, css_class="moinshare-content")) - text = getFormattedUpdate(update, request, fmt) - if text: - append(text) - else: - append(fmt.text(_("Update cannot be shown for content of type %s.") % update.content_type)) - append(fmt.div(on=0)) - - return "".join(result) - # The macro itself. def execute(macro, args):