The unified diff between revisions [8d9287a2..] and [66fcf32a..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "icalinate.py"
# from [bafb379a8b7d97e13288021714d468bd65cc4d27]
# to [92e16a3397513a44ef7bb405f31c52bbbd04baa5]
#
============================================================
--- icalinate.py bafb379a8b7d97e13288021714d468bd65cc4d27
+++ icalinate.py 92e16a3397513a44ef7bb405f31c52bbbd04baa5
@@ -7,9 +7,10 @@
# Copyright (C) 2007 Grahame Bowland
#
-import datetime
+import datetime, time
import vobject
import heapq
+import json
class EventWrapper(object):
def __init__ (self, vevent, offset):
@@ -27,6 +28,51 @@ class EventWrapper(object):
def __cmp__ (self, other_event):
return cmp (self.next_occurrence, other_event.next_occurrence)
+class EventOccurrence(object):
+ def __init__ (self, occurrence, event):
+ self.occurrence = occurrence
+ self.event = event
+ self.__calced = False
+
+ def __calc (self):
+ if self.__calced:
+ return
+ self.__dtstart = self.event.getChildValue ('dtstart')
+ self.__dtend = self.event.getChildValue ('dtend')
+ self.__duration = self.event.getChildValue ('duration')
+ if not self.__duration:
+ if self.__dtstart and self.__dtend:
+ self.__duration = self.__dtend - self.__dtstart
+ else:
+ self.__duration = None
+ self.__calced = True
+
+ def start (self):
+ self.__calc ()
+ return self.occurrence
+
+ def end (self):
+ self.__calc ()
+ return self.occurrence + self.__duration
+
+ def duration (self):
+ self.__calc ()
+ return self.__duration
+
+ def on_or_later (self, now=None):
+ self.__calc ()
+ if now == None:
+ now = datetime.datetime.now ()
+ if self.occurrence >= now:
+ return True
+ if self.__duration and self.occurrence + self.__duration >= now:
+ return True
+ return False
+
+ def get (self, *args, **kwargs):
+ return self.event.getChildValue (*args, **kwargs)
+
+
class Upcoming(object):
def __init__ (self, ical_file, offset=None):
self.ical = vobject.readOne (open (ical_file))
@@ -38,7 +84,7 @@ class Upcoming(object):
def __iter__ (self):
while len (self.heap) > 0:
wrapped = heapq.heappop (self.heap)
- yield wrapped.next_occurrence, wrapped.vevent
+ yield EventOccurrence (wrapped.next_occurrence, wrapped.vevent)
if wrapped.recur ():
heapq.heappush (self.heap, wrapped)
@@ -46,44 +92,57 @@ class iCalinate(object):
def __init__ (self, *args, **kwargs):
self.upcoming = Upcoming (*args, **kwargs)
self.__iter_cache = []
+ self.back_to_utc = -1 * int (time.time () - time.mktime (time.gmtime ()))
+ def __unix_from_datetime (self, dt):
+ # dt will be in local time
+ return time.mktime (dt.timetuple ()) + 1e-6 * dt.microsecond + self.back_to_utc
+
def summary (self, nevents=10):
rv = []
- for idx, (occurrence, event) in enumerate (self):
+ for idx, event in enumerate (self):
if idx >= nevents:
break
entry = {}
- dtstart = event.getChildValue ('dtstart')
- dtend = event.getChildValue ('dtend')
- duration = event.getChildValue ('duration')
- if not duration and dtstart and dtend:
- duration = dtend - dtstart
- entry['occurrence'] = occurrence
- entry['duration'] = duration
+ entry['start'] = event.start ()
+ entry['duration'] = event.duration ()
+ entry['end'] = event.end ()
for attr in ('summary', 'description'):
- entry[attr] = event.getChildValue (attr)
+ entry[attr] = event.get (attr)
rv.append (entry)
return rv
+
+ def json_summary (self, *args, **kwargs):
+ rv = self.summary (*args, **kwargs)
+ writer = json.JsonWriter ()
+ for entry in rv:
+ for k in entry.keys ():
+ v = entry[k]
+ if isinstance (v, datetime.datetime):
+ entry[k] = self.__unix_from_datetime (v)
+ else:
+ entry[k] = str(v)
+ print writer.write (rv)
def __iter__ (self):
now = datetime.datetime.now ()
old_count = 0
- for occurrence, event in self.__iter_cache:
- if occurrence >= now:
+ for event in self.__iter_cache:
+ if event.on_or_later (now=now):
break
else:
old_count += 1
self.__iter_cache = self.__iter_cache[old_count:]
- for occurrence, event in self.__iter_cache:
- yield occurrence, event
- for occurrence, event in self.upcoming:
- if occurrence < now:
+ for event in self.__iter_cache:
+ yield event
+ for event in self.upcoming:
+ if not event.on_or_later (now):
continue
- self.__iter_cache.append ((occurrence, event))
- yield occurrence, event
+ self.__iter_cache.append (event)
+ yield event
if __name__ == '__main__':
nated = iCalinate ('ical', offset=datetime.timedelta(hours=-8))
import pprint
- pprint.pprint (nated.summary())
+ nated.json_summary ()