1.1 --- a/imipweb/event.py Sat Oct 07 01:11:21 2017 +0200
1.2 +++ b/imipweb/event.py Sat Oct 07 22:38:01 2017 +0200
1.3 @@ -30,7 +30,7 @@
1.4 form_period_from_period, form_periods_from_updated_periods, \
1.5 get_period_control_values, \
1.6 remove_from_collection, \
1.7 - PeriodError
1.8 + PeriodError, State
1.9 from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject
1.10
1.11 # Fake gettext method for strings to be translated later.
1.12 @@ -41,8 +41,17 @@
1.13
1.14 "A resource presenting the details of an event."
1.15
1.16 - def __init__(self, resource=None):
1.17 - ResourceClientForObject.__init__(self, resource)
1.18 + def __init__(self, resource=None, messenger=None):
1.19 + ResourceClientForObject.__init__(self, resource, messenger or Messenger())
1.20 +
1.21 + # Manage editing state.
1.22 +
1.23 + self.state = State({
1.24 + "attendees" : self.get_current_attendees,
1.25 + "main" : self.get_current_main_period,
1.26 + "recurrences" : self.get_current_recurrence_periods,
1.27 + "remove" : list,
1.28 + })
1.29
1.30 # Various property values and labels.
1.31
1.32 @@ -137,7 +146,7 @@
1.33
1.34 page = self.page
1.35
1.36 - attendees = uri_values(self.get_current_attendees())
1.37 + attendees = uri_values(self.state.get("attendees"))
1.38 is_attendee = self.user in attendees
1.39
1.40 if not self.obj.is_shared():
1.41 @@ -199,8 +208,9 @@
1.42
1.43 # Obtain basic event information, generating any necessary editing controls.
1.44
1.45 - attendees = self.get_current_attendees()
1.46 - period = self.get_current_main_period()
1.47 + attendees = self.state.get("attendees")
1.48 + period = self.state.get("main")
1.49 + stored_period = self.get_stored_main_period()
1.50 self.show_object_datetime_controls(period)
1.51
1.52 # Provide a summary of the object.
1.53 @@ -377,7 +387,7 @@
1.54
1.55 remove_type = self.can_remove_attendee(attendee_uri) and "submit" or "checkbox"
1.56 self.control("remove", remove_type, str(i),
1.57 - attendee in self.get_state("remove", list),
1.58 + attendee in self.state.get("remove"),
1.59 id="remove-%d" % i, class_="remove")
1.60
1.61 page.label(_("Remove"), for_="remove-%d" % i, class_="remove")
1.62 @@ -412,7 +422,7 @@
1.63
1.64 # Obtain the periods associated with the event.
1.65
1.66 - recurrences = self.get_current_recurrence_periods()
1.67 + recurrences = self.state.get("recurrences")
1.68
1.69 if len(recurrences) < 1:
1.70 return
1.71 @@ -471,7 +481,6 @@
1.72
1.73 if period.cancelled:
1.74 self.control("recur-restore", "checkbox", str(index),
1.75 - period in self.get_state("recur-restore", list),
1.76 id="recur-restore-%d" % index, class_="restore")
1.77
1.78 page.label(for_="recur-restore-%d" % index, class_="restore")
1.79 @@ -494,7 +503,6 @@
1.80 remove_type = self.can_remove_recurrence(period) and "submit" or "checkbox"
1.81
1.82 self.control("recur-remove", remove_type, str(index),
1.83 - period in self.get_state("recur-remove", list),
1.84 id="recur-remove-%d" % index, class_="remove")
1.85
1.86 page.label(_("Remove"), for_="recur-remove-%d" % index, class_="remove")
1.87 @@ -528,7 +536,7 @@
1.88 return
1.89
1.90 attendees = self.get_verbose_attendees(attendees)
1.91 - current_attendees = [uri for (name, uri) in uri_parts(self.get_current_attendees())]
1.92 + current_attendees = [uri for (name, uri) in uri_parts(self.state.get("attendees"))]
1.93 current_periods = set(self.get_periods(self.obj))
1.94
1.95 # Get suggestions. Attendees are aggregated and reference the existing
1.96 @@ -662,7 +670,7 @@
1.97 conflicts = set()
1.98 attendee_map = uri_dict(self.obj.get_value_map("ATTENDEE"))
1.99
1.100 - for name, participant in uri_parts(self.get_current_attendees()):
1.101 + for name, participant in uri_parts(self.state.get("attendees")):
1.102 if participant == self.user:
1.103 freebusy = self.store.get_freebusy(participant)
1.104 elif participant:
1.105 @@ -746,9 +754,6 @@
1.106
1.107 "A request handler for the event page."
1.108
1.109 - def __init__(self, resource=None, messenger=None):
1.110 - ResourceClientForObject.__init__(self, resource, messenger or Messenger())
1.111 -
1.112 def link_to(self, uid=None, recurrenceid=None):
1.113 args = self.env.get_query()
1.114 d = {}
1.115 @@ -850,8 +855,8 @@
1.116
1.117 # Obtain any new participants and those to be removed.
1.118
1.119 - attendees = self.get_current_attendees()
1.120 - removed = self.get_removed_attendees()
1.121 + attendees = self.state.get("attendees")
1.122 + removed = self.state.get("remove")
1.123
1.124 added, to_cancel = self.update_attendees(attendees, removed)
1.125
1.126 @@ -978,9 +983,9 @@
1.127 "Return period details for the periods specified for an event."
1.128
1.129 periods = []
1.130 - periods.append(self.get_current_main_period().as_event_period())
1.131 + periods.append(self.state.get("main").as_event_period())
1.132
1.133 - for i, p in enumerate(self.get_current_recurrence_periods()):
1.134 + for i, p in enumerate(self.state.get("recurrences")):
1.135 periods.append(p.as_event_period(i))
1.136
1.137 return periods
1.138 @@ -1094,7 +1099,7 @@
1.139 if remove:
1.140 still_to_remove = remove_from_collection(attendees, remove,
1.141 self.can_remove_attendee)
1.142 - self.set_state("remove", still_to_remove)
1.143 + self.state.set("remove", still_to_remove)
1.144
1.145 if add or add_suggested or remove:
1.146 attendees = filter_duplicates(attendees)
1.147 @@ -1114,7 +1119,7 @@
1.148 add = args.has_key("recur-add")
1.149
1.150 if add:
1.151 - period = self.get_current_main_period()
1.152 + period = self.state.get("main").as_form_period()
1.153 period.origin = "RDATE"
1.154 period.replacement = False
1.155 period.cancelled = False
1.156 @@ -1144,27 +1149,6 @@
1.157
1.158 # Access to current object information.
1.159
1.160 - def get_state(self, key, fn, overwrite=False):
1.161 -
1.162 - """
1.163 - Return state for the given 'key', using 'fn' if no state exists to
1.164 - compute and set the state. If 'overwrite' is set to a true value,
1.165 - compute and return the state using 'fn' regardless of existing state.
1.166 - """
1.167 -
1.168 - if overwrite or not self.state.has_key(key):
1.169 - self.state[key] = fn()
1.170 - return self.state[key]
1.171 -
1.172 - def set_state(self, key, value):
1.173 -
1.174 - """
1.175 - Set state for the given 'key', establishing new state or replacing any
1.176 - existing state with the given 'value'.
1.177 - """
1.178 -
1.179 - self.state[key] = value
1.180 -
1.181 def get_current_main_period(self):
1.182
1.183 """
1.184 @@ -1172,8 +1156,10 @@
1.185 on whether editing has begun or whether the object has just been loaded.
1.186 """
1.187
1.188 - return self.get_state("main", self.is_initial_load() and
1.189 - self.get_stored_main_period or self.get_main_period_from_page)
1.190 + if self.is_initial_load():
1.191 + return self.get_stored_main_period()
1.192 + else:
1.193 + return self.get_main_period_from_page()
1.194
1.195 def get_current_recurrence_periods(self):
1.196
1.197 @@ -1182,16 +1168,22 @@
1.198 details where no editing is in progress, using form data otherwise.
1.199 """
1.200
1.201 - return self.get_state("recurrences", self.is_initial_load() and
1.202 - self.get_stored_recurrence_periods or self.get_recurrences_from_page)
1.203 + if self.is_initial_load():
1.204 + return self.get_stored_recurrence_periods()
1.205 + else:
1.206 + return self.get_recurrences_from_page()
1.207
1.208 def update_current_recurrences(self):
1.209
1.210 "Return an updated collection of recurrences for the current object."
1.211
1.212 - return self.get_state("recurrences", self.is_initial_load() and
1.213 - self.get_stored_recurrence_periods or self.update_recurrences_from_page,
1.214 - overwrite=True)
1.215 + if self.is_initial_load():
1.216 + l = self.get_stored_recurrence_periods()
1.217 + else:
1.218 + l = self.update_recurrences_from_page()
1.219 +
1.220 + self.state.set("recurrences", l)
1.221 + return l
1.222
1.223 def get_current_attendees(self):
1.224
1.225 @@ -1201,25 +1193,22 @@
1.226 form.
1.227 """
1.228
1.229 - return self.get_state("attendees", self.is_initial_load() and
1.230 - self.get_stored_attendees or self.get_attendees_from_page)
1.231 + if self.is_initial_load():
1.232 + return self.get_stored_attendees()
1.233 + else:
1.234 + return self.get_attendees_from_page()
1.235
1.236 def update_current_attendees(self):
1.237
1.238 "Return an updated collection of attendees for the current object."
1.239
1.240 - return self.get_state("attendees", self.is_initial_load() and
1.241 - self.get_stored_attendees or self.update_attendees_from_page,
1.242 - overwrite=True)
1.243 -
1.244 - def get_removed_attendees(self):
1.245 + if self.is_initial_load():
1.246 + l = self.get_stored_attendees()
1.247 + else:
1.248 + l = self.update_attendees_from_page()
1.249
1.250 - """
1.251 - Return details of attendees to be removed according to previously
1.252 - determined removal information.
1.253 - """
1.254 -
1.255 - return self.get_state("remove", list)
1.256 + self.state.set("attendees", l)
1.257 + return l
1.258
1.259 # Full page output methods.
1.260