# HG changeset patch # User Paul Boddie # Date 1412887812 -7200 # Node ID e2841274e1fbb6078ccdb12dbda164b5ff04856f # Parent 5f249406b86133cfde305484734846263bcd9e2a Added convenience and support functions for handling iCalendar rule values. diff -r 5f249406b861 -r e2841274e1fb tests/qualifiers.py --- a/tests/qualifiers.py Wed Oct 08 18:18:11 2014 +0200 +++ b/tests/qualifiers.py Thu Oct 09 22:50:12 2014 +0200 @@ -19,7 +19,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2003, 12, 24)) print len(l) == 7, 7, len(l) print l[0] == (1997, 11, 2), (1997, 11, 2), l[0] @@ -42,7 +42,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2003, 12, 24, 0, 0, 0)) print len(l) == 32, 32, len(l) print l[0] == (1997, 1, 11, 8, 30, 0), (1997, 1, 11, 8, 30, 0), l[0] @@ -61,7 +61,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -80,7 +80,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 113, 113, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -99,7 +99,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 57, 57, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -118,7 +118,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 17, 17, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -137,7 +137,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0), 5) print len(l) == 5, 5, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -158,7 +158,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2000, 1, 31, 14, 0, 0)) print len(l) == 93, 93, len(l) print l[0] == (1998, 1, 1, 9, 0, 0), (1998, 1, 1, 9, 0, 0), l[0] @@ -178,7 +178,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2000, 1, 31, 14, 0, 0)) print len(l) == 93, 93, len(l) print l[0] == (1998, 1, 1, 9, 0, 0), (1998, 1, 1, 9, 0, 0), l[0] @@ -197,7 +197,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -216,7 +216,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 17, 17, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -235,7 +235,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 2, 20, 0, 0, 0)) print len(l) == 13, 13, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -255,7 +255,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 10, 7, 9, 0, 0)) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -275,7 +275,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -295,7 +295,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 25, 25, len(l) print l[0] == (1997, 9, 1, 9, 0, 0), (1997, 9, 1, 9, 0, 0), l[0] @@ -315,7 +315,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0), 8) print len(l) == 8, 8, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -335,7 +335,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 5, 9, 0, 0), (1997, 9, 5, 9, 0, 0), l[0] @@ -355,7 +355,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 4, 4, len(l) print l[0] == (1997, 9, 5, 9, 0, 0), (1997, 9, 5, 9, 0, 0), l[0] @@ -375,7 +375,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 7, 9, 0, 0), (1997, 9, 7, 9, 0, 0), l[0] @@ -395,7 +395,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 6) print len(l) == 6, 6, len(l) print l[0] == (1997, 9, 22, 9, 0, 0), (1997, 9, 22, 9, 0, 0), l[0] @@ -415,7 +415,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 6) print len(l) == 6, 6, len(l) print l[0] == (1997, 9, 28, 9, 0, 0), (1997, 9, 28, 9, 0, 0), l[0] @@ -435,7 +435,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -455,7 +455,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 30, 9, 0, 0), (1997, 9, 30, 9, 0, 0), l[0] @@ -475,7 +475,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 10, 9, 0, 0), (1997, 9, 10, 9, 0, 0), l[0] @@ -495,7 +495,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 4, 1, 0, 0, 0)) print len(l) == 18, 18, len(l) print l[0] == (1997, 9, 2, 9, 0, 0), (1997, 9, 2, 9, 0, 0), l[0] @@ -515,7 +515,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2001, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 6, 10, 9, 0, 0), (1997, 6, 10, 9, 0, 0), l[0] @@ -535,7 +535,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2003, 12, 24, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 3, 10, 9, 0, 0), (1997, 3, 10, 9, 0, 0), l[0] @@ -555,7 +555,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2006, 2, 1, 0, 0, 0), 10) print len(l) == 10, 10, len(l) print l[0] == (1997, 1, 1, 9, 0, 0), (1997, 1, 1, 9, 0, 0), l[0] @@ -575,7 +575,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) print l[0] == (1997, 5, 19, 9, 0, 0), (1997, 5, 19, 9, 0, 0), l[0] @@ -597,7 +597,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) print l[0] == (1997, 5, 12, 9, 0, 0), (1997, 5, 12, 9, 0, 0), l[0] @@ -619,7 +619,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 11, 11, len(l) print l[0] == (1997, 3, 13, 9, 0, 0), (1997, 3, 13, 9, 0, 0), l[0] @@ -640,7 +640,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 39, 39, len(l) print l[0] == (1997, 6, 5, 9, 0, 0), (1997, 6, 5, 9, 0, 0), l[0] @@ -661,7 +661,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2000, 12, 24, 0, 0, 0)) print len(l) == 5, 5, len(l) print l[0] == (1998, 2, 13, 9, 0, 0), (1998, 2, 13, 9, 0, 0), l[0] @@ -682,7 +682,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 6, 30, 0, 0, 0)) print len(l) == 10, 10, len(l) print l[0] == (1997, 9, 13, 9, 0, 0), (1997, 9, 13, 9, 0, 0), l[0] @@ -704,7 +704,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (2004, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) print l[0] == (1996, 11, 5, 9, 0, 0), (1996, 11, 5, 9, 0, 0), l[0] @@ -724,7 +724,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0), 3, [3]) print len(l) == 3, 3, len(l) print l[0] == (1997, 9, 4, 9, 0, 0), (1997, 9, 4, 9, 0, 0), l[0] @@ -746,7 +746,7 @@ l = combine_datetime_with_qualifiers(dt, qualifiers) show(l) -s = process(l) +s = get_selector(dt, qualifiers) l = s.materialise(dt, (1998, 4, 1, 0, 0, 0), None, [-2]) print len(l) == 7, 7, len(l) print l[0] == (1997, 9, 29, 9, 0, 0), (1997, 9, 29, 9, 0, 0), l[0] diff -r 5f249406b861 -r e2841274e1fb vRecurrence.py --- a/vRecurrence.py Wed Oct 08 18:18:11 2014 +0200 +++ b/vRecurrence.py Thu Oct 09 22:50:12 2014 +0200 @@ -96,6 +96,7 @@ freq = dict([(level, i) for (i, level) in enumerate(freq_levels) if level]) enum = dict([(level, i) for (i, level) in enumerate(enum_levels) if level]) +weekdays = dict([(weekday, i+1) for (i, weekday) in enumerate(["MO", "TU", "WE", "TH", "FR", "SA", "SU"])]) # Functions for structuring the recurrences. @@ -105,6 +106,77 @@ except StopIteration: return None +def get_parameters(values): + + "Return parameters from the given list of 'values'." + + d = {} + for value in values: + parts = value.split("=", 1) + if len(parts) < 2: + continue + key, value = parts + if key in ("COUNT", "BYSETPOS"): + d[key] = int(value) + return d + +def get_qualifiers(values): + + """ + Process the list of 'values' of the form "key=value", returning a list of + qualifiers. + """ + + qualifiers = [] + frequency = None + interval = 1 + + for value in values: + parts = value.split("=", 1) + if len(parts) < 2: + continue + key, value = parts + if key == "FREQ" and freq.has_key(value): + qualifier = frequency = (value, {}) + elif key == "INTERVAL": + interval = int(value) + continue + elif enum.has_key(key): + qualifier = (key, {"values" : get_qualifier_values(key, value)}) + else: + continue + + qualifiers.append(qualifier) + + if frequency: + frequency[1]["interval"] = interval + + return qualifiers + +def get_qualifier_values(qualifier, value): + + """ + For the given 'qualifier', process the 'value' string, returning a list of + suitable values. + """ + + if qualifier != "BYDAY": + return map(int, value.split(",")) + + values = [] + for part in value.split(","): + weekday = weekdays.get(part[-2:]) + if not weekday: + continue + index = part[:-2] + if index: + index = int(index) + else: + index = None + values.append((weekday, index)) + + return values + def order_qualifiers(qualifiers): "Return the 'qualifiers' in order of increasing resolution." @@ -260,7 +332,14 @@ return to_tuple(d + s, len(t)) -def to_tuple(d, n): +def to_tuple(d, n=None): + if not isinstance(d, date): + return d + if n is None: + if isinstance(d, datetime): + n = 6 + else: + n = 3 return d.timetuple()[:n] def get_first_day(first_day, weekday): @@ -294,6 +373,8 @@ return "%s(%r, %r, %r, %r)" % (self.__class__.__name__, self.level, self.args, self.qualifier, self.context) def materialise(self, start, end, count=None, setpos=None): + start = to_tuple(start) + end = to_tuple(end) counter = count and [0, count] results = self.materialise_items(self.context, start, end, counter, setpos) results.sort() @@ -502,17 +583,27 @@ return self.filter_by_period(results, start, end) -def process(selectors): +special_enum_levels = { + "BYDAY" : WeekDayFilter, + "BYMONTHDAY" : MonthDayFilter, + "BYYEARDAY" : YearDayFilter, + } + +# Public functions. + +def connect_selectors(selectors): current = selectors[0] for selector in selectors[1:]: current.selecting = selector current = selector return selectors[0] -special_enum_levels = { - "BYDAY" : WeekDayFilter, - "BYMONTHDAY" : MonthDayFilter, - "BYYEARDAY" : YearDayFilter, - } +def get_selector(dt, qualifiers): + dt = to_tuple(dt) + return connect_selectors(combine_datetime_with_qualifiers(dt, qualifiers)) + +def get_rule(dt, rule): + qualifiers = get_qualifiers(rule) + return get_selector(dt, qualifiers) # vim: tabstop=4 expandtab shiftwidth=4