# HG changeset patch # User Paul Boddie # Date 1431894939 -7200 # Node ID 1006d95253866e49358285c247b8c053285f8c47 # Parent 08ba5a8321c1f3c1c1c11f8c6e25db56e78a1bea Removed the special get_periods_for_freebusy function, introducing start and end point methods for period objects. Moved the is_replaced and is_affected methods into the Web resource class. diff -r 08ba5a8321c1 -r 1006d9525386 imiptools/data.py --- a/imiptools/data.py Sun May 17 21:41:27 2015 +0200 +++ b/imiptools/data.py Sun May 17 22:35:39 2015 +0200 @@ -126,10 +126,6 @@ def get_periods(self, tzid, end): return get_periods(self, tzid, end) - def get_periods_for_freebusy(self, tzid, end): - periods = self.get_periods(tzid, end) - return get_periods_for_freebusy(self, periods, tzid) - def get_tzid(self): dtstart, dtstart_attr = self.get_datetime_item("DTSTART") dtend, dtend_attr = self.get_datetime_item("DTEND") @@ -478,25 +474,4 @@ return periods -def get_periods_for_freebusy(obj, periods, tzid): - - """ - Get free/busy-compliant periods employed by 'obj' from the given 'periods', - using the indicated 'tzid' to convert dates to datetimes. - """ - - tzid = obj.get_tzid() or tzid - - l = [] - - for p in periods: - start, end = get_freebusy_period(p.get_start(), p.get_end(), tzid) - - # Create a new period for free/busy purposes with the converted - # datetime information. - - l.append(p.__class__(start, end, *p.as_tuple()[2:])) - - return l - # vim: tabstop=4 expandtab shiftwidth=4 diff -r 08ba5a8321c1 -r 1006d9525386 imiptools/handlers/__init__.py --- a/imiptools/handlers/__init__.py Sun May 17 21:41:27 2015 +0200 +++ b/imiptools/handlers/__init__.py Sun May 17 22:35:39 2015 +0200 @@ -223,7 +223,7 @@ # Obtain the affected periods. - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()) + periods = obj.get_periods(self.get_tzid(), self.get_window_end()) # Record in the free/busy details unless a non-participating attendee. # Use any attendee information for an organiser, not the organiser's own diff -r 08ba5a8321c1 -r 1006d9525386 imiptools/handlers/person_outgoing.py --- a/imiptools/handlers/person_outgoing.py Sun May 17 21:41:27 2015 +0200 +++ b/imiptools/handlers/person_outgoing.py Sun May 17 22:35:39 2015 +0200 @@ -93,7 +93,7 @@ # Interpretation of periods can depend on the time zone. - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()) + periods = obj.get_periods(self.get_tzid(), self.get_window_end()) # Obtain the attendance attributes for this user, if available. diff -r 08ba5a8321c1 -r 1006d9525386 imiptools/handlers/resource.py --- a/imiptools/handlers/resource.py Sun May 17 21:41:27 2015 +0200 +++ b/imiptools/handlers/resource.py Sun May 17 22:35:39 2015 +0200 @@ -72,7 +72,7 @@ # If newer than any old version, discard old details from the # free/busy record and check for suitability. - periods = self.obj.get_periods_for_freebusy(tzid, self.get_window_end()) + periods = self.obj.get_periods(tzid, self.get_window_end()) freebusy = self.store.get_freebusy(self.user) scheduled = self.can_schedule(freebusy, periods) diff -r 08ba5a8321c1 -r 1006d9525386 imiptools/period.py --- a/imiptools/period.py Sun May 17 21:41:27 2015 +0200 +++ b/imiptools/period.py Sun May 17 22:35:39 2015 +0200 @@ -56,8 +56,8 @@ if isinstance(other, Period): return cmp( - (to_utc_datetime(self.get_start(), self.get_tzid()), to_utc_datetime(self.get_end(), self.get_tzid())), - (to_utc_datetime(other.get_start(), self.get_tzid()), to_utc_datetime(other.get_end(), self.get_tzid())) + (self.get_start_point(), self.get_end_point()), + (other.get_start_point(), other.get_end_point()) ) else: return 1 @@ -85,6 +85,12 @@ def get_end_item(self): return self.end, get_datetime_attributes(self.end) + def get_start_point(self): + return to_utc_datetime(self.get_start(), self.get_tzid()) + + def get_end_point(self): + return to_utc_datetime(self.get_end(), self.get_tzid()) + class FreeBusyPeriod(Period): "A free/busy record abstraction." @@ -105,7 +111,9 @@ self.organiser = organiser def as_tuple(self): - return format_datetime(self.start), format_datetime(self.end), self.uid, self.transp, self.recurrenceid, self.summary, self.organiser + return format_datetime(self.get_start_point()), \ + format_datetime(self.get_end_point()), \ + self.uid, self.transp, self.recurrenceid, self.summary, self.organiser def __cmp__(self, other): @@ -136,10 +144,10 @@ self.end_attr = end_attr def get_start_item(self): - return self.start, self.start_attr + return self.get_start(), self.start_attr def get_end_item(self): - return self.end, self.end_attr + return self.get_end(), self.end_attr def get_tzid(self): return get_tzid(self.start_attr, self.end_attr) or self.tzid @@ -249,7 +257,7 @@ # Stop looking if the start no longer matches the recurrence identifier. - if fb.get_start() != start: + if fb.get_start_point() != start: return # If the period belongs to the parent object, remove it and return. @@ -272,21 +280,21 @@ # Find the range of periods potentially overlapping the period in the # free/busy collection. - last = bisect_right(freebusy, Period(period.get_end(), period.get_end())) + last = bisect_right(freebusy, Period(period.get_end(), period.get_end(), period.get_tzid())) startpoints = freebusy[:last] # Find the range of periods potentially overlapping the period in a version # of the free/busy collection sorted according to end datetimes. - endpoints = [(fb.get_end(), fb.get_start(), fb) for fb in startpoints] + endpoints = [(fb.get_end_point(), fb.get_start_point(), fb) for fb in startpoints] endpoints.sort() - first = bisect_left(endpoints, (period.get_start(),)) + first = bisect_left(endpoints, (period.get_start_point(),)) endpoints = endpoints[first:] overlapping = set() for end, start, fb in endpoints: - if end > period.get_start() and start < period.get_end(): + if end > period.get_start_point() and start < period.get_end_point(): overlapping.add(fb) overlapping = list(overlapping) @@ -595,6 +603,6 @@ remove_period(freebusy, uid, recurrenceid) for p in periods: - insert_period(freebusy, FreeBusyPeriod(p.get_start(), p.get_end(), uid, transp, recurrenceid, summary, organiser)) + insert_period(freebusy, FreeBusyPeriod(p.get_start(), p.get_end(), uid, transp, recurrenceid, summary, organiser, p.get_tzid())) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 08ba5a8321c1 -r 1006d9525386 imipweb/event.py --- a/imipweb/event.py Sun May 17 21:41:27 2015 +0200 +++ b/imipweb/event.py Sun May 17 22:35:39 2015 +0200 @@ -23,8 +23,7 @@ from imiptools.client import update_attendees, update_participation from imiptools.data import get_uri, uri_dict, uri_values from imiptools.dates import format_datetime, get_datetime_item, \ - get_period_item, get_recurrence_start, to_date, \ - to_timezone + get_period_item, to_date, to_timezone from imiptools.mail import Messenger from imiptools.period import have_conflict from imipweb.data import EventPeriod, \ @@ -64,21 +63,6 @@ def is_organiser(self, obj): return get_uri(obj.get_value("ORGANIZER")) == self.user - def is_replaced(self, period, recurrenceids): - for s in recurrenceids: - dt = get_recurrence_start(s, self.get_tzid()) - if period.get_start() == dt: - return s - return None - - def is_affected(self, period, recurrenceid): - if not recurrenceid: - return None - dt = get_recurrence_start(recurrenceid, self.get_tzid()) - if period.get_start() == dt: - return recurrenceid - return None - # Request logic methods. def handle_request(self, obj): @@ -854,7 +838,7 @@ # Obtain the user's timezone. tzid = self.get_tzid() - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()) + periods = obj.get_periods(self.get_tzid(), self.get_window_end()) # Indicate whether there are conflicting events. diff -r 08ba5a8321c1 -r 1006d9525386 imipweb/handler.py --- a/imipweb/handler.py Sun May 17 21:41:27 2015 +0200 +++ b/imipweb/handler.py Sun May 17 22:35:39 2015 +0200 @@ -81,7 +81,7 @@ # free/busy details). update_freebusy(freebusy, - self.obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()), + self.obj.get_periods(self.get_tzid(), self.get_window_end()), self.obj.get_value("TRANSP") or "OPAQUE", self.uid, self.recurrenceid, self.obj.get_value("SUMMARY"), diff -r 08ba5a8321c1 -r 1006d9525386 imipweb/resource.py --- a/imipweb/resource.py Sun May 17 21:41:27 2015 +0200 +++ b/imipweb/resource.py Sun May 17 22:35:39 2015 +0200 @@ -22,7 +22,8 @@ from datetime import datetime from imiptools.client import Client from imiptools.data import get_uri, get_window_end, Object, uri_values -from imiptools.dates import format_datetime, format_time, to_recurrence_start +from imiptools.dates import format_datetime, format_time, get_recurrence_start, \ + to_recurrence_start from imiptools.period import FreeBusyPeriod, \ remove_period, remove_affected_period, update_freebusy from imipweb.env import CGIEnvironment @@ -128,7 +129,7 @@ for uid, recurrenceid in self._get_requests(): obj = self._get_object(uid, recurrenceid) if obj: - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()) + periods = obj.get_periods(self.get_tzid(), self.get_window_end()) recurrenceids = self._get_recurrences(uid) # Convert the periods to more substantial free/busy items. @@ -138,7 +139,7 @@ # Subtract any recurrences from the free/busy details of a # parent object. - if recurrenceid or p.start not in recurrenceids: + if recurrenceid or not self.is_replaced(p, recurrenceids): summary.append( FreeBusyPeriod( p.get_start(), @@ -152,6 +153,23 @@ )) return summary + # Period and recurrence testing. + + def is_replaced(self, period, recurrenceids): + for s in recurrenceids: + dt = get_recurrence_start(s, self.get_tzid()) + if period.get_start() == dt: + return s + return None + + def is_affected(self, period, recurrenceid): + if not recurrenceid: + return None + dt = get_recurrence_start(recurrenceid, self.get_tzid()) + if period.get_start() == dt: + return recurrenceid + return None + # Preference methods. def get_user_locale(self): @@ -195,7 +213,7 @@ freebusy = self.store.get_freebusy(self.user) update_freebusy(freebusy, - obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()), + obj.get_periods(self.get_tzid(), self.get_window_end()), is_only_organiser and "ORG" or obj.get_value("TRANSP"), uid, recurrenceid, obj.get_value("SUMMARY"),