paul@0 | 1 | #!/usr/bin/env python |
paul@0 | 2 | |
paul@0 | 3 | from email import message_from_file |
paul@0 | 4 | from vCalendar import parse |
paul@0 | 5 | import sys |
paul@0 | 6 | |
paul@0 | 7 | try: |
paul@0 | 8 | from cStringIO import StringIO |
paul@0 | 9 | except ImportError: |
paul@0 | 10 | from StringIO import StringIO |
paul@0 | 11 | |
paul@0 | 12 | # Postfix exit codes. |
paul@0 | 13 | |
paul@0 | 14 | EX_USAGE = 64 |
paul@0 | 15 | EX_DATAERR = 65 |
paul@0 | 16 | EX_NOINPUT = 66 |
paul@0 | 17 | EX_NOUSER = 67 |
paul@0 | 18 | EX_NOHOST = 68 |
paul@0 | 19 | EX_UNAVAILABLE = 69 |
paul@0 | 20 | EX_SOFTWARE = 70 |
paul@0 | 21 | EX_OSERR = 71 |
paul@0 | 22 | EX_OSFILE = 72 |
paul@0 | 23 | EX_CANTCREAT = 73 |
paul@0 | 24 | EX_IOERR = 74 |
paul@0 | 25 | EX_TEMPFAIL = 75 |
paul@0 | 26 | EX_PROTOCOL = 76 |
paul@0 | 27 | EX_NOPERM = 77 |
paul@0 | 28 | EX_CONFIG = 78 |
paul@0 | 29 | |
paul@0 | 30 | # Permitted iTIP content types. |
paul@0 | 31 | |
paul@0 | 32 | itip_content_types = [ |
paul@0 | 33 | "text/calendar", # from RFC 6047 |
paul@0 | 34 | "text/x-vcalendar", "application/ics", # other possibilities |
paul@0 | 35 | ] |
paul@0 | 36 | |
paul@1 | 37 | def process(f, args): |
paul@0 | 38 | msg = message_from_file(f) |
paul@1 | 39 | print >>open("/tmp/imip.txt", "a"), "----" |
paul@1 | 40 | print >>open("/tmp/imip.txt", "a"), args |
paul@1 | 41 | print >>open("/tmp/imip.txt", "a"), "----" |
paul@1 | 42 | print >>open("/tmp/imip.txt", "a"), msg.as_string() |
paul@1 | 43 | print >>open("/tmp/imip.txt", "a") |
paul@0 | 44 | |
paul@0 | 45 | # Handle messages with iTIP parts. |
paul@0 | 46 | |
paul@0 | 47 | for part in msg.walk(): |
paul@0 | 48 | if part.get_content_type() in itip_content_types and \ |
paul@0 | 49 | part.get_param("method"): |
paul@0 | 50 | |
paul@0 | 51 | handle_itip_part(part) |
paul@0 | 52 | |
paul@0 | 53 | def get_itip_elements(elements): |
paul@0 | 54 | d = {} |
paul@0 | 55 | for name, attr, value in elements: |
paul@0 | 56 | if isinstance(value, list): |
paul@0 | 57 | d[name] = attr, get_itip_elements(value) |
paul@0 | 58 | else: |
paul@0 | 59 | d[name] = attr, value |
paul@0 | 60 | return d |
paul@0 | 61 | |
paul@0 | 62 | def get_value(d, name): |
paul@0 | 63 | if d.has_key(name): |
paul@0 | 64 | attr, value = d[name] |
paul@0 | 65 | return value |
paul@0 | 66 | else: |
paul@0 | 67 | return None |
paul@0 | 68 | |
paul@0 | 69 | def handle_itip_part(part): |
paul@0 | 70 | method = part.get_param("method") |
paul@0 | 71 | |
paul@0 | 72 | f = StringIO(part.get_payload(decode=True)) |
paul@0 | 73 | doctype, attrs, elements = parse(f, encoding=part.get_content_charset()) |
paul@0 | 74 | |
paul@0 | 75 | if doctype == "VCALENDAR": |
paul@0 | 76 | itip = get_itip_elements(elements) |
paul@0 | 77 | |
paul@0 | 78 | if get_value(itip, "METHOD") == method: |
paul@0 | 79 | for name, handler in [ |
paul@0 | 80 | ("VFREEBUSY", handle_itip_freebusy), |
paul@0 | 81 | ("VEVENT", handle_itip_event), |
paul@0 | 82 | ("VTODO", handle_itip_todo), |
paul@0 | 83 | ("VJOURNAL", handle_itip_journal), |
paul@0 | 84 | ]: |
paul@0 | 85 | |
paul@0 | 86 | obj = get_value(itip, name) |
paul@0 | 87 | if obj: |
paul@0 | 88 | uid = get_value(obj, "UID") |
paul@0 | 89 | if uid: |
paul@0 | 90 | handler(obj, method) |
paul@0 | 91 | |
paul@0 | 92 | def handle_itip_freebusy(freebusy, method): |
paul@0 | 93 | print >>open("/tmp/imip.txt", "a"), freebusy |
paul@0 | 94 | |
paul@0 | 95 | def handle_itip_event(event, method): |
paul@0 | 96 | print >>open("/tmp/imip.txt", "a"), event |
paul@0 | 97 | |
paul@0 | 98 | def handle_itip_todo(todo, method): |
paul@0 | 99 | print >>open("/tmp/imip.txt", "a"), todo |
paul@0 | 100 | |
paul@0 | 101 | def handle_itip_journal(journal, method): |
paul@0 | 102 | print >>open("/tmp/imip.txt", "a"), journal |
paul@0 | 103 | |
paul@0 | 104 | if __name__ == "__main__": |
paul@1 | 105 | process(sys.stdin, sys.argv[1:]) |
paul@0 | 106 | |
paul@0 | 107 | # vim: tabstop=4 expandtab shiftwidth=4 |