# HG changeset patch # User Paul Boddie # Date 1506863300 -7200 # Node ID eeebb61f4473367ba03e1114dedf113041e8d341 # Parent 962ff52d7755a6d6d1140ec460989e22abd0cb64 Introduced a common base class for editable periods to ensure that recurrence identities are not lost or regenerated incorrectly for form periods. Propagate period index values to period conversion functions so that errors may contain index value information. diff -r 962ff52d7755 -r eeebb61f4473 imipweb/data.py --- a/imipweb/data.py Sun Oct 01 15:06:09 2017 +0200 +++ b/imipweb/data.py Sun Oct 01 15:08:20 2017 +0200 @@ -29,7 +29,31 @@ class PeriodError(Exception): pass -class EventPeriod(RecurringPeriod): +class EditablePeriod(RecurringPeriod): + + "An editable period tracking the identity of any original period." + + def _get_recurrenceid_item(self): + + # Convert any stored identifier to the current time zone. + # NOTE: This should not be necessary, but is done for consistency with + # NOTE: the datetime properties. + + dt = get_datetime(self.recurrenceid) + dt = to_timezone(dt, self.tzid) + return dt, get_datetime_attributes(dt) + + def get_recurrenceid(self): + if not self.recurrenceid: + return EditablePeriod.get_recurrenceid(self) + return self.recurrenceid + + def get_recurrenceid_item(self): + if not self.recurrenceid: + return EditablePeriod.get_recurrenceid_item(self) + return self._get_recurrenceid_item() + +class EventPeriod(EditablePeriod): """ A simple period plus attribute details, compatible with RecurringPeriod, and @@ -60,7 +84,7 @@ regardless of whether it is separate or not. """ - RecurringPeriod.__init__(self, start, end, tzid, origin, start_attr, end_attr) + EditablePeriod.__init__(self, start, end, tzid, origin, start_attr, end_attr) self.form_start = form_start self.form_end = form_end @@ -86,27 +110,7 @@ def copy(self): return EventPeriod(*self.as_tuple()) - def _get_recurrenceid_item(self): - - # Convert any stored identifier to the current time zone. - # NOTE: This should not be necessary, but is done for consistency with - # NOTE: the datetime properties. - - dt = get_datetime(self.recurrenceid) - dt = to_timezone(dt, self.tzid) - return dt, get_datetime_attributes(dt) - - def get_recurrenceid(self): - if not self.recurrenceid: - return RecurringPeriod.get_recurrenceid(self) - return self.recurrenceid - - def get_recurrenceid_item(self): - if not self.recurrenceid: - return RecurringPeriod.get_recurrenceid_item(self) - return self._get_recurrenceid_item() - - def as_event_period(self): + def as_event_period(self, index=None): return self def get_start_item(self): @@ -150,7 +154,7 @@ dt, attr ) -class FormPeriod(RecurringPeriod): +class FormPeriod(EditablePeriod): "A period whose information originates from a form." @@ -364,7 +368,7 @@ else: return {"VALUE" : "DATE"} -def event_period_from_period(period): +def event_period_from_period(period, index=None): """ Convert a 'period' to one suitable for use in an iCalendar representation. @@ -375,7 +379,7 @@ if isinstance(period, EventPeriod): return period elif isinstance(period, FormPeriod): - return period.as_event_period() + return period.as_event_period(index) else: dtstart, dtstart_attr = period.get_start_item() dtend, dtend_attr = period.get_end_item() @@ -388,7 +392,7 @@ recurrenceid=format_datetime(to_utc_datetime(dtstart))) def event_periods_from_periods(periods): - return map(event_period_from_period, periods) + return map(event_period_from_period, periods, range(0, len(periods))) def form_period_from_period(period):