Below is the file 'icalinate.py' from this revision. You can also download the file.
#!/usr/bin/env python # # iCalinate : Expose simple information from an iCal # file so other applications don't have to care. # # Copyright (C) 2007 Grahame Bowland # import datetime import vobject import heapq class EventWrapper(object): def __init__ (self, vevent, offset): self.vevent = vevent self.offset = offset self.rruleset_iter = iter (vevent.getrruleset (addRDate=True)) self.recur () def recur (self): self.next_occurrence = self.rruleset_iter.next() if self.next_occurrence and self.offset: self.next_occurrence -= self.offset return self.next_occurrence != None def __cmp__ (self, other_event): return cmp (self.next_occurrence, other_event.next_occurrence) class Upcoming(object): def __init__ (self, ical_file, offset=None): self.ical = vobject.readOne (open (ical_file)) self.offset = offset self.heap = [] for vevent in self.ical.vevent_list: heapq.heappush (self.heap, EventWrapper (vevent, offset)) def __iter__ (self): while len (self.heap) > 0: wrapped = heapq.heappop (self.heap) yield wrapped.next_occurrence, wrapped.vevent if wrapped.recur (): heapq.heappush (self.heap, wrapped) class iCalinate(object): def __init__ (self, *args, **kwargs): self.upcoming = Upcoming (*args, **kwargs) self.__iter_cache = [] def summary (self, nevents=10): rv = [] for idx, (occurrence, 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 for attr in ('summary', 'description'): entry[attr] = event.getChildValue (attr) rv.append (entry) return rv def __iter__ (self): now = datetime.datetime.now () old_count = 0 for occurrence, event in self.__iter_cache: if occurrence >= 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: continue self.__iter_cache.append ((occurrence, event)) yield occurrence, event if __name__ == '__main__': nated = iCalinate ('ical', offset=datetime.timedelta(hours=-8)) import pprint pprint.pprint (nated.summary())