# HG changeset patch # User Paul Boddie # Date 1411396476 -7200 # Node ID f5795f1b7ff925a2e79a71b1eff6910f001ca808 # Parent f71e9cf75f4736311435ab7ecf659c9309cda1e9 Fixed conversion to dictionary of calendar data. Restructured the handler mechanism. Added a simple store implementation. diff -r f71e9cf75f47 -r f5795f1b7ff9 imip_agent.py --- a/imip_agent.py Sun Sep 21 23:50:20 2014 +0200 +++ b/imip_agent.py Mon Sep 22 16:34:36 2014 +0200 @@ -2,6 +2,7 @@ from email import message_from_file from vCalendar import parse +import imip_store import sys try: @@ -56,13 +57,20 @@ if isinstance(value, list): d[name] = attr, get_itip_elements(value) else: - d[name] = attr, value + if not d.has_key(name): + d[name] = [] + d[name].append((attr, value)) return d -def get_value(d, name): +def get_value(d, name, single=True): if d.has_key(name): - attr, value = d[name] - return value + values = d[name] + if isinstance(values, tuple): + return values[1] + elif single and len(values) == 1: + return values[0][1] + else: + return map(lambda x: x[1], values) else: return None @@ -76,30 +84,123 @@ itip = get_itip_elements(elements) if get_value(itip, "METHOD") == method: - for name, handler in [ - ("VFREEBUSY", handle_itip_freebusy), - ("VEVENT", handle_itip_event), - ("VTODO", handle_itip_todo), - ("VJOURNAL", handle_itip_journal), - ]: + + for name, cls in handlers: + details = get_value(itip, name) + + if details: + print >>open("/tmp/imip.txt", "a"), details + handler = cls(details) + print >>open("/tmp/imip.txt", "a"), "Handling", method, "with", handler, "->", methods[method](handler) + methods[method](handler)() + +class Handler: + def __init__(self, details): + self.details = details + self.uid = get_value(details, "UID") + self.sequence = get_value(details, "SEQUENCE") + self.store = imip_store.FileStore() + + def publish(self): + pass + + def get_value(self, name, single=False): + return get_value(self.details, name, single) + +class Event(Handler): + def add(self): + pass + + def cancel(self): + pass + + def counter(self): + pass + + def declinecounter(self): + pass + + def refresh(self): + pass + + def reply(self): + pass + + def request(self): + pass + +class Freebusy(Handler): + def reply(self): + attendees = self.get_value("ATTENDEE", False) + organiser = self.get_value("ORGANIZER") + if not attendees and not organiser: + return + + # Store the reply details for the attendee. - obj = get_value(itip, name) - if obj: - uid = get_value(obj, "UID") - if uid: - handler(obj, method) + def request(self): + attendees = self.get_value("ATTENDEE", False) + organiser = self.get_value("ORGANIZER") + print >>open("/tmp/imip.txt", "a"), attendees, organiser + if not attendees and not organiser: + return + + # Get the details for the attendee. + + for attendee in attendees: + freebusy = self.store.get_freebusy(attendee) + print >>open("/tmp/imip.txt", "a"), freebusy + + # Send a reply with the information. -def handle_itip_freebusy(freebusy, method): - print >>open("/tmp/imip.txt", "a"), freebusy +class Journal(Handler): + def add(self): + pass + + def cancel(self): + pass + +class Todo(Handler): + def add(self): + pass + + def cancel(self): + pass + + def counter(self): + pass -def handle_itip_event(event, method): - print >>open("/tmp/imip.txt", "a"), event + def declinecounter(self): + pass + + def refresh(self): + pass + + def reply(self): + pass + + def request(self): + pass + +# Handler registry. -def handle_itip_todo(todo, method): - print >>open("/tmp/imip.txt", "a"), todo +handlers = [ + ("VFREEBUSY", Freebusy), + ("VEVENT", Event), + ("VTODO", Todo), + ("VJOURNAL", Journal), + ] -def handle_itip_journal(journal, method): - print >>open("/tmp/imip.txt", "a"), journal +methods = { + "ADD" : lambda handler: handler.add, + "CANCEL" : lambda handler: handler.cancel, + "COUNTER" : lambda handler: handler.counter, + "DECLINECOUNTER" : lambda handler: handler.declinecounter, + "PUBLISH" : lambda handler: handler.publish, + "REFRESH" : lambda handler: handler.refresh, + "REPLY" : lambda handler: handler.reply, + "REQUEST" : lambda handler: handler.request, + } if __name__ == "__main__": process(sys.stdin, sys.argv[1:]) diff -r f71e9cf75f47 -r f5795f1b7ff9 imip_store.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imip_store.py Mon Sep 22 16:34:36 2014 +0200 @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +from os.path import abspath, commonprefix, exists, join +from os import makedirs + +STORE_DIR = "/tmp/imip" + +def check_dir(base, dir): + return commonprefix([base, abspath(dir)]) == base + +class FileStore: + + "A file store of tabular data." + + def __init__(self): + self.store_dir = STORE_DIR + if not exists(self.store_dir): + makedirs(self.store_dir) + + def get_freebusy(self, calendar): + + "Get free/busy details from the given 'calendar'." + + dir = join(self.store_dir, calendar) + if not check_dir(self.store_dir, dir): + return None + + filename = join(dir, "freebusy") + if not exists(filename): + return None + + f = open(filename) + try: + l = [] + for line in f.readlines(): + l.append(line.strip().split("\t")) + return l + finally: + f.close() + +# vim: tabstop=4 expandtab shiftwidth=4