1.1 --- a/imip_manager.py Tue Oct 28 00:09:07 2014 +0100
1.2 +++ b/imip_manager.py Tue Oct 28 00:09:46 2014 +0100
1.3 @@ -4,7 +4,7 @@
1.4
1.5 sys.path.append("/var/lib/imip-agent")
1.6
1.7 -from imiptools import make_message, sendmail
1.8 +from imiptools import Messenger
1.9 from imiptools.content import Handler, \
1.10 format_datetime, get_address, get_datetime, \
1.11 get_item, get_uri, get_utc_datetime, get_values, \
1.12 @@ -67,10 +67,12 @@
1.13
1.14 "A content handler for use by the manager."
1.15
1.16 - def __init__(self, details, objtype, user):
1.17 + def __init__(self, details, objtype, user, messenger):
1.18 Handler.__init__(self, details)
1.19 self.objtype = objtype
1.20 self.user = user
1.21 + self.messenger = messenger
1.22 +
1.23 self.organisers = map(get_address, self.get_values("ORGANIZER"))
1.24
1.25 # Communication methods.
1.26 @@ -82,12 +84,10 @@
1.27 given 'sender'.
1.28 """
1.29
1.30 - # NOTE: Should parameterise the subject and body text.
1.31 -
1.32 node = to_node({self.objtype : [(self.details, {})]})
1.33 part = to_part("REPLY", [node])
1.34 - message = make_message([part], self.organisers, sender, "Response to request", "Response to a calendar request")
1.35 - sendmail(sender, self.organisers, message.as_string())
1.36 + message = self.messenger.make_message([part], self.organisers)
1.37 + self.messenger.sendmail(self.organisers, message.as_string())
1.38
1.39 # Action methods.
1.40
1.41 @@ -128,7 +128,9 @@
1.42
1.43 "A simple manager application."
1.44
1.45 - def __init__(self):
1.46 + def __init__(self, messenger=None):
1.47 + self.messenger = messenger or Messenger()
1.48 +
1.49 self.env = CGIEnvironment()
1.50 user = self.env.get_user()
1.51 self.user = user and get_uri(user) or None
1.52 @@ -221,7 +223,7 @@
1.53
1.54 if accept or decline:
1.55
1.56 - handler = ManagerHandler(request, objtype, self.user)
1.57 + handler = ManagerHandler(request, objtype, self.user, self.messenger)
1.58
1.59 if handler.process_request(accept):
1.60
1.61 @@ -302,7 +304,7 @@
1.62 else:
1.63 self.no_page()
1.64
1.65 - def show(self):
1.66 + def __call__(self):
1.67
1.68 "Interpret a request and show an appropriate response."
1.69
1.70 @@ -318,6 +320,6 @@
1.71 self.out.write(unicode(self.page).encode(self.encoding))
1.72
1.73 if __name__ == "__main__":
1.74 - Manager().show()
1.75 + Manager()()
1.76
1.77 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imiptools/__init__.py Tue Oct 28 00:09:07 2014 +0100
2.2 +++ b/imiptools/__init__.py Tue Oct 28 00:09:46 2014 +0100
2.3 @@ -27,29 +27,6 @@
2.4 "text/x-vcalendar", "application/ics", # other possibilities
2.5 ]
2.6
2.7 -# Sending of outgoing messages.
2.8 -
2.9 -def sendmail(sender, recipients, data, lmtp_socket=None):
2.10 - if lmtp_socket:
2.11 - smtp = LMTP(lmtp_socket)
2.12 - else:
2.13 - smtp = SMTP("localhost")
2.14 - smtp.sendmail(sender, recipients, data)
2.15 - smtp.quit()
2.16 -
2.17 -def make_message(parts, recipients, sender, subject, body_text):
2.18 - message = MIMEMultipart("mixed", _subparts=parts)
2.19 - message.preamble = body_text
2.20 - payload = message.get_payload()
2.21 - payload.insert(0, MIMEText(body_text))
2.22 -
2.23 - message["From"] = sender
2.24 - for recipient in recipients:
2.25 - message["To"] = recipient
2.26 - message["Subject"] = subject
2.27 -
2.28 - return message
2.29 -
2.30 # Processing of incoming messages.
2.31
2.32 def get_all_values(msg, key):
2.33 @@ -58,15 +35,68 @@
2.34 l += [s.strip() for s in v.split(",")]
2.35 return l
2.36
2.37 +class Messenger:
2.38 +
2.39 + "Sending of outgoing messages."
2.40 +
2.41 + def __init__(self, sender=None, subject=None, body_text=None):
2.42 + self.sender = sender or MESSAGE_SENDER
2.43 + self.subject = subject or MESSAGE_SUBJECT
2.44 + self.body_text = body_text or MESSAGE_TEXT
2.45 +
2.46 + def sendmail(self, recipients, data, lmtp_socket=None):
2.47 +
2.48 + """
2.49 + Send a mail to the given 'recipients' consisting of the given 'data',
2.50 + delivering to a local mail system using LMTP if 'lmtp_socket' is
2.51 + provided.
2.52 + """
2.53 +
2.54 + if lmtp_socket:
2.55 + smtp = LMTP(lmtp_socket)
2.56 + else:
2.57 + smtp = SMTP("localhost")
2.58 +
2.59 + smtp.sendmail(self.sender, recipients, data)
2.60 + smtp.quit()
2.61 +
2.62 + def make_message(self, parts, recipients):
2.63 +
2.64 + "Make a message from the given 'parts' for the given 'recipients'."
2.65 +
2.66 + message = MIMEMultipart("mixed", _subparts=parts)
2.67 + message.preamble = self.body_text
2.68 + payload = message.get_payload()
2.69 + payload.insert(0, MIMEText(self.body_text))
2.70 +
2.71 + message["From"] = self.sender
2.72 + for recipient in recipients:
2.73 + message["To"] = recipient
2.74 + message["Subject"] = self.subject
2.75 +
2.76 + return message
2.77 +
2.78 + def wrap_message(self, msg, parts):
2.79 +
2.80 + "Wrap 'msg' and provide the given 'parts' as the primary content."
2.81 +
2.82 + message = MIMEMultipart("mixed", _subparts=parts)
2.83 + message.preamble = self.body_text
2.84 + message.get_payload().append(MIMEMessage(msg))
2.85 +
2.86 + message["From"] = msg["From"]
2.87 + message["To"] = msg["To"]
2.88 + message["Subject"] = msg["Subject"]
2.89 +
2.90 + return message
2.91 +
2.92 class Processor:
2.93
2.94 "The processing framework."
2.95
2.96 - def __init__(self, handlers, sender=None, subject=None, body_text=None):
2.97 + def __init__(self, handlers, messenger=None):
2.98 self.handlers = handlers
2.99 - self.sender = sender or MESSAGE_SENDER
2.100 - self.subject = subject or MESSAGE_SUBJECT
2.101 - self.body_text = body_text or MESSAGE_TEXT
2.102 + self.messenger = messenger or Messenger()
2.103 self.lmtp_socket = None
2.104
2.105 def process(self, f, original_recipients, recipients):
2.106 @@ -107,22 +137,22 @@
2.107 # Reply using any outgoing parts in a new message.
2.108
2.109 if outgoing_parts:
2.110 - message = self.make_message(outgoing_parts, senders)
2.111 + message = self.messenger.make_message(outgoing_parts, senders)
2.112
2.113 if "-d" in sys.argv:
2.114 print message
2.115 else:
2.116 - sendmail(self.sender, senders, message.as_string())
2.117 + self.messenger.sendmail(senders, message.as_string())
2.118
2.119 # Forward messages to their recipients using the existing message.
2.120
2.121 if forwarded_parts:
2.122 - message = self.wrap_message(msg, forwarded_parts)
2.123 + message = self.messenger.wrap_message(msg, forwarded_parts)
2.124
2.125 if "-d" in sys.argv:
2.126 print message
2.127 elif self.lmtp_socket:
2.128 - sendmail(self.sender, original_recipients, message.as_string(), self.lmtp_socket)
2.129 + self.messenger.sendmail(original_recipients, message.as_string(), self.lmtp_socket)
2.130
2.131 # Unhandled messages are delivered as they are.
2.132
2.133 @@ -130,27 +160,7 @@
2.134 if "-d" in sys.argv:
2.135 print msg
2.136 elif self.lmtp_socket:
2.137 - sendmail(self.sender, original_recipients, msg.as_string(), self.lmtp_socket)
2.138 -
2.139 - def make_message(self, parts, recipients):
2.140 -
2.141 - "Make a message from the given 'parts' for the given 'recipients'."
2.142 -
2.143 - return make_message(parts, recipients, self.sender, self.subject, self.body_text)
2.144 -
2.145 - def wrap_message(self, msg, parts):
2.146 -
2.147 - "Wrap 'msg' and provide the given 'parts' as the primary content."
2.148 -
2.149 - message = MIMEMultipart("mixed", _subparts=parts)
2.150 - message.preamble = self.body_text
2.151 - message.get_payload().append(MIMEMessage(msg))
2.152 -
2.153 - message["From"] = msg["From"]
2.154 - message["To"] = msg["To"]
2.155 - message["Subject"] = msg["Subject"]
2.156 -
2.157 - return message
2.158 + self.messenger.sendmail(original_recipients, msg.as_string(), self.lmtp_socket)
2.159
2.160 def process_args(self, args, stream):
2.161
2.162 @@ -194,7 +204,7 @@
2.163 else:
2.164 l.append(arg)
2.165
2.166 - self.sender = senders and senders[0] or self.sender
2.167 + self.messenger.sender = senders and senders[0] or self.messenger.sender
2.168 self.lmtp_socket = lmtp and lmtp[0] or None
2.169 self.process(stream, original_recipients, recipients)
2.170
2.171 @@ -219,6 +229,8 @@
2.172 raise
2.173 type, value, tb = sys.exc_info()
2.174 print >>sys.stderr, "Exception %s at %d" % (exc, tb.tb_lineno)
2.175 + #import traceback
2.176 + #traceback.print_exc(file=open("/tmp/mail.log", "a"))
2.177 sys.exit(EX_TEMPFAIL)
2.178 sys.exit(0)
2.179