imip-agent

tools/make_freebusy.py

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