1.1 --- a/imiptools/handlers/resource.py Mon Oct 26 15:03:46 2015 +0100
1.2 +++ b/imiptools/handlers/resource.py Mon Oct 26 17:12:56 2015 +0100
1.3 @@ -81,81 +81,21 @@
1.4
1.5 "Attempt to schedule the current object for the current user."
1.6
1.7 - method = "REPLY"
1.8 attendee_attr = uri_dict(self.obj.get_value_map("ATTENDEE"))[self.user]
1.9 -
1.10 - # Check any constraints on the request.
1.11 -
1.12 - try:
1.13 - corrected = self.correct_object()
1.14 -
1.15 - # Refuse to schedule obviously invalid requests.
1.16 -
1.17 - except ValidityError:
1.18 - attendee_attr = self.update_participation("DECLINED")
1.19 -
1.20 - # With a valid request, determine whether the event can be scheduled.
1.21 -
1.22 - else:
1.23 - # Interpretation of periods can depend on the time zone.
1.24 + scheduled = self.schedule()
1.25
1.26 - tzid = self.get_tzid()
1.27 -
1.28 - # If newer than any old version, discard old details from the
1.29 - # free/busy record and check for suitability.
1.30 -
1.31 - periods = self.obj.get_periods(tzid, self.get_window_end())
1.32 -
1.33 - freebusy = self.store.get_freebusy(self.user)
1.34 - offers = self.store.get_freebusy_offers(self.user)
1.35 -
1.36 - # Check the periods against any scheduled events and against
1.37 - # any outstanding offers.
1.38 -
1.39 - scheduled = self.can_schedule(freebusy, periods)
1.40 - scheduled = scheduled and self.can_schedule(offers, periods)
1.41 -
1.42 - # Where the corrected object can be scheduled, issue a counter
1.43 - # request.
1.44 + # Update the participation of the resource in the object.
1.45 + # Update free/busy information.
1.46
1.47 - if scheduled and corrected:
1.48 - method = "COUNTER"
1.49 -
1.50 - # Find the next available slot if the event cannot be scheduled.
1.51 -
1.52 - #elif not scheduled and len(periods) == 1:
1.53 -
1.54 - # # Find a free period, update the object with the details.
1.55 -
1.56 - # duration = periods[0].get_duration()
1.57 - # free = invert_freebusy(freebusy)
1.58 + if scheduled in ("ACCEPTED", "DECLINED"):
1.59 + method = "REPLY"
1.60 + attendee_attr = self.update_participation(scheduled)
1.61
1.62 - # for found in periods_from(free, periods[0]):
1.63 - # # NOTE: Correct the found period first.
1.64 - # if found.get_duration() >= duration
1.65 - # scheduled = True
1.66 - # method = "COUNTER"
1.67 - # # NOTE: Set the period using the original duration.
1.68 - # break
1.69 -
1.70 - # Update the participation of the resource in the object.
1.71 - # Update free/busy information.
1.72 + self.update_event_in_freebusy(for_organiser=False)
1.73 + self.remove_event_from_freebusy_offers()
1.74
1.75 - if method == "REPLY":
1.76 - attendee_attr = self.update_participation(scheduled and "ACCEPTED" or "DECLINED")
1.77 -
1.78 - self.update_event_in_freebusy(for_organiser=False)
1.79 - self.remove_event_from_freebusy_offers()
1.80 + # Set the complete event or an additional occurrence.
1.81
1.82 - # For countered proposals, record the offer in the resource's
1.83 - # free/busy collection.
1.84 -
1.85 - elif method == "COUNTER":
1.86 - self.update_event_in_freebusy_offers()
1.87 -
1.88 - # Set the complete event or an additional occurrence.
1.89 -
1.90 - if method == "REPLY":
1.91 event = self.obj.to_node()
1.92 self.store.set_event(self.user, self.uid, self.recurrenceid, event)
1.93
1.94 @@ -168,6 +108,19 @@
1.95 else:
1.96 self.store.remove_cancellation(self.user, self.uid, self.recurrenceid)
1.97
1.98 + # For countered proposals, record the offer in the resource's
1.99 + # free/busy collection.
1.100 +
1.101 + elif scheduled == "COUNTER":
1.102 + method = "COUNTER"
1.103 + self.update_event_in_freebusy_offers()
1.104 +
1.105 + # For inappropriate periods, reply declining participation.
1.106 +
1.107 + else:
1.108 + method = "REPLY"
1.109 + attendee_attr = self.update_participation("DECLINED")
1.110 +
1.111 # Make a version of the object with just this attendee, update the
1.112 # DTSTAMP in the response, and return the object for sending.
1.113
1.114 @@ -198,6 +151,48 @@
1.115
1.116 self.remove_event_from_freebusy_offers()
1.117
1.118 + # Scheduling details.
1.119 +
1.120 + def schedule(self):
1.121 +
1.122 + """
1.123 + Attempt to schedule the current object, returning an indication of the
1.124 + kind of response to be returned: "COUNTER" for counter-proposals,
1.125 + "ACCEPTED" for acceptances, "DECLINED" for rejections, and None for
1.126 + invalid requests.
1.127 + """
1.128 +
1.129 + # Check any constraints on the request.
1.130 +
1.131 + try:
1.132 + corrected = self.correct_object()
1.133 +
1.134 + # Refuse to schedule obviously invalid requests.
1.135 +
1.136 + except ValidityError:
1.137 + return None
1.138 +
1.139 + # With a valid request, determine whether the event can be scheduled.
1.140 +
1.141 + # If newer than any old version, discard old details from the
1.142 + # free/busy record and check for suitability.
1.143 +
1.144 + periods = self.get_periods(self.obj)
1.145 +
1.146 + freebusy = self.store.get_freebusy(self.user)
1.147 + offers = self.store.get_freebusy_offers(self.user)
1.148 +
1.149 + # Check the periods against any scheduled events and against
1.150 + # any outstanding offers.
1.151 +
1.152 + scheduled = self.can_schedule(freebusy, periods)
1.153 + scheduled = scheduled and self.can_schedule(offers, periods)
1.154 +
1.155 + # Where the corrected object can be scheduled, issue a counter
1.156 + # request.
1.157 +
1.158 + return scheduled and (corrected and "COUNTER" or "ACCEPTED") or "DECLINED"
1.159 +
1.160 class Event(ResourceHandler):
1.161
1.162 "An event handler."