1.1 --- a/MoinShare.py Tue Jul 09 18:44:27 2013 +0200
1.2 +++ b/MoinShare.py Wed Jul 10 18:08:15 2013 +0200
1.3 @@ -215,24 +215,29 @@
1.4 store = ItemStore(page, "messages", "message-locks")
1.5
1.6 for n, message_text in enumerate(iter(store)):
1.7 -
1.8 - update = Update()
1.9 - message = Parser().parse(StringIO(message_text))
1.10 -
1.11 - # Produce a fragment identifier.
1.12 -
1.13 - update.fragment = update.updated = getDateTimeFromRFC2822(message.get("date"))
1.14 - update.title = message.get("subject", "Update #%d" % n)
1.15 -
1.16 + update = getUpdateFromMessageText(message_text, n)
1.17 update.page = page
1.18 - update.message_number = n
1.19 -
1.20 - update.content, update.content_type, update.parts = getUpdateContentFromPart(message)
1.21 -
1.22 updates.append(update)
1.23
1.24 return updates
1.25
1.26 +def getUpdateFromMessageText(message_text, message_number):
1.27 +
1.28 + "Return an update for the given 'message_text' and 'message_number'."
1.29 +
1.30 + update = Update()
1.31 + message = Parser().parse(StringIO(message_text))
1.32 +
1.33 + # Produce a fragment identifier.
1.34 +
1.35 + update.fragment = update.updated = getDateTimeFromRFC2822(message.get("date"))
1.36 + update.title = message.get("subject", "Update #%d" % message_number)
1.37 +
1.38 + update.message_number = message_number
1.39 +
1.40 + update.content, update.content_type, update.parts = getUpdateContentFromPart(message)
1.41 + return update
1.42 +
1.43 def getUpdateContentFromPart(part):
1.44
1.45 """
1.46 @@ -256,6 +261,11 @@
1.47 content, content_type = getPartContent(main_part)
1.48 return content, content_type, [main_part]
1.49
1.50 + # Encrypted content cannot be meaningfully separated.
1.51 +
1.52 + elif part.get_content_subtype() == "encrypted":
1.53 + return part.as_string(), part.get_content_type(), None
1.54 +
1.55 # Otherwise, just obtain the parts for separate display.
1.56
1.57 else:
1.58 @@ -277,6 +287,122 @@
1.59 update.content, update.content_type, update.parts = getUpdateContentFromPart(part)
1.60 return update
1.61
1.62 +def getUpdatesForFormatting(update):
1.63 +
1.64 + "Get a list of updates for formatting given 'update'."
1.65 +
1.66 + updates = []
1.67 +
1.68 + # Handle multipart/alternative and other non-related multiparts.
1.69 +
1.70 + if update.parts:
1.71 + for n, part in enumerate(update.parts):
1.72 + update_part = getUpdateFromPart(update, part, n)
1.73 + updates += getUpdatesForFormatting(update_part)
1.74 + else:
1.75 + updates.append(update)
1.76 +
1.77 + return updates
1.78 +
1.79 +# Update formatting.
1.80 +
1.81 +def getFormattedUpdate(update, request, fmt):
1.82 +
1.83 + """
1.84 + Return the formatted form of the given 'update' using the given 'request'
1.85 + and 'fmt'.
1.86 + """
1.87 +
1.88 + # NOTE: Some control over the HTML and XHTML should be exercised.
1.89 +
1.90 + if update.content:
1.91 + if update.content_type == "text/html" and update.message_number is not None:
1.92 + parsers = [get_make_parser(update.page, update.message_number)]
1.93 + else:
1.94 + parsers = getParsersForContentType(request.cfg, update.content_type)
1.95 +
1.96 + if parsers:
1.97 + for parser_cls in parsers:
1.98 + if hasattr(parser_cls, "formatForOutputType"):
1.99 + return formatTextForOutputType(update.content, request, parser_cls, "text/html")
1.100 + else:
1.101 + return formatText(update.content, request, fmt, parser_cls=parser_cls)
1.102 + break
1.103 + else:
1.104 + return None
1.105 + else:
1.106 + return None
1.107 +
1.108 +def formatUpdate(update, request, fmt):
1.109 +
1.110 + "Format the given 'update' using the given 'request' and 'fmt'."
1.111 +
1.112 + result = []
1.113 + append = result.append
1.114 +
1.115 + updates = getUpdatesForFormatting(update)
1.116 + single = len(updates) == 1
1.117 +
1.118 + # Format some navigation tabs.
1.119 +
1.120 + if not single:
1.121 + append(fmt.div(on=1, css_class="moinshare-alternatives"))
1.122 +
1.123 + first = True
1.124 +
1.125 + for update_part in updates:
1.126 + append(fmt.url(1, "#%s" % update_part.unique_id()))
1.127 + append(fmt.text(update_part.content_type))
1.128 + append(fmt.url(0))
1.129 +
1.130 + first = False
1.131 +
1.132 + append(fmt.div(on=0))
1.133 +
1.134 + # Format the content.
1.135 +
1.136 + first = True
1.137 +
1.138 + for update_part in updates:
1.139 +
1.140 + # Encapsulate each alternative if many exist.
1.141 +
1.142 + if not single:
1.143 + css_class = first and "moinshare-default" or "moinshare-other"
1.144 + append(fmt.div(on=1, css_class="moinshare-alternative %s" % css_class, id=update_part.unique_id()))
1.145 +
1.146 + # Include the content.
1.147 +
1.148 + append(formatUpdatePart(update_part, request, fmt))
1.149 +
1.150 + if not single:
1.151 + append(fmt.div(on=0))
1.152 +
1.153 + first = False
1.154 +
1.155 + return "".join(result)
1.156 +
1.157 +def formatUpdatePart(update, request, fmt):
1.158 +
1.159 + "Format the given 'update' using the given 'request' and 'fmt'."
1.160 +
1.161 + _ = request.getText
1.162 +
1.163 + result = []
1.164 + append = result.append
1.165 +
1.166 + # Encapsulate the content.
1.167 +
1.168 + append(fmt.div(on=1, css_class="moinshare-content"))
1.169 + text = getFormattedUpdate(update, request, fmt)
1.170 + if text:
1.171 + append(text)
1.172 + else:
1.173 + append(fmt.text(_("Update cannot be shown for content of type %s.") % update.content_type))
1.174 + append(fmt.div(on=0))
1.175 +
1.176 + return "".join(result)
1.177 +
1.178 # Source management.
1.179
1.180 def getUpdateSources(pagename, request):
2.1 --- a/macros/SharedContent.py Tue Jul 09 18:44:27 2013 +0200
2.2 +++ b/macros/SharedContent.py Wed Jul 10 18:08:15 2013 +0200
2.3 @@ -9,11 +9,10 @@
2.4 from DateSupport import getDateTimeFromISO8601, DateTime
2.5 from MoinMoin.Page import Page
2.6 from MoinRemoteSupport import *
2.7 -from MoinSupport import parseMacroArguments, getParsersForContentType, \
2.8 - formatText, formatTextForOutputType
2.9 +from MoinSupport import parseMacroArguments
2.10 from MoinShare import getUpdateSources, getUpdatesFromPage, \
2.11 - getUpdatesFromStore, getUpdateFromPart, \
2.12 - Update, get_make_parser
2.13 + getUpdatesFromStore, formatUpdate, \
2.14 + Update
2.15 from email.utils import parsedate
2.16 import xml.dom.pulldom
2.17
2.18 @@ -208,122 +207,6 @@
2.19
2.20 return (feed_type, channel_title, channel_link), feed_updates
2.21
2.22 -# Update formatting.
2.23 -
2.24 -def getUpdatesForFormatting(update):
2.25 -
2.26 - "Get a list of updates for formatting given 'update'."
2.27 -
2.28 - updates = []
2.29 -
2.30 - # Handle multipart/alternative.
2.31 -
2.32 - if update.parts:
2.33 - for n, part in enumerate(update.parts):
2.34 - update_part = getUpdateFromPart(update, part, n)
2.35 - updates += getUpdatesForFormatting(update_part)
2.36 - else:
2.37 - updates.append(update)
2.38 -
2.39 - return updates
2.40 -
2.41 -def getFormattedUpdate(update, request, fmt):
2.42 -
2.43 - """
2.44 - Return the formatted form of the given 'update' using the given 'request'
2.45 - and 'fmt'.
2.46 - """
2.47 -
2.48 - # NOTE: Some control over the HTML and XHTML should be exercised.
2.49 -
2.50 - if update.content:
2.51 - if update.content_type == "text/html" and update.message_number is not None:
2.52 - parsers = [get_make_parser(update.page, update.message_number)]
2.53 - else:
2.54 - parsers = getParsersForContentType(request.cfg, update.content_type)
2.55 -
2.56 - if parsers:
2.57 - for parser_cls in parsers:
2.58 - if hasattr(parser_cls, "formatForOutputType"):
2.59 - return formatTextForOutputType(update.content, request, parser_cls, "text/html")
2.60 - else:
2.61 - return formatText(update.content, request, fmt, parser_cls=parser_cls)
2.62 - break
2.63 - else:
2.64 - return None
2.65 - else:
2.66 - return None
2.67 -
2.68 -def formatUpdate(update, request, fmt):
2.69 -
2.70 - "Format the given 'update' using the given 'request' and 'fmt'."
2.71 -
2.72 - result = []
2.73 - append = result.append
2.74 -
2.75 - updates = getUpdatesForFormatting(update)
2.76 - single = len(updates) == 1
2.77 -
2.78 - # Format some navigation tabs.
2.79 -
2.80 - if not single:
2.81 - append(fmt.div(on=1, css_class="moinshare-alternatives"))
2.82 -
2.83 - first = True
2.84 -
2.85 - for update_part in updates:
2.86 - append(fmt.url(1, "#%s" % update_part.unique_id()))
2.87 - append(fmt.text(update_part.content_type))
2.88 - append(fmt.url(0))
2.89 -
2.90 - first = False
2.91 -
2.92 - append(fmt.div(on=0))
2.93 -
2.94 - # Format the content.
2.95 -
2.96 - first = True
2.97 -
2.98 - for update_part in updates:
2.99 -
2.100 - # Encapsulate each alternative if many exist.
2.101 -
2.102 - if not single:
2.103 - css_class = first and "moinshare-default" or "moinshare-other"
2.104 - append(fmt.div(on=1, css_class="moinshare-alternative %s" % css_class, id=update_part.unique_id()))
2.105 -
2.106 - # Include the content.
2.107 -
2.108 - append(formatUpdatePart(update_part, request, fmt))
2.109 -
2.110 - if not single:
2.111 - append(fmt.div(on=0))
2.112 -
2.113 - first = False
2.114 -
2.115 - return "".join(result)
2.116 -
2.117 -def formatUpdatePart(update, request, fmt):
2.118 -
2.119 - "Format the given 'update' using the given 'request' and 'fmt'."
2.120 -
2.121 - _ = request.getText
2.122 -
2.123 - result = []
2.124 - append = result.append
2.125 -
2.126 - # Encapsulate the content.
2.127 -
2.128 - append(fmt.div(on=1, css_class="moinshare-content"))
2.129 - text = getFormattedUpdate(update, request, fmt)
2.130 - if text:
2.131 - append(text)
2.132 - else:
2.133 - append(fmt.text(_("Update cannot be shown for content of type %s.") % update.content_type))
2.134 - append(fmt.div(on=0))
2.135 -
2.136 - return "".join(result)
2.137 -
2.138 # The macro itself.
2.139
2.140 def execute(macro, args):