# HG changeset patch # User Paul Boddie # Date 1438273723 -7200 # Node ID 6338539a488e328a80a8140ef8cb71f8ed526c73 # Parent b021078b64d4aae77b30480ddc4f89c0d073d961 Moved various period-related methods to the Object class. Changed period abstractions to support datetime metadata retrieval methods. Made the time zone access method in period abstractions return datetime-originating zone information in preference to any explicit zone details, thus eliminating the need to supply any object zone details when initialising periods. diff -r b021078b64d4 -r 6338539a488e imiptools/data.py --- a/imiptools/data.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imiptools/data.py Thu Jul 30 18:28:43 2015 +0200 @@ -92,6 +92,20 @@ dt, attr = t return dt + def set_datetime(self, name, dt, tzid): + + """ + Set a datetime for property 'name' using 'dt' and 'tzid', returning + whether an update has occurred. + """ + + if dt: + old_value = self.get_value(name) + self[name] = [get_datetime_item(dt, tzid)] + return format_datetime(dt) != old_value + + return False + def get_datetime_item(self, name): return get_datetime_item(self.details, name) @@ -134,8 +148,23 @@ # Computed results. def get_periods(self, tzid, end): + + """ + Return periods defined by this object, employing the given 'tzid' where + no time zone information is defined, and limiting the collection to a + window of time with the given 'end'. + """ + return get_periods(self, tzid, end) + def set_period(self, period): + + "Set the given 'period' as the main start and end." + + result = self.set_datetime("DTSTART", period.get_start(), period.start_attr().get("TZID")) + result = self.set_datetime("DTEND", period.get_end(), period.end_attr().get("TZID")) or result + return result + def get_tzid(self): """ diff -r b021078b64d4 -r 6338539a488e imiptools/handlers/common.py --- a/imiptools/handlers/common.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imiptools/handlers/common.py Thu Jul 30 18:28:43 2015 +0200 @@ -56,10 +56,9 @@ if self.messenger: attendee_attr["SENT-BY"] = get_uri(self.messenger.sender) - 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 + period = dtstart and dtend and Period(dtstart, dtend, self.get_tzid()) or None rwrite(make_freebusy(freebusy, self.uid, organiser, organiser_attr, attendee, attendee_attr, period)) diff -r b021078b64d4 -r 6338539a488e imiptools/handlers/person.py --- a/imiptools/handlers/person.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imiptools/handlers/person.py Thu Jul 30 18:28:43 2015 +0200 @@ -140,10 +140,9 @@ except ValueError: pass - 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) + period = Period(dtstart, dtend, self.get_tzid()) for sender, sender_attr in senders: stored_freebusy = self.store.get_freebusy_for_other(self.user, sender) diff -r b021078b64d4 -r 6338539a488e imiptools/period.py --- a/imiptools/period.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imiptools/period.py Thu Jul 30 18:28:43 2015 +0200 @@ -37,6 +37,9 @@ """ Initialise a period with the given 'start' and 'end', having a contextual 'tzid', if specified, and an indicated 'origin'. + + All metadata from the start and end points are derived from the supplied + dates/datetimes. """ self.start = isinstance(start, date) and start or get_datetime(start) @@ -80,13 +83,19 @@ return self.end def get_tzid(self): - return self.tzid + return get_tzid(self.get_start_attr(), self.get_end_attr()) or self.tzid + + def get_start_attr(self): + return get_datetime_attributes(self.start, self.tzid) + + def get_end_attr(self): + return get_datetime_attributes(self.end, self.tzid) def get_start_item(self): - return self.start, get_datetime_attributes(self.start, self.get_tzid()) + return self.get_start(), self.get_start_attr() def get_end_item(self): - return self.end, get_datetime_attributes(self.end, self.get_tzid()) + return self.get_end(), self.get_end_attr() def get_start_point(self): return to_utc_datetime(self.get_start(), self.get_tzid()) @@ -152,21 +161,21 @@ class RecurringPeriod(Period): - "A period with iCalendar attribute and origin information from the object." + """ + A period with iCalendar metadata attributes and origin information from an + object. + """ def __init__(self, start, end, tzid=None, origin=None, start_attr=None, end_attr=None): Period.__init__(self, start, end, tzid, origin) self.start_attr = start_attr self.end_attr = end_attr - def get_start_item(self): - return self.get_start(), self.start_attr + def get_start_attr(self): + return self.start_attr - def get_end_item(self): - return self.get_end(), self.end_attr - - def get_tzid(self): - return get_tzid(self.start_attr, self.end_attr) or self.tzid + def get_end_attr(self): + return self.end_attr def as_tuple(self): return self.start, self.end, self.tzid, self.origin, self.start_attr, self.end_attr diff -r b021078b64d4 -r 6338539a488e imipweb/data.py --- a/imipweb/data.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imipweb/data.py Thu Jul 30 18:28:43 2015 +0200 @@ -89,7 +89,7 @@ dt, attr ) -class FormPeriod: +class FormPeriod(RecurringPeriod): "A period whose information originates from a form." @@ -107,36 +107,6 @@ def __repr__(self): return "FormPeriod(%r)" % (self.as_tuple(),) - def _get_start(self): - return self.start.as_datetime(self.times_enabled), self.start.get_attributes(self.times_enabled) - - def _get_end(self): - - # Handle specified end datetimes. - - if self.end_enabled: - dtend = self.end.as_datetime(self.times_enabled) - dtend_attr = self.end.get_attributes(self.times_enabled) - if not dtend: - return None, None - - # Otherwise, treat the end date as the start date. Datetimes are - # handled by making the event occupy the rest of the day. - - else: - dtstart, dtstart_attr = self._get_start() - if dtstart: - dtend_attr = dtstart_attr - - if isinstance(dtstart, datetime): - dtend = get_end_of_day(dtstart, dtstart_attr["TZID"]) - else: - dtend = dtstart - else: - return None, None - - return dtend, dtend_attr - def as_event_period(self, index=None): """ @@ -164,18 +134,37 @@ # Period data methods. def get_start(self): - dtstart, dtstart_attr = self._get_start() - return dtstart + return self.start.as_datetime(self.times_enabled) def get_end(self): - dtend, dtend_attr = self._get_end() + + # Handle specified end datetimes. + + if self.end_enabled: + dtend = self.end.as_datetime(self.times_enabled) + if not dtend: + return None + + # Otherwise, treat the end date as the start date. Datetimes are + # handled by making the event occupy the rest of the day. + + else: + dtstart, dtstart_attr = self.get_start_item() + if dtstart: + if isinstance(dtstart, datetime): + dtend = get_end_of_day(dtstart, dtstart_attr["TZID"]) + else: + dtend = dtstart + else: + return None + return dtend - def get_start_item(self): - return self._get_start() + def get_start_attr(self): + return self.start.get_attributes(self.times_enabled) - def get_end_item(self): - return self._get_end() + def get_end_attr(self): + return self.end.get_attributes(self.times_enabled) # Form data methods. diff -r b021078b64d4 -r 6338539a488e imipweb/event.py --- a/imipweb/event.py Wed Jul 29 18:41:11 2015 +0200 +++ b/imipweb/event.py Thu Jul 30 18:28:43 2015 +0200 @@ -165,7 +165,7 @@ to_unschedule = self.get_removed_periods() - self.set_period_in_object(obj, period) + obj.set_period(period) self.set_periods_in_object(obj, periods) # Update summary. @@ -234,14 +234,6 @@ return None - def set_period_in_object(self, obj, period): - - "Set in the given 'obj' the given 'period' as the main start and end." - - result = self.set_datetime_in_object(period.get_start(), period.start_attr and period.start_attr.get("TZID"), "DTSTART", obj) - result = self.set_datetime_in_object(period.get_end(), period.end_attr and period.end_attr.get("TZID"), "DTEND", obj) or result - return result - def set_periods_in_object(self, obj, periods): "Set in the given 'obj' the given 'periods'." @@ -263,20 +255,6 @@ # NOTE: To do: calculate the update status. return update - def set_datetime_in_object(self, dt, tzid, property, obj): - - """ - Set 'dt' and 'tzid' for the given 'property' in 'obj', returning whether - an update has occurred. - """ - - if dt: - old_value = obj.get_value(property) - obj[property] = [get_datetime_item(dt, tzid)] - return format_datetime(dt) != old_value - - return False - def handle_main_period(self): "Return period details for the main start/end period in an event."