1.1 --- a/vRecurrence.py Sun Dec 03 17:13:17 2017 +0100
1.2 +++ b/vRecurrence.py Sun Dec 03 19:19:14 2017 +0100
1.3 @@ -488,24 +488,32 @@
1.4 from_dt = get_next(iter_dt)
1.5 from_sel = get_next(iter_sel)
1.6 have_sel = False
1.7 + held_dt = []
1.8
1.9 # Consume from both lists, merging entries.
1.10
1.11 - while from_dt and from_sel:
1.12 - _level = from_dt.level
1.13 + while from_sel:
1.14 level = from_sel.level
1.15
1.16 # Datetime value at wider resolution.
1.17
1.18 - if _level < level:
1.19 + if from_dt and from_dt.level < level:
1.20 + held_dt.append(from_dt)
1.21 from_dt = get_next(iter_dt)
1.22
1.23 # Qualifier at wider or same resolution as datetime value.
1.24
1.25 else:
1.26 if not have_sel:
1.27 - add_initial_selector(from_sel, level, l)
1.28 - have_sel = True
1.29 + have_sel = add_initial_selector(from_sel, level, l)
1.30 +
1.31 + # Introduce any held datetime values, if appropriate.
1.32 +
1.33 + elif can_restrict_selector(from_sel):
1.34 + for from_held_dt in held_dt:
1.35 + add_datetime_selector(from_held_dt, l)
1.36 +
1.37 + held_dt = []
1.38
1.39 # Add the qualifier to the combined list.
1.40
1.41 @@ -513,7 +521,7 @@
1.42
1.43 # Datetime value at same resolution.
1.44
1.45 - if _level == level:
1.46 + if from_dt and from_dt.level == level:
1.47 from_dt = get_next(iter_dt)
1.48
1.49 # Get the next qualifier.
1.50 @@ -523,45 +531,44 @@
1.51 # Complete the list by adding remaining datetime enumerators.
1.52
1.53 while from_dt:
1.54 -
1.55 - # Ignore datetime values that conflict with day-level qualifiers.
1.56 -
1.57 - if not l or from_dt.level != freq["DAILY"] or \
1.58 - l[-1].level not in daylevels:
1.59 -
1.60 - l.append(from_dt)
1.61 -
1.62 + add_datetime_selector(from_dt, l)
1.63 from_dt = get_next(iter_dt)
1.64
1.65 - # Complete the list by adding remaining qualifiers.
1.66 + return l
1.67
1.68 - while from_sel:
1.69 - if not have_sel:
1.70 - add_initial_selector(from_sel, level, l)
1.71 - have_sel = True
1.72 +def can_restrict_selector(from_sel):
1.73
1.74 - # Add the qualifier to the combined list.
1.75 -
1.76 - l.append(from_sel)
1.77 + "Return whether 'from_sel' can be restricted using datetime information."
1.78
1.79 - # Get the next qualifier.
1.80 -
1.81 - from_sel = get_next(iter_sel)
1.82 -
1.83 - return l
1.84 + return not isinstance(from_sel, Pattern) and from_sel.qualifier != "BYDAY"
1.85
1.86 def add_initial_selector(from_sel, level, l):
1.87
1.88 """
1.89 - Take the first selector 'from_sel' at the given resolution 'level', using it
1.90 - to create an initial selector, adding it to the combined list 'l' if
1.91 - required.
1.92 + Take the selector 'from_sel' at the given resolution 'level', using it to
1.93 + create an initial selector, adding it to the combined list 'l' if required.
1.94 +
1.95 + Return whether a frequency selector has been introduced or if 'from_sel' is
1.96 + such a selector.
1.97 """
1.98
1.99 if isinstance(from_sel, Enum) and level > 0:
1.100 parent_level = enum_parent_levels[level]
1.101 repeat = Pattern(parent_level, {"interval" : 1}, freq_levels[parent_level])
1.102 l.append(repeat)
1.103 + return True
1.104 +
1.105 + return isinstance(from_sel, Pattern)
1.106 +
1.107 +def add_datetime_selector(from_dt, l):
1.108 +
1.109 + """
1.110 + Take the selector 'from_dt' and add it to the list 'l' if it does not
1.111 + conflict with any day-level qualifiers already in 'l'.
1.112 + """
1.113 +
1.114 + if not l or from_dt.level != freq["DAILY"] or l[-1].level not in daylevels:
1.115 + l.append(from_dt)
1.116
1.117 def get_multiple(qualifier):
1.118
1.119 @@ -1531,4 +1538,13 @@
1.120 rule = (rule or "").split(";")
1.121 return make_selectors(get_qualifiers(rule))
1.122
1.123 +def get_selectors_from_selector(selector):
1.124 +
1.125 + "Return the chain of selectors from 'selector', useful for debugging."
1.126 +
1.127 + if selector.selecting:
1.128 + return [selector] + get_selectors_from_selector(selector.selecting)
1.129 + else:
1.130 + return [selector]
1.131 +
1.132 # vim: tabstop=4 expandtab shiftwidth=4