1.1 --- a/imipweb/data.py Tue Sep 12 21:58:33 2017 +0200
1.2 +++ b/imipweb/data.py Tue Sep 12 23:02:29 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(str(i))
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 21:58:33 2017 +0200
2.2 +++ b/imipweb/event.py Tue Sep 12 23:02:29 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, set_period_control_values, \
2.10 PeriodError
2.11 from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject
2.12 @@ -996,19 +998,6 @@
2.13
2.14 return [p.as_event_period(i) for i, p in enumerate(self.get_recurrences_from_page())]
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 @@ -1061,7 +1050,7 @@
2.33
2.34 # Get all periods that are not replaced.
2.35
2.36 - active_periods = self.get_active_periods(periods)
2.37 + active_periods = get_active_periods(periods)
2.38
2.39 for i in args.get("recur-remove", []):
2.40 try:
2.41 @@ -1109,50 +1098,6 @@
2.42 attendee_map = self.obj.get_value_map("ATTENDEE")
2.43 return [get_verbose_address(value, attendee_map.get(value)) for value in attendees]
2.44
2.45 - def filter_duplicates(self, l):
2.46 -
2.47 - """
2.48 - Return collection 'l' filtered for duplicate values, retaining the given
2.49 - element ordering.
2.50 - """
2.51 -
2.52 - s = set()
2.53 - f = []
2.54 -
2.55 - for value in l:
2.56 - if value not in s:
2.57 - s.add(value)
2.58 - f.append(value)
2.59 -
2.60 - return f
2.61 -
2.62 - def remove_from_collection(self, l, indexes, fn):
2.63 -
2.64 - """
2.65 - Remove from collection 'l' all values having 'indexes' where 'fn'
2.66 - applied to each referenced value returns a true value. Values where 'fn'
2.67 - returns a false value are added to a list of deferred removals which is
2.68 - returned.
2.69 - """
2.70 -
2.71 - still_to_remove = []
2.72 - correction = 0
2.73 -
2.74 - for i in indexes:
2.75 - try:
2.76 - i = int(i) - correction
2.77 - value = l[i]
2.78 - except (IndexError, ValueError):
2.79 - continue
2.80 -
2.81 - if fn(value):
2.82 - del l[i]
2.83 - correction += 1
2.84 - else:
2.85 - still_to_remove.append(str(i))
2.86 -
2.87 - return still_to_remove
2.88 -
2.89 def update_attendees_from_page(self):
2.90
2.91 "Add or remove attendees. This does not affect the stored object."
2.92 @@ -1185,12 +1130,12 @@
2.93 remove = args.has_key("remove")
2.94
2.95 if remove:
2.96 - still_to_remove = self.remove_from_collection(attendees,
2.97 + still_to_remove = remove_from_collection(attendees,
2.98 args["remove"], self.can_remove_attendee)
2.99 args["remove"] = still_to_remove
2.100
2.101 if add or add_suggested or remove:
2.102 - attendees = self.filter_duplicates(attendees)
2.103 + attendees = filter_duplicates(attendees)
2.104
2.105 args["attendee"] = attendees
2.106 return attendees
2.107 @@ -1216,12 +1161,12 @@
2.108 remove = args.has_key("recur-remove")
2.109
2.110 if remove:
2.111 - still_to_remove = self.remove_from_collection(recurrences,
2.112 + still_to_remove = remove_from_collection(recurrences,
2.113 args["recur-remove"], self.can_remove_recurrence)
2.114 args["recur-remove"] = still_to_remove
2.115
2.116 if add or remove:
2.117 - recurrences = self.filter_duplicates(recurrences)
2.118 + recurrences = filter_duplicates(recurrences)
2.119
2.120 self.set_recurrences_in_page(recurrences)
2.121 return recurrences