1.1 --- a/imiptools/handlers/resource.py Sun Aug 16 00:39:41 2015 +0200
1.2 +++ b/imiptools/handlers/resource.py Sun Aug 16 00:40:13 2015 +0200
1.3 @@ -20,6 +20,7 @@
1.4 """
1.5
1.6 from imiptools.data import get_address, to_part
1.7 +from imiptools.dates import ValidityError
1.8 from imiptools.handlers import Handler
1.9 from imiptools.handlers.common import CommonFreebusy, Outgoing
1.10
1.11 @@ -41,10 +42,6 @@
1.12
1.13 organiser_item, attendees = oa
1.14
1.15 - # Process each attendee separately.
1.16 -
1.17 - calendar = []
1.18 -
1.19 # Process for the current user, a resource as attendee.
1.20
1.21 if not self.have_new_object() or not self.is_attendee(self.user):
1.22 @@ -52,11 +49,7 @@
1.23
1.24 # Collect response objects produced when handling the request.
1.25
1.26 - response = handle_for_attendee()
1.27 - if response:
1.28 - calendar.append(response)
1.29 -
1.30 - return calendar
1.31 + handle_for_attendee()
1.32
1.33 def _schedule_for_attendee(self):
1.34
1.35 @@ -64,20 +57,16 @@
1.36 Attempt to schedule the current object for the current user.
1.37 """
1.38
1.39 + method = "REPLY"
1.40 +
1.41 # Check any constraints on the request.
1.42
1.43 try:
1.44 - check = self.check_object()
1.45 -
1.46 - # NOTE: Support countering by correcting any invalid values and
1.47 - # NOTE: attempting to schedule using the corrected values.
1.48 -
1.49 - if check:
1.50 - raise self.ValidityError
1.51 + corrected = self.correct_object()
1.52
1.53 # Refuse to schedule obviously invalid requests.
1.54
1.55 - except self.ValidityError:
1.56 + except ValidityError:
1.57 scheduled = False
1.58
1.59 # With a valid request, determine whether the event can be scheduled.
1.60 @@ -94,34 +83,57 @@
1.61 freebusy = self.store.get_freebusy(self.user)
1.62 scheduled = self.can_schedule(freebusy, periods)
1.63
1.64 - # NOTE: Support countering by finding the next available slot if
1.65 - # NOTE: the event cannot be scheduled.
1.66 + # Where the corrected object can be scheduled, issue a counter
1.67 + # request.
1.68 +
1.69 + if scheduled and corrected:
1.70 + method = "COUNTER"
1.71 +
1.72 + # Find the next available slot if the event cannot be scheduled.
1.73 +
1.74 + #elif not scheduled and len(periods) == 1:
1.75 +
1.76 + # # Find a free period, update the object with the details.
1.77 +
1.78 + # duration = periods[0].get_duration()
1.79 + # free = invert_freebusy(freebusy)
1.80 +
1.81 + # for found in periods_from(free, periods[0]):
1.82 + # # NOTE: Correct the found period first.
1.83 + # if found.get_duration() >= duration
1.84 + # scheduled = True
1.85 + # method = "COUNTER"
1.86 + # # NOTE: Set the period using the original duration.
1.87 + # break
1.88
1.89 # Update the participation of the resource in the object.
1.90
1.91 - attendee_attr = self.update_participation(self.obj,
1.92 - scheduled and "ACCEPTED" or "DECLINED")
1.93 + if method == "REPLY":
1.94 + attendee_attr = self.update_participation(self.obj,
1.95 + scheduled and "ACCEPTED" or "DECLINED")
1.96
1.97 - # Set the complete event or an additional occurrence.
1.98 + # Set the complete event or an additional occurrence.
1.99
1.100 - event = self.obj.to_node()
1.101 - self.store.set_event(self.user, self.uid, self.recurrenceid, event)
1.102 + event = self.obj.to_node()
1.103 + self.store.set_event(self.user, self.uid, self.recurrenceid, event)
1.104
1.105 - # Remove additional recurrences if handling a complete event.
1.106 + # Remove additional recurrences if handling a complete event.
1.107 +
1.108 + if not self.recurrenceid:
1.109 + self.store.remove_recurrences(self.user, self.uid)
1.110
1.111 - if not self.recurrenceid:
1.112 - self.store.remove_recurrences(self.user, self.uid)
1.113 + # Update free/busy information.
1.114
1.115 - # Update free/busy information.
1.116 -
1.117 - self.update_event_in_freebusy(from_organiser=False)
1.118 + self.update_event_in_freebusy(from_organiser=False)
1.119 + else:
1.120 + attendee_attr = self.obj.get_value_map("ATTENDEE")[self.user]
1.121
1.122 # Make a version of the object with just this attendee, update the
1.123 # DTSTAMP in the response, and return the object for sending.
1.124
1.125 self.obj["ATTENDEE"] = [(self.user, attendee_attr)]
1.126 self.update_dtstamp()
1.127 - return self.obj.to_node()
1.128 + self.add_result(method, map(get_address, self.obj.get_values("ORGANIZER")), to_part(method, [self.obj.to_node()]))
1.129
1.130 def _cancel_for_attendee(self):
1.131
1.132 @@ -137,10 +149,6 @@
1.133
1.134 self.remove_event_from_freebusy()
1.135
1.136 - # No response is required.
1.137 -
1.138 - return None
1.139 -
1.140 class Event(ResourceHandler):
1.141
1.142 "An event handler."
1.143 @@ -194,9 +202,7 @@
1.144 No support for countering requests is implemented.
1.145 """
1.146
1.147 - response = self._record_and_respond(self._schedule_for_attendee)
1.148 - if response:
1.149 - self.add_result("REPLY", map(get_address, self.obj.get_values("ORGANIZER")), to_part("REPLY", response))
1.150 + self._record_and_respond(self._schedule_for_attendee)
1.151
1.152 class Freebusy(Handler, CommonFreebusy):
1.153