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):