1.1 --- a/imiptools/data.py Sat Nov 25 00:11:38 2017 +0100
1.2 +++ b/imiptools/data.py Fri Dec 01 23:09:21 2017 +0100
1.3 @@ -33,7 +33,7 @@
1.4 MergingIterator, RulePeriodCollection
1.5 from itertools import ifilter
1.6 from vCalendar import iterwrite, parse, ParseError, to_dict, to_node
1.7 -from vRecurrence import get_parameters
1.8 +from vRecurrence import get_parameters, get_rule
1.9 import email.utils
1.10
1.11 try:
1.12 @@ -1217,31 +1217,32 @@
1.13 will be included.
1.14 """
1.15
1.16 - tzid = obj.get_tzid()
1.17 rrule = obj.get_value("RRULE")
1.18
1.19 - # Use localised datetimes.
1.20 -
1.21 - main_period = obj.get_main_period()
1.22 -
1.23 - if not rrule:
1.24 - rule_periods = iter([main_period])
1.25 -
1.26 # Recurrence rules create multiple instances to be checked.
1.27 # Conflicts may only be assessed within a period defined by policy
1.28 # for the agent, with instances outside that period being considered
1.29 # unchecked.
1.30
1.31 - elif end or rule_has_end(rrule):
1.32 + if not end and not rule_has_end(rrule):
1.33 + return iter([])
1.34
1.35 - # Filter periods using a start point. The end will be handled in the
1.36 - # materialisation process.
1.37 + tzid = obj.get_tzid()
1.38 + main_period = obj.get_main_period()
1.39 +
1.40 + start = main_period.get_start()
1.41 + selector = get_rule(start, rrule)
1.42
1.43 - rule_periods = ifilter(Period(start, None).wraps,
1.44 - RulePeriodCollection(rrule, main_period, tzid,
1.45 - end, inclusive))
1.46 - else:
1.47 - rule_periods = iter([])
1.48 + if not selector:
1.49 + return iter([main_period])
1.50 +
1.51 + parameters = get_parameters(rrule)
1.52 + until = parameters and parameters.has_key("UNTIL") or None
1.53 + until = until and to_timezone(get_datetime(until), tzid)
1.54 +
1.55 + rule_periods = get_periods_using_selector(selector, until,
1.56 + main_period, tzid, start, end,
1.57 + inclusive)
1.58
1.59 # Add recurrence dates.
1.60
1.61 @@ -1259,6 +1260,17 @@
1.62
1.63 return filter(lambda p, excluded=exdates: p not in excluded, periods)
1.64
1.65 +def get_periods_using_selector(selector, until, main_period, tzid, start, end,
1.66 + inclusive=False):
1.67 +
1.68 + # Filter periods using a start point. The period from the given start
1.69 + # until the end of time must wrap each period for that period to be
1.70 + # included. The end will be handled in the materialisation process.
1.71 +
1.72 + return ifilter(Period(start, None).wraps,
1.73 + RulePeriodCollection(selector, until, main_period, tzid,
1.74 + end, inclusive))
1.75 +
1.76 def get_main_period(periods):
1.77
1.78 "Return the main period from 'periods' using origin information."