1.1 --- a/imipweb/data.py Tue Sep 12 22:09:24 2017 +0200
1.2 +++ b/imipweb/data.py Tue Sep 12 23:07:14 2017 +0200
1.3 @@ -343,6 +343,23 @@
1.4
1.5
1.6
1.7 +# Form period processing.
1.8 +
1.9 +def get_active_periods(periods):
1.10 +
1.11 + "Return a mapping of non-replaced periods to counts, given 'periods'."
1.12 +
1.13 + active_periods = {}
1.14 + for p in periods:
1.15 + if not p.replaced:
1.16 + if not active_periods.has_key(p):
1.17 + active_periods[p] = 1
1.18 + else:
1.19 + active_periods[p] += 1
1.20 + return active_periods
1.21 +
1.22 +
1.23 +
1.24 # Form field extraction and serialisation.
1.25
1.26 def get_date_control_inputs(args, name, tzid_name=None):
1.27 @@ -545,4 +562,52 @@
1.28 set_date_control_values(all_starts, args, start_name)
1.29 set_date_control_values(all_ends, args, end_name, tzid_name=start_name)
1.30
1.31 +
1.32 +
1.33 +# Utilities.
1.34 +
1.35 +def filter_duplicates(l):
1.36 +
1.37 + """
1.38 + Return collection 'l' filtered for duplicate values, retaining the given
1.39 + element ordering.
1.40 + """
1.41 +
1.42 + s = set()
1.43 + f = []
1.44 +
1.45 + for value in l:
1.46 + if value not in s:
1.47 + s.add(value)
1.48 + f.append(value)
1.49 +
1.50 + return f
1.51 +
1.52 +def remove_from_collection(l, indexes, fn):
1.53 +
1.54 + """
1.55 + Remove from collection 'l' all values present at the given 'indexes' where
1.56 + 'fn' applied to each referenced value returns a true value. Values where
1.57 + 'fn' returns a false value are added to a list of deferred removals which is
1.58 + returned.
1.59 + """
1.60 +
1.61 + still_to_remove = []
1.62 + correction = 0
1.63 +
1.64 + for i in indexes:
1.65 + try:
1.66 + i = int(i) - correction
1.67 + value = l[i]
1.68 + except (IndexError, ValueError):
1.69 + continue
1.70 +
1.71 + if fn(value):
1.72 + del l[i]
1.73 + correction += 1
1.74 + else:
1.75 + still_to_remove.append(value)
1.76 +
1.77 + return still_to_remove
1.78 +
1.79 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imipweb/event.py Tue Sep 12 22:09:24 2017 +0200
2.2 +++ b/imipweb/event.py Tue Sep 12 23:07:14 2017 +0200
2.3 @@ -24,6 +24,8 @@
2.4 from imiptools.dates import format_datetime, to_timezone
2.5 from imiptools.mail import Messenger
2.6 from imipweb.data import EventPeriod, event_period_from_period, \
2.7 + filter_duplicates, get_active_periods, \
2.8 + remove_from_collection, \
2.9 get_period_control_values, \
2.10 PeriodError
2.11 from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject
2.12 @@ -1004,19 +1006,6 @@
2.13 periods.append(p.as_event_period(i))
2.14 return periods
2.15
2.16 - def get_active_periods(self, periods):
2.17 -
2.18 - "Return a mapping of non-replaced periods to counts, given 'periods'."
2.19 -
2.20 - active_periods = {}
2.21 - for p in periods:
2.22 - if not p.replaced:
2.23 - if not active_periods.has_key(p):
2.24 - active_periods[p] = 1
2.25 - else:
2.26 - active_periods[p] += 1
2.27 - return active_periods
2.28 -
2.29 # Access to form-originating object information.
2.30
2.31 def get_main_period_from_page(self):
2.32 @@ -1065,50 +1054,6 @@
2.33 attendee_map = self.obj.get_value_map("ATTENDEE")
2.34 return [get_verbose_address(value, attendee_map.get(value)) for value in attendees]
2.35
2.36 - def filter_duplicates(self, l):
2.37 -
2.38 - """
2.39 - Return collection 'l' filtered for duplicate values, retaining the given
2.40 - element ordering.
2.41 - """
2.42 -
2.43 - s = set()
2.44 - f = []
2.45 -
2.46 - for value in l:
2.47 - if value not in s:
2.48 - s.add(value)
2.49 - f.append(value)
2.50 -
2.51 - return f
2.52 -
2.53 - def remove_from_collection(self, l, indexes, fn):
2.54 -
2.55 - """
2.56 - Remove from collection 'l' all values having 'indexes' where 'fn'
2.57 - applied to each referenced value returns a true value. Values where 'fn'
2.58 - returns a false value are added to a list of deferred removals which is
2.59 - returned.
2.60 - """
2.61 -
2.62 - still_to_remove = []
2.63 - correction = 0
2.64 -
2.65 - for i in indexes:
2.66 - try:
2.67 - i = int(i) - correction
2.68 - value = l[i]
2.69 - except (IndexError, ValueError):
2.70 - continue
2.71 -
2.72 - if fn(value):
2.73 - del l[i]
2.74 - correction += 1
2.75 - else:
2.76 - still_to_remove.append(value)
2.77 -
2.78 - return still_to_remove
2.79 -
2.80 def update_attendees_from_page(self):
2.81
2.82 "Add or remove attendees. This does not affect the stored object."
2.83 @@ -1141,12 +1086,12 @@
2.84 remove = args.has_key("remove")
2.85
2.86 if remove:
2.87 - still_to_remove = self.remove_from_collection(attendees,
2.88 + still_to_remove = remove_from_collection(attendees,
2.89 args["remove"], self.can_remove_attendee)
2.90 self.set_state("remove", still_to_remove)
2.91
2.92 if add or add_suggested or remove:
2.93 - attendees = self.filter_duplicates(attendees)
2.94 + attendees = filter_duplicates(attendees)
2.95
2.96 return attendees
2.97
2.98 @@ -1171,12 +1116,12 @@
2.99 remove = args.has_key("recur-remove")
2.100
2.101 if remove:
2.102 - still_to_remove = self.remove_from_collection(recurrences,
2.103 + still_to_remove = remove_from_collection(recurrences,
2.104 args["recur-remove"], self.can_remove_recurrence)
2.105 self.set_state("recur-remove", still_to_remove)
2.106
2.107 if add or remove:
2.108 - recurrences = self.filter_duplicates(recurrences)
2.109 + recurrences = filter_duplicates(recurrences)
2.110
2.111 return recurrences
2.112
2.113 @@ -1273,7 +1218,7 @@
2.114
2.115 # Get all periods that are not replaced.
2.116
2.117 - active_periods = self.get_active_periods(periods)
2.118 + active_periods = get_active_periods(periods)
2.119
2.120 for period in self.get_state("recur-remove", list):
2.121 active_periods[period] -= 1