1.1 --- a/imipweb/data.py Thu Sep 14 23:18:30 2017 +0200
1.2 +++ b/imipweb/data.py Fri Sep 15 00:03:38 2017 +0200
1.3 @@ -343,46 +343,80 @@
1.4
1.5 # Form period processing.
1.6
1.7 -def get_active_periods(periods):
1.8 +def get_existing_periods(periods, still_to_remove):
1.9
1.10 - "Return a mapping of non-replaced periods to counts, given 'periods'."
1.11 + """
1.12 + Find all periods that existed before editing, given 'periods', applying
1.13 + the periods in 'still_to_remove' and producing retained, replaced and
1.14 + to-remove collections containing these existing periods.
1.15 + """
1.16
1.17 - active_periods = {}
1.18 + retained = []
1.19 + replaced = []
1.20 + to_remove = []
1.21 +
1.22 for p in periods:
1.23 - if not p.replaced:
1.24 - if not active_periods.has_key(p):
1.25 - active_periods[p] = 1
1.26 + p = form_period_from_period(p)
1.27 + if p.recurrenceid:
1.28 + if p.replaced:
1.29 + replaced.append(p)
1.30 + elif p in still_to_remove:
1.31 + to_remove.append(p)
1.32 else:
1.33 - active_periods[p] += 1
1.34 - return active_periods
1.35 + retained.append(p)
1.36 +
1.37 + return retained, replaced, to_remove
1.38 +
1.39 +def get_new_periods(periods):
1.40 +
1.41 + "Return all periods introduced during editing, given 'periods'."
1.42 +
1.43 + new = []
1.44 + for p in periods:
1.45 + fp = form_period_from_period(p)
1.46 + if not fp.recurrenceid:
1.47 + new.append(p)
1.48 + return new
1.49
1.50 -def get_removed_periods(periods, still_to_remove):
1.51 +def get_changed_periods(periods):
1.52 +
1.53 + "Return changed and unchanged periods, given 'periods'."
1.54 +
1.55 + changed = []
1.56 + unchanged = []
1.57 +
1.58 + for p in periods:
1.59 + fp = form_period_from_period(p)
1.60 + if fp.is_changed():
1.61 + changed.append(p)
1.62 + else:
1.63 + unchanged.append(p)
1.64 +
1.65 + return changed, unchanged
1.66 +
1.67 +def classify_periods(periods, still_to_remove):
1.68
1.69 """
1.70 From the recurrence 'periods', given details of those 'still_to_remove',
1.71 - return the remaining active periods and the periods to unschedule or
1.72 - exclude, using a tuple of the form (active, unscheduled, excluded).
1.73 + return a tuple containing collections of new, changed, unchanged, replaced
1.74 + and to-be-removed periods.
1.75 """
1.76
1.77 - to_remove = set()
1.78 -
1.79 - # Get all periods that are not replaced.
1.80 + retained, replaced, to_remove = get_existing_periods(periods, still_to_remove)
1.81
1.82 - active_periods = get_active_periods(periods)
1.83 + # Filter new periods with the existing period information.
1.84
1.85 - for period in still_to_remove:
1.86 - active_periods[period] -= 1
1.87 - to_remove.add(period)
1.88 + new = set(get_new_periods(periods))
1.89
1.90 - # Determine whether some periods are both removed and added.
1.91 + new.difference_update(retained)
1.92 + new.difference_update(replaced)
1.93 + new.difference_update(to_remove)
1.94
1.95 - remaining = []
1.96 - for period, n in active_periods.items():
1.97 - if n > 0:
1.98 - remaining.append(period)
1.99 + # Divide retained periods into changed and unchanged collections.
1.100
1.101 - to_remove.difference_update(remaining)
1.102 - return remaining, to_remove
1.103 + changed, unchanged = get_changed_periods(retained)
1.104 +
1.105 + return list(new), changed, unchanged, replaced, to_remove
1.106
1.107
1.108