# HG changeset patch # User Paul Boddie # Date 1301848924 -7200 # Node ID 41f74731f67203705c80c8459a3c9730bf28afdd # Parent 0c7952a36a959fe159559b13e800317eed567aa3 Reverted various attempts to use TimespanCollection as a container for shown events, since it is not appropriate for collections of overlapping events. Reintroduced the getEventsInPeriod function, but without the resolution parameter, since it is only applicable when determining event coverage and whether events collide in a particular slot. Added a getEventLimits function to separately determine the earliest and latest event times. diff -r 0c7952a36a95 -r 41f74731f672 EventAggregatorSupport.py --- a/EventAggregatorSupport.py Sun Apr 03 02:31:06 2011 +0200 +++ b/EventAggregatorSupport.py Sun Apr 03 18:42:04 2011 +0200 @@ -781,14 +781,14 @@ return events -def getEventsInPeriod(events, calendar_period, resolution): +def getEventsInPeriod(events, calendar_period): """ Return a collection containing those of the given 'events' which occur - within the given 'calendar_period' at the given 'resolution'. + within the given 'calendar_period'. """ - all_shown_events = TimespanCollection(resolution) + all_shown_events = [] for event in events: @@ -799,10 +799,30 @@ # Compare the dates to the requested calendar window, if any. if event in calendar_period: - all_shown_events.insert_in_order(event) + all_shown_events.append(event) return all_shown_events +def getEventLimits(events): + + "Return the earliest and latest of the given 'events'." + + earliest = None + latest = None + + for event in events: + + # Test for the suitability of the event. + + if event.as_timespan() is not None: + ts = event.as_timespan() + if earliest is None or ts.start < earliest: + earliest = ts.start + if latest is None or ts.end > latest: + latest = ts.end + + return earliest, latest + def setEventTimestamps(request, events): """ @@ -848,12 +868,11 @@ ordered_events.sort() return ordered_events -def getCalendarPeriod(calendar_start, calendar_end, resolution): +def getCalendarPeriod(calendar_start, calendar_end): """ - Return a calendar period for the given 'calendar_start' and 'calendar_end', - employing the given 'resolution'. The 'calendar_start' and 'calendar_end' - parameters can be given as None. + Return a calendar period for the given 'calendar_start' and 'calendar_end'. + These parameters can be given as None. """ # Re-order the window, if appropriate. @@ -861,9 +880,7 @@ if calendar_start is not None and calendar_end is not None and calendar_start > calendar_end: calendar_start, calendar_end = calendar_end, calendar_start - # Return a timespan at the given resolution. - - return Timespan(calendar_start, calendar_end).convert(resolution) + return Timespan(calendar_start, calendar_end) def getConcretePeriod(calendar_start, calendar_end, earliest, latest): @@ -1613,8 +1630,9 @@ class TimespanCollection: """ - A collection of timespans providing a list-like interface supporting - membership tests at a particular resolution. + A class providing a list-like interface supporting membership tests at a + particular resolution in order to maintain a collection of non-overlapping + timespans. """ def __init__(self, resolution, values=None): @@ -1640,7 +1658,8 @@ def convert(self, value): if isinstance(value, ActsAsTimespan): - return value.as_timespan().convert(self.resolution) + ts = value.as_timespan() + return ts and ts.convert(self.resolution) else: return value.convert(self.resolution) @@ -1670,13 +1689,7 @@ return self.values.pop() def insert_in_order(self, value): - i = bisect.bisect_left(self, self.convert(value)) - self.insert(i, value) - - def items_in_range(self, start, end): - slice_start = bisect.bisect_left(self, start) - slice_end = bisect.bisect_right(self, end, slice_start) - return self.values[slice_start:slice_end] + bisect.insort_left(self, value) def getCountry(s): diff -r 0c7952a36a95 -r 41f74731f672 actions/EventAggregatorSummary.py --- a/actions/EventAggregatorSummary.py Sun Apr 03 02:31:06 2011 +0200 +++ b/actions/EventAggregatorSummary.py Sun Apr 03 18:42:04 2011 +0200 @@ -270,9 +270,7 @@ event_pages = getPagesFromResults(getAllCategoryPages(category_names, request), request) events = getEventsFromPages(event_pages) - calendar_period = getCalendarPeriod(calendar_start, calendar_end, resolution) - all_shown_events = getEventsInPeriod(events, calendar_period, resolution) - + all_shown_events = getEventsInPeriod(events, getCalendarPeriod(calendar_start, calendar_end)) latest_timestamp = setEventTimestamps(request, all_shown_events) # Output summary data... @@ -374,12 +372,7 @@ if latest_timestamp is not None: request.write('%s\r\n' % getHTTPTimeString(latest_timestamp)) - # Sort all_shown_events by start date, reversed: - # - # * event_details are dictionaries, with the "start" entry providing - # the start date - # - # So we use as sorting key the "start" key from the event details. + # Sort all_shown_events by start date, reversed. ordered_events = getOrderedEvents(all_shown_events) ordered_events.reverse() diff -r 0c7952a36a95 -r 41f74731f672 macros/EventAggregator.py --- a/macros/EventAggregator.py Sun Apr 03 02:31:06 2011 +0200 +++ b/macros/EventAggregator.py Sun Apr 03 18:42:04 2011 +0200 @@ -1144,14 +1144,10 @@ # Get the events according to the resolution of the calendar. - resolution = mode == "day" and "date" or "month" - event_pages = getPagesFromResults(getAllCategoryPages(category_names, request), request) events = getEventsFromPages(event_pages) - calendar_period = getCalendarPeriod(calendar_start, calendar_end, resolution) - all_shown_events = getEventsInPeriod(events, calendar_period, resolution) - - earliest, latest = all_shown_events.as_limits() + all_shown_events = getEventsInPeriod(events, getCalendarPeriod(calendar_start, calendar_end)) + earliest, latest = getEventLimits(all_shown_events) # Get a concrete period of time. @@ -1195,13 +1191,9 @@ output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) - # Get the events in order. - - ordered_events = getOrderedEvents(all_shown_events) - # Show the events in order. - for event in ordered_events: + for event in all_shown_events: event_page = event.getPage() event_summary = event.getSummary(parent_name) event_details = event.getDetails() @@ -1308,7 +1300,7 @@ week_end = month.as_date(min(first_day + 6, number_of_days)) full_coverage, week_slots = getCoverage( - all_shown_events.items_in_range(week_start, week_end.next_day())) + getEventsInPeriod(all_shown_events, getCalendarPeriod(week_start, week_end))) # Output a week, starting with the day numbers. @@ -1350,14 +1342,9 @@ output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"})) - # Get the events in order. - - ordered_events = getOrderedEvents( - all_shown_events.items_in_range(month, month.next_month())) - # Show the events in order. - for event in ordered_events: + for event in getEventsInPeriod(all_shown_events, getCalendarPeriod(month, month)): event_page = event.getPage() event_details = event.getDetails() event_summary = event.getSummary(parent_name) @@ -1423,7 +1410,7 @@ output.append(fmt.table(on=1, attrs={"tableclass" : "event-calendar-day"})) full_coverage, day_slots = getCoverage( - all_shown_events.items_in_range(date, date.next_day()), "datetime") + getEventsInPeriod(all_shown_events, getCalendarPeriod(date, date)), "datetime") # Work out how many columns the day title will need. # Include spacers before each event column.