domain.py: import peak.events.trellis as trellis from datetime import timedelta, datetime, time, date one_day = timedelta(1) one_hour = timedelta(hours=1) class Event(trellis.Component): trellis.values( start = None, end = None, globaltz = None ) def busyHoursForDay(self, day): """Return the number of busy hours the event takes up on day.""" if None in (self.start, self.end): return 0 range_start = datetime.combine(day, time(0, tzinfo=self.globaltz)) range_end = range_start + one_day if range_end >= self.start and range_start <= self.end: return 1 class Day(trellis.Component): trellis.values( date = None, events = trellis.Set(), busy = 0 ) @trellis.rule def busy(self): return sum(event.busyHoursForDay(self.date) for event in self.events) class ManyDays(trellis.Component): trellis.values( days = trellis.Set() ) def __getitem__(self, day): for member in self.days: if member.date == day: return member return None def __add__(self, other): new = ManyDays() new.days.update(self.days) for day in other.days: if new[day.date] is None: new.days.add = days else: new[day.date].events.update(day.events) return new def _makeDays(year, month, day_range, hours): days = [] for day in day_range: dt = date(year, month, day) events = set() for hour in hours: start = datetime.combine(dt, time(hour)) events.add(Event(start=start, end=start + one_hour)) days.append(Day(date=dt, events=events)) return days ---------------- test_domain.py import domain import unittest import datetime one_day = datetime.timedelta(1) class MiniCalendarEventTestCase(unittest.TestCase): start = datetime.datetime(2007, 8, 5, 9) end = datetime.datetime(2007, 8, 5, 10) day = datetime.date( 2007, 8, 5 ) def testInit(self): event = domain.Event() self.failIf(event is None) self.failIf(event.start) self.failIf(event.end) def _getEvent(self): return domain.Event(start=self.start, end=self.end) def testSimpleEvent(self): event = self._getEvent() self.failIf(event is None) self.assertEqual(event.start, self.start) self.assertEqual(event.end, self.end) def testDays(self): days1 = domain.ManyDays(days=domain._makeDays(2007, 8, xrange(4, 10), (9,))) days2 = domain.ManyDays(days=domain._makeDays(2007, 8, xrange(5, 9), (11, 13))) self.assertEqual(len(days1[self.day].events), 1) self.assertEqual(len(days2[self.day].events), 2) combined = days1 + days2 self.assertEqual(len(combined[self.day].events), 3) def testBusy(self): event = self._getEvent() self.assertEqual(event.busyHoursForDay(self.day), 1) days = domain.ManyDays(days=domain._makeDays(2007, 8, [5], (9,10,11))) day_instance = days[self.day] self.assertEqual(day_instance.busy, 3) day_instance.events.add(event) self.assertEqual(day_instance.busy, 4) if __name__ == "__main__": unittest.main()