imip-agent

tools/make_freebusy.py

481:f44bef24d615
2015-04-05 Paul Boddie Updated the free/busy tool to work with recent period abstraction changes.
     1 #!/usr/bin/env python     2      3 from imiptools.data import get_window_end, Object     4 from imiptools.dates import format_datetime, get_default_timezone     5 from imiptools.period import FreeBusyPeriod     6 from imiptools.profile import Preferences     7 from imip_store import FileStore, FilePublisher     8 import sys     9     10 def get_periods(fb, obj, tzid, window_end, only_organiser, recurrenceids):    11     12     # Update free/busy details with the actual periods associated with the event.    13     14     recurrenceid = format_datetime(obj.get_utc_datetime("RECURRENCE-ID")) or ""    15     16     for p in obj.get_periods_for_freebusy(tzid, window_end):    17         if recurrenceid or p.start not in recurrenceids:    18             fb.append(FreeBusyPeriod(    19                 p.start, p.end,    20                 obj.get_value("UID"),    21                 only_organiser and "ORG" or obj.get_value("TRANSP") or "OPAQUE",    22                 recurrenceid,    23                 obj.get_value("SUMMARY"),    24                 obj.get_value("ORGANIZER")    25                 ))    26     27 # Main program.    28     29 try:    30     user = sys.argv[1]    31     args = sys.argv[2:]    32     participant = args and args[0] not in ("-n", "-s", "-v") and args[0] or user    33     store_and_publish = "-s" in args    34     include_needs_action = "-n" in args    35     verbose = "-v" in args    36 except IndexError:    37     print >>sys.stderr, """\    38 Need a user and an optional participant (if different from the user),    39 along with the -s option if updating the store and the published details.    40 """    41     sys.exit(1)    42     43 preferences = Preferences(user)    44 tzid = preferences.get("TZID") or get_default_timezone()    45     46 # Get the size of the free/busy window.    47     48 try:    49     window_size = int(preferences.get("window_size"))    50 except (TypeError, ValueError):    51     window_size = 100    52 window_end = get_window_end(tzid, window_size)    53     54 store = FileStore()    55 publisher = FilePublisher()    56     57 # Get all identifiers for events.    58     59 uids = store.get_events(user)    60     61 all_events = set()    62 for uid in uids:    63     all_events.add((uid, None))    64     all_events.update([(uid, recurrenceid) for recurrenceid in store.get_recurrences(user, uid)])    65     66 # Filter out cancelled events.    67     68 cancelled = store.get_cancellations(user) or []    69 all_events.difference_update(cancelled)    70     71 # Obtain event objects.    72     73 objs = []    74 for uid, recurrenceid in all_events:    75     if verbose:    76         print >>sys.stderr, uid, recurrenceid    77     event = store.get_event(user, uid, recurrenceid)    78     if event:    79         objs.append(Object(event))    80     81 # Build a free/busy collection for the given user.    82     83 fb = []    84 for obj in objs:    85     attendees = obj.get_value_map("ATTENDEE")    86     organiser = obj.get_value("ORGANIZER")    87     recurrenceids = store.get_recurrences(user, obj.get_value("UID"))    88     89     for attendee, attendee_attr in attendees.items():    90     91         # Only consider events where the stated participant actually attends.    92     93         if attendee == participant:    94             partstat = attendee_attr.get("PARTSTAT", "NEEDS-ACTION")    95     96             if partstat not in ("DECLINED", "DELEGATED", "NEEDS-ACTION") or \    97                 include_needs_action and partstat == "NEEDS-ACTION":    98     99                 get_periods(fb, obj, tzid, window_end, False, recurrenceids)   100    101             break   102    103     # Where not attending, retain the affected periods and mark them as   104     # organising periods.   105    106     else:   107         if organiser == participant:   108             get_periods(fb, obj, tzid, window_end, True, recurrenceids)   109    110 fb.sort()   111    112 # Store and publish the free/busy collection.   113    114 if store_and_publish:   115     if user == participant:   116         store.set_freebusy(user, fb)   117         publisher.set_freebusy(user, fb)   118     else:   119         store.set_freebusy_for_other(user, fb, participant)   120 else:   121     for item in fb:   122         print "\t".join(item.as_tuple())   123    124 # vim: tabstop=4 expandtab shiftwidth=4