# HG changeset patch # User Paul Boddie # Date 1505426618 -7200 # Node ID 7819b77d9330ef54bbe0ccb6129cc64817095aa6 # Parent e3cda8fa8ee7e22afbc0b775db3b4ee9ae0ddbab Introduced a tentative means of classifying periods for suitable operations upon updating an event. diff -r e3cda8fa8ee7 -r 7819b77d9330 imipweb/data.py --- a/imipweb/data.py Thu Sep 14 23:18:30 2017 +0200 +++ b/imipweb/data.py Fri Sep 15 00:03:38 2017 +0200 @@ -343,46 +343,80 @@ # Form period processing. -def get_active_periods(periods): +def get_existing_periods(periods, still_to_remove): - "Return a mapping of non-replaced periods to counts, given 'periods'." + """ + Find all periods that existed before editing, given 'periods', applying + the periods in 'still_to_remove' and producing retained, replaced and + to-remove collections containing these existing periods. + """ - active_periods = {} + retained = [] + replaced = [] + to_remove = [] + for p in periods: - if not p.replaced: - if not active_periods.has_key(p): - active_periods[p] = 1 + p = form_period_from_period(p) + if p.recurrenceid: + if p.replaced: + replaced.append(p) + elif p in still_to_remove: + to_remove.append(p) else: - active_periods[p] += 1 - return active_periods + retained.append(p) + + return retained, replaced, to_remove + +def get_new_periods(periods): + + "Return all periods introduced during editing, given 'periods'." + + new = [] + for p in periods: + fp = form_period_from_period(p) + if not fp.recurrenceid: + new.append(p) + return new -def get_removed_periods(periods, still_to_remove): +def get_changed_periods(periods): + + "Return changed and unchanged periods, given 'periods'." + + changed = [] + unchanged = [] + + for p in periods: + fp = form_period_from_period(p) + if fp.is_changed(): + changed.append(p) + else: + unchanged.append(p) + + return changed, unchanged + +def classify_periods(periods, still_to_remove): """ From the recurrence 'periods', given details of those 'still_to_remove', - return the remaining active periods and the periods to unschedule or - exclude, using a tuple of the form (active, unscheduled, excluded). + return a tuple containing collections of new, changed, unchanged, replaced + and to-be-removed periods. """ - to_remove = set() - - # Get all periods that are not replaced. + retained, replaced, to_remove = get_existing_periods(periods, still_to_remove) - active_periods = get_active_periods(periods) + # Filter new periods with the existing period information. - for period in still_to_remove: - active_periods[period] -= 1 - to_remove.add(period) + new = set(get_new_periods(periods)) - # Determine whether some periods are both removed and added. + new.difference_update(retained) + new.difference_update(replaced) + new.difference_update(to_remove) - remaining = [] - for period, n in active_periods.items(): - if n > 0: - remaining.append(period) + # Divide retained periods into changed and unchanged collections. - to_remove.difference_update(remaining) - return remaining, to_remove + changed, unchanged = get_changed_periods(retained) + + return list(new), changed, unchanged, replaced, to_remove diff -r e3cda8fa8ee7 -r 7819b77d9330 imipweb/event.py --- a/imipweb/event.py Thu Sep 14 23:18:30 2017 +0200 +++ b/imipweb/event.py Fri Sep 15 00:03:38 2017 +0200 @@ -25,8 +25,8 @@ from imiptools.mail import Messenger from imipweb.data import EventPeriod, event_period_from_period, \ form_period_from_period, \ - filter_duplicates, get_active_periods, \ - get_removed_periods, remove_from_collection, \ + classify_periods, filter_duplicates, \ + remove_from_collection, \ get_period_control_values, \ PeriodError from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject @@ -857,7 +857,11 @@ # modified period information. # NOTE: Currently, rules are not updated. - active_periods, to_unschedule, to_exclude = self.get_removed_periods(periods) + editable_periods, to_change, to_remove = self.classify_periods(periods) + + active_periods = editable_periods + to_change + to_unschedule = self.is_organiser() and to_remove or [] + to_exclude = not self.is_organiser() and to_remove or [] periods = set(periods) changed = self.obj.set_period(period) or changed @@ -1037,32 +1041,20 @@ recurrenceid_name="recur-id", tzid=self.get_tzid()) - def get_removed_periods(self, periods): + def classify_periods(self, periods): """ From the recurrence 'periods' and information provided in the request, - return the remaining active periods, the periods to unschedule, and the - periods to exclude, in a tuple of the form (active, unscheduled, - excluded). + return a tuple containing the new and unchanged periods, the changed + periods, and the periods to be removed. """ # Get remaining periods and those whose removal is deferred. - remaining, to_remove = get_removed_periods(periods, + new, changed, unchanged, replaced, to_remove = classify_periods(periods, self.get_state("recur-remove", list)) - # Sort the deferred removal periods into categories. - - to_unschedule = set() - to_exclude = set() - - for period in to_remove: - if not self.can_edit_recurrence(period) and self.is_organiser(): - to_unschedule.add(period) - else: - to_exclude.add(period) - - return remaining, to_unschedule, to_exclude + return new + unchanged, changed, to_remove def get_attendees_from_page(self):