1.1 --- a/imip_agent.py Thu Sep 25 23:21:21 2014 +0200
1.2 +++ b/imip_agent.py Wed Oct 01 00:02:17 2014 +0200
1.3 @@ -211,11 +211,7 @@
1.4 encoding = "utf-8"
1.5 out = StringIO()
1.6 try:
1.7 - calendar[:0] = [
1.8 - ("METHOD", {}, method),
1.9 - ("VERSION", {}, "2.0")
1.10 - ]
1.11 - imip_store.to_stream(out, ("VCALENDAR", {}, calendar), encoding)
1.12 + imip_store.to_stream(out, imip_store.make_calendar(calendar, method), encoding)
1.13 part = MIMEText(out.getvalue(), "calendar", encoding)
1.14 part.set_param("method", method)
1.15 return part
1.16 @@ -311,6 +307,11 @@
1.17
1.18 self.store = imip_store.FileStore()
1.19
1.20 + try:
1.21 + self.publisher = imip_store.FilePublisher()
1.22 + except OSError:
1.23 + self.publisher = None
1.24 +
1.25 def get_items(self, name, all=True):
1.26 return get_items(self.details, name, all)
1.27
1.28 @@ -450,9 +451,12 @@
1.29 if not conflict:
1.30 insert_period(freebusy, (dtstart, dtend, self.uid))
1.31
1.32 - if self.get_value("TRANSP") in (None, "TRANSPARENT"):
1.33 + if self.get_value("TRANSP") in (None, "OPAQUE"):
1.34 self.store.set_freebusy(attendee, freebusy)
1.35
1.36 + if self.publisher:
1.37 + self.publisher.set_freebusy(attendee, freebusy)
1.38 +
1.39 self.store.set_event(attendee, self.uid, to_node(
1.40 {"VEVENT" : [(self.details, {})]}
1.41 ))
2.1 --- a/imip_store.py Thu Sep 25 23:21:21 2014 +0200
2.2 +++ b/imip_store.py Wed Oct 01 00:02:17 2014 +0200
2.3 @@ -1,23 +1,32 @@
2.4 #!/usr/bin/env python
2.5
2.6 +from datetime import datetime
2.7 from os.path import abspath, commonprefix, exists, join, split
2.8 from os import makedirs
2.9 from vCalendar import iterwrite
2.10
2.11 STORE_DIR = "/var/lib/imip-agent/store"
2.12 +PUBLISH_DIR = "/var/www/imip-agent"
2.13
2.14 def check_dir(base, dir):
2.15 return commonprefix([base, abspath(dir)]) == base
2.16
2.17 +def make_calendar(fragment, method=None):
2.18 + return ("VCALENDAR", {},
2.19 + (method and [("METHOD", {}, method)] or []) +
2.20 + [("VERSION", {}, "2.0")] +
2.21 + fragment
2.22 + )
2.23 +
2.24 def to_stream(out, fragment, encoding="utf-8"):
2.25 iterwrite(out, encoding=encoding).append(fragment)
2.26
2.27 -class FileStore:
2.28 +class FileBase:
2.29
2.30 - "A file store of tabular data."
2.31 + "Basic filesystem operations."
2.32
2.33 - def __init__(self):
2.34 - self.store_dir = STORE_DIR
2.35 + def __init__(self, store_dir=STORE_DIR):
2.36 + self.store_dir = store_dir
2.37 if not exists(self.store_dir):
2.38 makedirs(self.store_dir)
2.39
2.40 @@ -25,6 +34,10 @@
2.41 pathname = join(base, *parts)
2.42 return check_dir(base, pathname) and pathname or None
2.43
2.44 +class FileStore(FileBase):
2.45 +
2.46 + "A file store of tabular free/busy data and objects."
2.47 +
2.48 def get_event(self, user, uid):
2.49
2.50 "Get the event for the given 'user' with the given 'uid'."
2.51 @@ -97,4 +110,42 @@
2.52
2.53 return True
2.54
2.55 +class FilePublisher(FileBase):
2.56 +
2.57 + "A publisher of objects."
2.58 +
2.59 + def __init__(self, store_dir=PUBLISH_DIR):
2.60 + FileBase.__init__(self, store_dir)
2.61 +
2.62 + def set_freebusy(self, user, freebusy):
2.63 +
2.64 + "For the given 'user', set 'freebusy' details."
2.65 +
2.66 + filename = self.get_file_object(self.store_dir, user, "freebusy")
2.67 + if not filename:
2.68 + return False
2.69 +
2.70 + dir = split(filename)[0]
2.71 +
2.72 + if not exists(dir):
2.73 + makedirs(dir)
2.74 +
2.75 + record = []
2.76 + rwrite = record.append
2.77 +
2.78 + rwrite(("ORGANIZER", {}, user))
2.79 + rwrite(("UID", {}, user))
2.80 + rwrite(("DTSTAMP", {}, datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")))
2.81 +
2.82 + for start, end, uid in freebusy:
2.83 + rwrite(("FREEBUSY", {"FBTYPE" : "BUSY"}, "/".join([start, end])))
2.84 +
2.85 + f = open(filename, "w")
2.86 + try:
2.87 + to_stream(f, make_calendar([("VFREEBUSY", {}, record)], "PUBLISH"))
2.88 + finally:
2.89 + f.close()
2.90 +
2.91 + return True
2.92 +
2.93 # vim: tabstop=4 expandtab shiftwidth=4