imip-agent

imip_store.py

52:d574e0854a24
2014-10-22 Paul Boddie Made a more general method for defining and identifying stored filenames.
     1 #!/usr/bin/env python     2      3 from datetime import datetime     4 from os.path import abspath, commonprefix, exists, join, split     5 from os import makedirs     6 from vCalendar import iterwrite     7      8 STORE_DIR = "/var/lib/imip-agent/store"     9 PUBLISH_DIR = "/var/www/imip-agent"    10     11 def check_dir(base, dir):    12     return commonprefix([base, abspath(dir)]) == base    13     14 def make_calendar(fragment, method=None):    15     return ("VCALENDAR", {},    16             (method and [("METHOD", {}, method)] or []) +    17             [("VERSION", {}, "2.0")] +    18             fragment    19            )    20     21 def to_stream(out, fragment, encoding="utf-8"):    22     iterwrite(out, encoding=encoding).append(fragment)    23     24 class FileBase:    25     26     "Basic filesystem operations."    27     28     def __init__(self, store_dir=STORE_DIR):    29         self.store_dir = store_dir    30         if not exists(self.store_dir):    31             makedirs(self.store_dir)    32     33     def get_file_object(self, base, *parts):    34         pathname = join(base, *parts)    35         return check_dir(base, pathname) and pathname or None    36     37     def get_object_in_store(self, *parts):    38     39         """    40         Return the name of any valid object stored within a hierarchy specified    41         by the given 'parts'.    42         """    43     44         parent = expected = self.store_dir    45     46         for part in parts:    47             filename = self.get_file_object(expected, part)    48             if not filename:    49                 return False    50             parent = expected    51             expected = filename    52     53         if not exists(parent):    54             makedirs(parent)    55     56         return filename    57     58 class FileStore(FileBase):    59     60     "A file store of tabular free/busy data and objects."    61     62     def get_event(self, user, uid):    63     64         "Get the event for the given 'user' with the given 'uid'."    65     66         filename = self.get_object_in_store(user, uid)    67         if not filename or not exists(filename):    68             return None    69     70         return exists(filename) and open(filename) or None    71     72     def set_event(self, user, uid, node):    73     74         "Set an event for 'user' having the given 'uid' and 'node'."    75     76         filename = self.get_object_in_store(user, uid)    77         if not filename:    78             return False    79     80         f = open(filename, "w")    81         try:    82             to_stream(f, node)    83         finally:    84             f.close()    85     86         return True    87     88     def get_freebusy(self, user):    89     90         "Get free/busy details for the given 'user'."    91     92         filename = self.get_object_in_store(user, "freebusy")    93         if not filename or not exists(filename):    94             return None    95     96         f = open(filename)    97         try:    98             l = []    99             for line in f.readlines():   100                 l.append(tuple(line.strip().split("\t")))   101             return l   102         finally:   103             f.close()   104    105     def set_freebusy(self, user, freebusy):   106    107         "For the given 'user', set 'freebusy' details."   108    109         filename = self.get_object_in_store(user, "freebusy")   110         if not filename:   111             return False   112    113         f = open(filename, "w")   114         try:   115             for item in freebusy:   116                 f.write("\t".join(item) + "\n")   117         finally:   118             f.close()   119    120         return True   121    122 class FilePublisher(FileBase):   123    124     "A publisher of objects."   125    126     def __init__(self, store_dir=PUBLISH_DIR):   127         FileBase.__init__(self, store_dir)   128    129     def set_freebusy(self, user, freebusy):   130    131         "For the given 'user', set 'freebusy' details."   132    133         filename = self.get_object_in_store(user, "freebusy")   134         if not filename:   135             return False   136    137         record = []   138         rwrite = record.append   139    140         rwrite(("ORGANIZER", {}, user))   141         rwrite(("UID", {}, user))   142         rwrite(("DTSTAMP", {}, datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")))   143    144         for start, end, uid in freebusy:   145             rwrite(("FREEBUSY", {"FBTYPE" : "BUSY"}, "/".join([start, end])))   146    147         f = open(filename, "w")   148         try:   149             to_stream(f, make_calendar([("VFREEBUSY", {}, record)], "PUBLISH"))   150         finally:   151             f.close()   152    153         return True   154    155 # vim: tabstop=4 expandtab shiftwidth=4