1.1 --- a/imip_agent.py Mon Sep 22 18:26:59 2014 +0200
1.2 +++ b/imip_agent.py Mon Sep 22 18:28:56 2014 +0200
1.3 @@ -1,7 +1,9 @@
1.4 #!/usr/bin/env python
1.5
1.6 from email import message_from_file
1.7 -from vCalendar import parse, iterwrite
1.8 +from email.mime.text import MIMEText
1.9 +from smtplib import SMTP
1.10 +from vCalendar import parse, iterwrite, ParseError, SECTION_TYPES
1.11 import imip_store
1.12 import sys
1.13
1.14 @@ -35,7 +37,21 @@
1.15 "text/x-vcalendar", "application/ics", # other possibilities
1.16 ]
1.17
1.18 +# Sending of outgoing messages.
1.19 +
1.20 +def sendmail(sender, recipients, data):
1.21 + smtp = SMTP("localhost")
1.22 + smtp.sendmail(sender, recipients, data)
1.23 + smtp.quit()
1.24 +
1.25 +# Processing of incoming messages.
1.26 +
1.27 def process(f, args):
1.28 +
1.29 + "Process content from the stream 'f' accompanied by the given 'args'."
1.30 +
1.31 + recipient = args[0]
1.32 +
1.33 msg = message_from_file(f)
1.34 print >>open("/tmp/imip.txt", "a"), "----"
1.35 print >>open("/tmp/imip.txt", "a"), args
1.36 @@ -49,25 +65,23 @@
1.37 if part.get_content_type() in itip_content_types and \
1.38 part.get_param("method"):
1.39
1.40 - handle_itip_part(part)
1.41 + handle_itip_part(part, recipient)
1.42
1.43 def get_itip_elements(elements):
1.44 d = {}
1.45 for name, attr, value in elements:
1.46 - if isinstance(value, list):
1.47 - d[name] = attr, get_itip_elements(value)
1.48 + if not d.has_key(name):
1.49 + d[name] = []
1.50 + if name in SECTION_TYPES:
1.51 + d[name].append((attr, get_itip_elements(value)))
1.52 else:
1.53 - if not d.has_key(name):
1.54 - d[name] = []
1.55 d[name].append((attr, value))
1.56 return d
1.57
1.58 def get_attr_value(d, name, single=True):
1.59 if d.has_key(name):
1.60 values = d[name]
1.61 - if isinstance(values, tuple):
1.62 - return values
1.63 - elif single and len(values) == 1:
1.64 + if single and len(values) == 1:
1.65 return values[0]
1.66 else:
1.67 return values
1.68 @@ -77,36 +91,51 @@
1.69 def get_value(d, name, single=True):
1.70 if d.has_key(name):
1.71 values = d[name]
1.72 - if isinstance(values, tuple):
1.73 - return values[1]
1.74 - elif single and len(values) == 1:
1.75 + if single and len(values) == 1:
1.76 return values[0][1]
1.77 else:
1.78 return map(lambda x: x[1], values)
1.79 else:
1.80 return None
1.81
1.82 -def handle_itip_part(part):
1.83 +def handle_itip_part(part, recipient):
1.84 method = part.get_param("method")
1.85
1.86 + # Decode the data and parse it.
1.87 +
1.88 f = StringIO(part.get_payload(decode=True))
1.89 - doctype, attrs, elements = parse(f, encoding=part.get_content_charset())
1.90 +
1.91 + try:
1.92 + doctype, attrs, elements = parse(f, encoding=part.get_content_charset())
1.93 + except (ParseError, ValueError):
1.94 + sys.exit(EX_DATAERR)
1.95 +
1.96 + # Only handle calendar information.
1.97
1.98 if doctype == "VCALENDAR":
1.99 itip = get_itip_elements(elements)
1.100
1.101 + # Require consistency between declared and employed methods.
1.102 +
1.103 if get_value(itip, "METHOD") == method:
1.104
1.105 + # Look for different kinds of sections.
1.106 +
1.107 for name, cls in handlers:
1.108 - details = get_value(itip, name)
1.109 + for details in get_value(itip, name, False) or []:
1.110 +
1.111 + # Dispatch to a handler and obtain any response.
1.112
1.113 - if details:
1.114 - print >>open("/tmp/imip.txt", "a"), details
1.115 handler = cls(details)
1.116 - print >>open("/tmp/imip.txt", "a"), "Handling", method, "with", handler, "->", methods[method](handler)
1.117 - methods[method](handler)()
1.118 + part = methods[method](handler)()
1.119 +
1.120 + if part:
1.121 + print >>open("/tmp/imip.txt", "a"), part.as_string()
1.122
1.123 class Handler:
1.124 +
1.125 + "General handler support."
1.126 +
1.127 def __init__(self, details):
1.128 self.details = details
1.129 self.uid = get_value(details, "UID")
1.130 @@ -180,9 +209,9 @@
1.131
1.132 # Get the details for the attendee.
1.133
1.134 - out = open("/tmp/imip.txt", "a")
1.135 + out = StringIO()
1.136 try:
1.137 - w = iterwrite(out)
1.138 + w = iterwrite(out, encoding="utf-8")
1.139
1.140 calendar = []
1.141 cwrite = calendar.append
1.142 @@ -207,6 +236,8 @@
1.143
1.144 w.write("VCALENDAR", {}, calendar)
1.145
1.146 + return MIMEText(out.getvalue(), "calendar", "utf-8")
1.147 +
1.148 finally:
1.149 out.close()
1.150