1.1 --- a/imiptools/mail.py Sun Oct 23 23:21:01 2016 +0200
1.2 +++ b/imiptools/mail.py Mon Dec 19 23:39:20 2016 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Mail preparation support.
1.6
1.7 -Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -128,41 +128,104 @@
1.13
1.14 """
1.15 Return a simple summary using details from 'msg' and the given 'parts'.
1.16 + Information messages provided amongst the parts by the handlers will be
1.17 + merged into the preamble so that mail programs will show them
1.18 + immediately.
1.19 """
1.20
1.21 - message = self._make_summary_for_parts(parts)
1.22 + message = self._make_summary_for_parts(parts, True)
1.23 self._copy_headers(message, msg)
1.24 return message
1.25
1.26 def wrap_message(self, msg, parts):
1.27
1.28 - "Wrap 'msg' and provide the given 'parts' as the primary content."
1.29 + """
1.30 + Wrap 'msg' and provide the given 'parts' as the primary content.
1.31 + Information messages provided amongst the parts by the handlers will be
1.32 + merged into the preamble so that mail programs will show them
1.33 + immediately.
1.34 + """
1.35
1.36 - message = self._make_container_for_parts(parts)
1.37 + message = self._make_container_for_parts(parts, True)
1.38 payload = message.get_payload()
1.39 payload.append(MIMEMessage(msg))
1.40 self._copy_headers(message, msg)
1.41 return message
1.42
1.43 - def _make_summary_for_parts(self, parts):
1.44 + def _make_summary_for_parts(self, parts, merge=False):
1.45
1.46 - "Return a simple summary for the given 'parts'."
1.47 + """
1.48 + Return a simple summary for the given 'parts', merging information parts if
1.49 + 'merge' is specified and set to a true value.
1.50 + """
1.51
1.52 if len(parts) == 1:
1.53 return parts[0]
1.54 else:
1.55 - return self._make_container_for_parts(parts)
1.56 + return self._make_container_for_parts(parts, merge)
1.57 +
1.58 + def _make_container_for_parts(self, parts, merge=False):
1.59 +
1.60 + """
1.61 + Return a container for the given 'parts', merging information parts if
1.62 + 'merge' is specified and set to a true value.
1.63 + """
1.64
1.65 - def _make_container_for_parts(self, parts):
1.66 + # Merge calendar information if requested.
1.67
1.68 - "Return a container for the given 'parts'."
1.69 + if merge:
1.70 + info, parts = self._merge_calendar_info_parts(parts)
1.71 + else:
1.72 + info = []
1.73 +
1.74 + # Insert a preamble message before any calendar information messages.
1.75 +
1.76 + info.insert(0, self.preamble_text or
1.77 + self.gettext and self.gettext(PREAMBLE_TEXT) or PREAMBLE_TEXT)
1.78
1.79 message = MIMEMultipart("mixed", _subparts=parts)
1.80 - message.preamble = self.preamble_text or \
1.81 - self.gettext and self.gettext(PREAMBLE_TEXT) or PREAMBLE_TEXT
1.82 + message.preamble = "\n\n".join(info)
1.83 return message
1.84
1.85 + def _merge_calendar_info_parts(self, parts):
1.86 +
1.87 + """
1.88 + Return a collection of plain text calendar information messages from
1.89 + 'parts', together with a collection of the remaining parts.
1.90 + """
1.91 +
1.92 + info = []
1.93 + remaining = []
1.94 +
1.95 + for part in parts:
1.96 +
1.97 + # Attempt to acquire informational messages.
1.98 +
1.99 + if part.get("X-IMIP-Agent") == "info":
1.100 +
1.101 + # Ignore the preamble of any multipart message and just
1.102 + # collect its parts.
1.103 +
1.104 + if part.is_multipart():
1.105 + i, r = self._merge_calendar_info_parts(part.get_payload())
1.106 + remaining += r
1.107 +
1.108 + # Obtain any single-part messages.
1.109 +
1.110 + else:
1.111 + info.append(part.get_payload(decode=True))
1.112 +
1.113 + # Accumulate other parts regardless of their purpose.
1.114 +
1.115 + else:
1.116 + remaining.append(part)
1.117 +
1.118 + return info, remaining
1.119 +
1.120 def _copy_headers(self, message, msg):
1.121 +
1.122 + "Copy to 'message' certain headers from 'msg'."
1.123 +
1.124 message["From"] = msg["From"]
1.125 message["To"] = msg["To"]
1.126 message["Subject"] = msg["Subject"]