# HG changeset patch # User Paul Boddie # Date 1439153849 -7200 # Node ID cb98880e024feda4c52dfa282d332cbb8b449657 # Parent 62b87431494268f29355575f078b079bd1f1dde2 Introduced a common method for obtaining the "main period" of an object. Fixed period enumeration where an object specifies an UNTIL property but where no overriding limit is given. diff -r 62b874314942 -r cb98880e024f imiptools/data.py --- a/imiptools/data.py Thu Aug 06 22:00:45 2015 +0200 +++ b/imiptools/data.py Sun Aug 09 22:57:29 2015 +0200 @@ -174,6 +174,27 @@ # Computed results. + def get_main_period_items(self, tzid): + + """ + Return two (value, attributes) items corresponding to the main start-end + period for the object. + """ + + dtstart, dtstart_attr = self.get_datetime_item("DTSTART") + + if self.has_key("DTEND"): + dtend, dtend_attr = self.get_datetime_item("DTEND") + duration = dtend - dtstart + elif self.has_key("DURATION"): + duration = self.get_duration("DURATION") + dtend = dtstart + duration + dtend_attr = dtstart_attr + else: + dtend, dtend_attr = dtstart, dtstart_attr + + return (dtstart, dtstart_attr), (dtend, dtend_attr) + def get_periods(self, tzid, end=None): """ @@ -294,6 +315,33 @@ return self.get_value("SEQUENCE") is not None + def possibly_active_from(self, dt, tzid): + + """ + Return whether the object is possibly active from or after the given + datetime 'dt' using 'tzid' to convert any dates or floating datetimes. + """ + + dt = to_datetime(dt, tzid) + periods = self.get_periods(tzid) + + for p in periods: + if p.get_end_point() > dt: + return True + + rrule = self.get_value("RRULE") + parameters = rrule and get_parameters(rrule) + until = parameters and parameters.get("UNTIL") + + if not rrule: + return False + elif not until: + return True + + dtstart, dtstart_attr = self.get_datetime_item("DTSTART") + until = get_datetime(until, dtstart_attr) + return until > dt + # Modification methods. def set_datetime(self, name, dt, tzid=None): @@ -649,17 +697,8 @@ # Use localised datetimes. - dtstart, dtstart_attr = obj.get_datetime_item("DTSTART") - - if obj.has_key("DTEND"): - dtend, dtend_attr = obj.get_datetime_item("DTEND") - duration = dtend - dtstart - elif obj.has_key("DURATION"): - duration = obj.get_duration("DURATION") - dtend = dtstart + duration - dtend_attr = dtstart_attr - else: - dtend, dtend_attr = dtstart, dtstart_attr + (dtstart, dtstart_attr), (dtend, dtend_attr) = obj.get_main_period_items(tzid) + duration = dtend - dtstart # Attempt to get time zone details from the object, using the supplied zone # only as a fallback. @@ -681,7 +720,8 @@ until = parameters.get("UNTIL") if until: - end = min(to_timezone(get_datetime(until, dtstart_attr), obj_tzid), end) + until_dt = to_timezone(get_datetime(until, dtstart_attr), obj_tzid) + end = end and min(until_dt, end) or until_dt inclusive = True for recurrence_start in selector.materialise(dtstart, end, parameters.get("COUNT"), parameters.get("BYSETPOS"), inclusive):