1.1 --- a/imiptools/handlers/person.py Mon Oct 26 14:05:25 2015 +0100
1.2 +++ b/imiptools/handlers/person.py Mon Oct 26 15:03:46 2015 +0100
1.3 @@ -28,21 +28,28 @@
1.4
1.5 "Event handling mechanisms specific to people."
1.6
1.7 - def _add(self, queue=True):
1.8 + def _process(self, handle, from_organiser=True, **kw):
1.9 +
1.10 + """
1.11 + Obtain valid organiser and attendee details in order to invoke the given
1.12 + 'handle' callable, with 'from_organiser' being indicated to obtain the
1.13 + details. Any additional keyword arguments will be passed to 'handle'.
1.14 + """
1.15 +
1.16 + oa = self.require_organiser_and_attendees(from_organiser)
1.17 + if not oa:
1.18 + return False
1.19 +
1.20 + (organiser, organiser_attr), attendees = oa
1.21 + return handle(organiser, attendees, **kw)
1.22 +
1.23 + def _add(self, organiser, attendees, queue=True):
1.24
1.25 """
1.26 Add an event occurrence for the current object or produce a response
1.27 that requests the event details to be sent again.
1.28 """
1.29
1.30 - # Obtain valid organiser and attendee details.
1.31 -
1.32 - oa = self.require_organiser_and_attendees()
1.33 - if not oa:
1.34 - return False
1.35 -
1.36 - (organiser, organiser_attr), attendees = oa
1.37 -
1.38 # Request details where configured, doing so for unknown objects anyway.
1.39
1.40 if self.will_refresh():
1.41 @@ -72,21 +79,13 @@
1.42
1.43 return True
1.44
1.45 - def _counter(self):
1.46 + def _counter(self, organiser, attendees):
1.47
1.48 """
1.49 Record details from a counter-proposal, updating the stored object with
1.50 attendance information.
1.51 """
1.52
1.53 - # Obtain valid organiser and attendee details.
1.54 -
1.55 - oa = self.require_organiser_and_attendees(from_organiser=False)
1.56 - if not oa:
1.57 - return False
1.58 -
1.59 - (organiser, organiser_attr), attendees = oa
1.60 -
1.61 # Update the attendance for the sender.
1.62
1.63 attendee = self.get_sending_attendee()
1.64 @@ -120,20 +119,13 @@
1.65 self.remove_freebusy_from_attendees(uri_dict(self.obj.get_value_map("ATTENDEE")))
1.66 return True
1.67
1.68 - return self._record(from_organiser=True, queue=False, cancel=True)
1.69 + return self._process(self._schedule_for_attendee, queue=False, cancel=True)
1.70
1.71 - def _declinecounter(self):
1.72 + def _declinecounter(self, organiser, attendees):
1.73
1.74 "Revoke any counter-proposal recorded as a free/busy offer."
1.75
1.76 - # Obtain valid organiser and attendee details.
1.77 -
1.78 - oa = self.require_organiser_and_attendees()
1.79 - if not oa:
1.80 - return False
1.81 -
1.82 self.remove_event_from_freebusy_offers()
1.83 -
1.84 return True
1.85
1.86 def _publish(self):
1.87 @@ -150,9 +142,9 @@
1.88 self.update_event_in_freebusy()
1.89 return True
1.90
1.91 - return self._record(from_organiser=True, queue=False)
1.92 + return self._process(self._schedule_for_attendee, queue=False)
1.93
1.94 - def _record(self, from_organiser=True, queue=False, cancel=False):
1.95 + def _schedule_for_attendee(self, organiser, attendees, queue=False, cancel=False):
1.96
1.97 """
1.98 Record details from the current object given a message originating
1.99 @@ -161,88 +153,71 @@
1.100 'cancel' is set to a true value.
1.101 """
1.102
1.103 - # Obtain valid organiser and attendee details.
1.104 + # Process for the current user, an attendee.
1.105
1.106 - oa = self.require_organiser_and_attendees(from_organiser)
1.107 - if not oa:
1.108 + if not self.have_new_object():
1.109 return False
1.110
1.111 - (organiser, organiser_attr), attendees = oa
1.112 -
1.113 - # Handle notifications and invitations.
1.114 + # Remove additional recurrences if handling a complete event.
1.115 + # Also remove any previous cancellations involving this event.
1.116
1.117 - if from_organiser:
1.118 -
1.119 - # Process for the current user, an attendee.
1.120 -
1.121 - if not self.have_new_object():
1.122 - return False
1.123 + if not self.recurrenceid:
1.124 + self.store.remove_recurrences(self.user, self.uid)
1.125 + self.store.remove_cancellations(self.user, self.uid)
1.126 + else:
1.127 + self.store.remove_cancellation(self.user, self.uid, self.recurrenceid)
1.128
1.129 - # Remove additional recurrences if handling a complete event.
1.130 - # Also remove any previous cancellations involving this event.
1.131 + # Queue any request, if appropriate.
1.132
1.133 - if not self.recurrenceid:
1.134 - self.store.remove_recurrences(self.user, self.uid)
1.135 - self.store.remove_cancellations(self.user, self.uid)
1.136 - else:
1.137 - self.store.remove_cancellation(self.user, self.uid, self.recurrenceid)
1.138 + if queue:
1.139 + self.store.queue_request(self.user, self.uid, self.recurrenceid)
1.140
1.141 - # Queue any request, if appropriate.
1.142 + # Set the complete event or an additional occurrence.
1.143
1.144 - if queue:
1.145 - self.store.queue_request(self.user, self.uid, self.recurrenceid)
1.146 -
1.147 - # Set the complete event or an additional occurrence.
1.148 + self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
1.149
1.150 - self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
1.151 -
1.152 - # Cancel complete events or particular occurrences in recurring
1.153 - # events.
1.154 + # Cancel complete events or particular occurrences in recurring
1.155 + # events.
1.156
1.157 - if cancel:
1.158 - self.store.cancel_event(self.user, self.uid, self.recurrenceid)
1.159 + if cancel:
1.160 + self.store.cancel_event(self.user, self.uid, self.recurrenceid)
1.161
1.162 - # Remove any associated request.
1.163 -
1.164 - self.store.dequeue_request(self.user, self.uid, self.recurrenceid)
1.165 - self.store.remove_counters(self.user, self.uid, self.recurrenceid)
1.166 + # Remove any associated request.
1.167
1.168 - # No return message will occur to update the free/busy
1.169 - # information, so this is done here using outgoing message
1.170 - # functionality.
1.171 -
1.172 - self.remove_event_from_freebusy()
1.173 + self.store.dequeue_request(self.user, self.uid, self.recurrenceid)
1.174 + self.store.remove_counters(self.user, self.uid, self.recurrenceid)
1.175
1.176 - # Update the recipient's record of the organiser's schedule.
1.177 -
1.178 - self.remove_freebusy_from_organiser(organiser)
1.179 + # No return message will occur to update the free/busy
1.180 + # information, so this is done here using outgoing message
1.181 + # functionality.
1.182
1.183 - else:
1.184 - self.update_freebusy_from_organiser(organiser)
1.185 + self.remove_event_from_freebusy()
1.186
1.187 - # As organiser, update attendance from valid attendees.
1.188 + # Update the recipient's record of the organiser's schedule.
1.189 +
1.190 + self.remove_freebusy_from_organiser(organiser)
1.191
1.192 else:
1.193 - if self.merge_attendance(attendees):
1.194 - self.update_freebusy_from_attendees(attendees)
1.195 + self.update_freebusy_from_organiser(organiser)
1.196
1.197 return True
1.198
1.199 - def _refresh(self):
1.200 + def _schedule_for_organiser(self, organiser, attendees):
1.201 +
1.202 + "As organiser, update attendance from valid attendees."
1.203 +
1.204 + if self.merge_attendance(attendees):
1.205 + self.update_freebusy_from_attendees(attendees)
1.206 +
1.207 + return True
1.208 +
1.209 + def _refresh(self, organiser, attendees):
1.210
1.211 """
1.212 Respond to a refresh message by providing complete event details to
1.213 attendees.
1.214 """
1.215
1.216 - # Obtain valid organiser and attendee details.
1.217 -
1.218 - oa = self.require_organiser_and_attendees(False)
1.219 - if not oa:
1.220 - return False
1.221 -
1.222 - (organiser, organiser_attr), attendees = oa
1.223 -
1.224 # Filter by stored attendees.
1.225
1.226 obj = self.get_stored_object_version()
1.227 @@ -268,7 +243,7 @@
1.228
1.229 "Queue a suggested additional recurrence for any active event."
1.230
1.231 - if self.allow_add() and self._add(queue=True):
1.232 + if self.allow_add() and self._process(self._add, queue=True):
1.233 return self.wrap("An addition to an event has been received.")
1.234
1.235 def cancel(self):
1.236 @@ -282,14 +257,14 @@
1.237
1.238 "Record a counter-proposal to a proposed event."
1.239
1.240 - if self._counter():
1.241 + if self._process(self._counter, from_organiser=False):
1.242 return self.wrap("A counter proposal to an event invitation has been received.", link=True)
1.243
1.244 def declinecounter(self):
1.245
1.246 "Record a rejection of a counter-proposal."
1.247
1.248 - if self._declinecounter():
1.249 + if self._process(self._declinecounter):
1.250 return self.wrap("Your counter proposal to an event invitation has been declined.", link=True)
1.251
1.252 def publish(self):
1.253 @@ -304,7 +279,7 @@
1.254 "Requests to refresh events are handled either here or by the client."
1.255
1.256 if self.is_refreshing():
1.257 - return self._refresh()
1.258 + return self._process(self._refresh, from_organiser=False)
1.259 else:
1.260 return self.wrap("A request for updated event details has been received.")
1.261
1.262 @@ -312,14 +287,14 @@
1.263
1.264 "Record replies and notify the recipient."
1.265
1.266 - if self._record(from_organiser=False, queue=False):
1.267 + if self._process(self._schedule_for_organiser, from_organiser=False):
1.268 return self.wrap("A reply to an event invitation has been received.")
1.269
1.270 def request(self):
1.271
1.272 "Hold requests and notify the recipient."
1.273
1.274 - if self._record(from_organiser=True, queue=True):
1.275 + if self._process(self._schedule_for_attendee, queue=True):
1.276 return self.wrap("An event invitation has been received.")
1.277
1.278 class PersonFreebusy(CommonFreebusy, Handler):