# HG changeset patch # User Paul Boddie # Date 1431954509 -7200 # Node ID fac3b41b0ccbff359480c55f83b71266a40cc02f # Parent 6078f2a58c3c7268d9d5eda2002a12f62ad8a218 Tidied up period initialisation and usage, fixing and improving the free/busy period constraint application performed by the common free/busy handler. diff -r 6078f2a58c3c -r fac3b41b0ccb imiptools/data.py --- a/imiptools/data.py Mon May 18 00:28:53 2015 +0200 +++ b/imiptools/data.py Mon May 18 15:08:29 2015 +0200 @@ -127,6 +127,12 @@ return get_periods(self, tzid, end) def get_tzid(self): + + """ + Return a time zone identifier used by the start or end datetimes, + potentially suitable for converting dates to datetimes. + """ + if not self.has_key("DTSTART"): return None dtstart, dtstart_attr = self.get_datetime_item("DTSTART") @@ -149,7 +155,7 @@ ) def make_freebusy(freebusy, uid, organiser, organiser_attr=None, attendee=None, - attendee_attr=None, dtstart=None, dtend=None): + attendee_attr=None, period=None): """ Return a calendar node defining the free/busy details described in the given @@ -157,8 +163,7 @@ optional 'organiser_attr', with the optional 'attendee' providing recipient details together with the optional 'attendee_attr'. - The result will be constrained to the 'dtstart' and 'dtend' period if these - parameters are given. + The result will be constrained to the 'period' if specified. """ record = [] @@ -175,19 +180,17 @@ # Get a constrained view if start and end limits are specified. - periods = dtstart and dtend and \ - period_overlaps(freebusy, Period(dtstart, dtend), True) or \ - freebusy + periods = period and period_overlaps(freebusy, period, True) or freebusy # Write the limits of the resource. - rwrite(("DTSTART", {"VALUE" : "DATE-TIME"}, format_datetime(periods[0].get_start()))) - rwrite(("DTEND", {"VALUE" : "DATE-TIME"}, format_datetime(periods[-1].get_end()))) + rwrite(("DTSTART", {"VALUE" : "DATE-TIME"}, format_datetime(periods[0].get_start_point()))) + rwrite(("DTEND", {"VALUE" : "DATE-TIME"}, format_datetime(periods[-1].get_end_point()))) for p in periods: if p.transp == "OPAQUE": rwrite(("FREEBUSY", {"FBTYPE" : "BUSY"}, "/".join( - map(format_datetime, [p.get_start(), p.get_end()]) + map(format_datetime, [p.get_start_point(), p.get_end_point()]) ))) return ("VFREEBUSY", {}, record) @@ -334,6 +337,13 @@ return to_utc_datetime(dt, date_tzid) def get_datetime_item(d, name): + + """ + Return the value provided by 'd' for 'name' as a datetime or as a date, + together with the attributes describing it. Return None if no value exists + for 'name' in 'd'. + """ + t = get_item(d, name) if not t: return None @@ -421,7 +431,7 @@ else: dtend, dtend_attr = dtstart, dtstart_attr - tzid = get_tzid(dtstart_attr, dtend_attr) or tzid + tzid = obj.get_tzid() or tzid if not rrule: periods = [RecurringPeriod(dtstart, dtend, tzid, "DTSTART", dtstart_attr, dtend_attr)] @@ -468,9 +478,9 @@ if exdates: for exdate in exdates: if isinstance(exdate, tuple): - period = Period(exdate[0], exdate[1]) + period = Period(exdate[0], exdate[1], tzid) else: - period = Period(exdate, exdate + duration) + period = Period(exdate, exdate + duration, tzid) i = bisect_left(periods, period) while i < len(periods) and periods[i] == period: del periods[i] diff -r 6078f2a58c3c -r fac3b41b0ccb imiptools/handlers/__init__.py --- a/imiptools/handlers/__init__.py Mon May 18 00:28:53 2015 +0200 +++ b/imiptools/handlers/__init__.py Mon May 18 15:08:29 2015 +0200 @@ -133,7 +133,6 @@ "Remove this event from the given 'freebusy' collection." if not remove_period(freebusy, self.uid, self.recurrenceid) and self.recurrenceid: - tzid = self.obj.get_tzid() or self.get_tzid() remove_affected_period(freebusy, self.uid, self.to_recurrence_start_point(self.recurrenceid)) def remove_freebusy_for_recurrences(self, freebusy, recurrenceids=None): diff -r 6078f2a58c3c -r fac3b41b0ccb imiptools/handlers/common.py --- a/imiptools/handlers/common.py Mon May 18 00:28:53 2015 +0200 +++ b/imiptools/handlers/common.py Mon May 18 15:08:29 2015 +0200 @@ -21,6 +21,7 @@ from imiptools.data import get_address, get_uri, make_freebusy, to_part from imiptools.dates import format_datetime +from imiptools.period import Period class CommonFreebusy: @@ -54,10 +55,12 @@ if self.messenger: attendee_attr["SENT-BY"] = get_uri(self.messenger.sender) - dtstart = format_datetime(self.obj.get_utc_datetime("DTSTART")) - dtend = format_datetime(self.obj.get_utc_datetime("DTEND")) + tzid = self.obj.get_tzid() or self.get_tzid() + dtstart = self.obj.get_datetime("DTSTART") + dtend = self.obj.get_datetime("DTEND") + period = dtstart and dtend and Period(dtstart, dtend, tzid) or None - rwrite(make_freebusy(freebusy, self.uid, organiser, organiser_attr, attendee, attendee_attr, dtstart, dtend)) + rwrite(make_freebusy(freebusy, self.uid, organiser, organiser_attr, attendee, attendee_attr, period)) # Return the reply. diff -r 6078f2a58c3c -r fac3b41b0ccb imiptools/handlers/person.py --- a/imiptools/handlers/person.py Mon May 18 00:28:53 2015 +0200 +++ b/imiptools/handlers/person.py Mon May 18 15:08:29 2015 +0200 @@ -136,12 +136,14 @@ except ValueError: pass - dtstart = self.obj.get_utc_datetime("DTSTART") - dtend = self.obj.get_utc_datetime("DTEND") + tzid = self.obj.get_tzid() or self.get_tzid() + dtstart = self.obj.get_datetime("DTSTART") + dtend = self.obj.get_datetime("DTEND") + period = Period(dtstart, dtend, tzid) for sender, sender_attr in senders: stored_freebusy = self.store.get_freebusy_for_other(self.user, sender) - replace_overlapping(stored_freebusy, Period(dtstart, dtend), freebusy) + replace_overlapping(stored_freebusy, period, freebusy) self.store.set_freebusy_for_other(self.user, stored_freebusy, sender) class Event(PersonHandler):