1.1 --- a/imiptools/client.py Wed Sep 02 17:52:52 2015 +0200
1.2 +++ b/imiptools/client.py Wed Sep 02 17:53:31 2015 +0200
1.3 @@ -266,13 +266,24 @@
1.4
1.5 # Object update methods.
1.6
1.7 + def update_recurrenceid(self):
1.8 +
1.9 + """
1.10 + Update the RECURRENCE-ID in the current object, initialising it from
1.11 + DTSTART.
1.12 + """
1.13 +
1.14 + self.obj["RECURRENCE-ID"] = [self.obj.get_datetime_item("DTSTART")]
1.15 + self.recurrenceid = self.obj.get_recurrenceid()
1.16 +
1.17 def update_dtstamp(self):
1.18
1.19 "Update the DTSTAMP in the current object."
1.20
1.21 dtstamp = self.obj.get_utc_datetime("DTSTAMP")
1.22 utcnow = to_timezone(datetime.utcnow(), "UTC")
1.23 - self.obj["DTSTAMP"] = [(format_datetime(dtstamp > utcnow and dtstamp or utcnow), {})]
1.24 + self.dtstamp = format_datetime(dtstamp > utcnow and dtstamp or utcnow)
1.25 + self.obj["DTSTAMP"] = [(self.dtstamp, {})]
1.26
1.27 def set_sequence(self, increment=False):
1.28
1.29 @@ -535,7 +546,8 @@
1.30 Update the 'freebusy' collection for this event with the periods and
1.31 transparency associated with the current object, subject to the 'user'
1.32 identity and the attendance details provided for them, indicating
1.33 - whether the update is 'for_organiser' or not.
1.34 + whether the update is being done 'for_organiser' (for the organiser of
1.35 + an event) or not.
1.36 """
1.37
1.38 # Obtain the stored object if the current object is not issued by the
1.39 @@ -569,14 +581,14 @@
1.40
1.41 """
1.42 Update the 'freebusy' collection using the given 'periods', involving
1.43 - the given 'user', indicating whether the update is 'for_organiser' or
1.44 - not, and whether it is 'updating_other' (meaning another user's
1.45 - details).
1.46 + the given 'user', indicating whether the update is 'for_organiser'
1.47 + (being done for the organiser of an event) or not, and whether it is
1.48 + 'updating_other' (meaning another user's details).
1.49 """
1.50
1.51 # Record in the free/busy details unless a non-participating attendee.
1.52 - # Use any attendee information for an organiser, not the organiser's own
1.53 - # attributes.
1.54 + # Use any attendee property information for an organiser, not the
1.55 + # organiser property attributes.
1.56
1.57 if self.is_participating(user, for_organiser and not updating_other):
1.58 self.update_freebusy(freebusy, user, for_organiser)
2.1 --- a/imiptools/handlers/common.py Wed Sep 02 17:52:52 2015 +0200
2.2 +++ b/imiptools/handlers/common.py Wed Sep 02 17:53:31 2015 +0200
2.3 @@ -70,15 +70,18 @@
2.4
2.5 "Common outgoing message handling functionality mix-in."
2.6
2.7 - def update_event_in_freebusy(self, from_organiser=True):
2.8 + def update_event_in_freebusy(self, for_organiser=True):
2.9
2.10 - "Update free/busy information when handling an object."
2.11 + """
2.12 + Update free/busy information when handling an object, doing so for the
2.13 + organiser of an event if 'for_organiser' is set to a true value.
2.14 + """
2.15
2.16 freebusy = self.store.get_freebusy(self.user)
2.17
2.18 # Obtain the attendance attributes for this user, if available.
2.19
2.20 - self.update_freebusy_for_participant(freebusy, self.user, from_organiser)
2.21 + self.update_freebusy_for_participant(freebusy, self.user, for_organiser)
2.22
2.23 # Remove original recurrence details replaced by additional
2.24 # recurrences, as well as obsolete additional recurrences.
3.1 --- a/imiptools/handlers/resource.py Wed Sep 02 17:52:52 2015 +0200
3.2 +++ b/imiptools/handlers/resource.py Wed Sep 02 17:53:31 2015 +0200
3.3 @@ -51,12 +51,33 @@
3.4
3.5 handle_for_attendee()
3.6
3.7 - def _schedule_for_attendee(self):
3.8 + def _add_for_attendee(self):
3.9
3.10 """
3.11 - Attempt to schedule the current object for the current user.
3.12 + Attempt to add a recurrence to an existing object for the current user.
3.13 + This does not request a response concerning participation, apparently.
3.14 """
3.15
3.16 + # Ignore unknown objects.
3.17 + # NOTE: We could issue a REFRESH to get such objects.
3.18 +
3.19 + if not self.get_stored_object_version():
3.20 + return
3.21 +
3.22 + # Record the event as a recurrence of the parent object.
3.23 +
3.24 + self.update_recurrenceid()
3.25 + event = self.obj.to_node()
3.26 + self.store.set_event(self.user, self.uid, self.recurrenceid, event)
3.27 +
3.28 + # Update free/busy information.
3.29 +
3.30 + self.update_event_in_freebusy(for_organiser=False)
3.31 +
3.32 + def _schedule_for_attendee(self):
3.33 +
3.34 + "Attempt to schedule the current object for the current user."
3.35 +
3.36 method = "REPLY"
3.37
3.38 # Check any constraints on the request.
3.39 @@ -124,7 +145,7 @@
3.40
3.41 # Update free/busy information.
3.42
3.43 - self.update_event_in_freebusy(from_organiser=False)
3.44 + self.update_event_in_freebusy(for_organiser=False)
3.45 else:
3.46 attendee_attr = self.obj.get_value_map("ATTENDEE")[self.user]
3.47
3.48 @@ -156,7 +177,10 @@
3.49 "An event handler."
3.50
3.51 def add(self):
3.52 - pass
3.53 +
3.54 + "Add a new occurrence to an existing event."
3.55 +
3.56 + self._record_and_respond(self._add_for_attendee)
3.57
3.58 def cancel(self):
3.59
3.60 @@ -180,6 +204,12 @@
3.61 pass
3.62
3.63 def publish(self):
3.64 +
3.65 + """
3.66 + Resources only consider events sent as requests, not generally published
3.67 + events.
3.68 + """
3.69 +
3.70 pass
3.71
3.72 def refresh(self):
3.73 @@ -189,6 +219,8 @@
3.74 do not act as organisers themselves.
3.75 """
3.76
3.77 + pass
3.78 +
3.79 def reply(self):
3.80
3.81 "Since this handler does not send requests, it will not handle replies."
3.82 @@ -211,6 +243,9 @@
3.83 "A free/busy handler."
3.84
3.85 def publish(self):
3.86 +
3.87 + "Resources ignore generally published free/busy information."
3.88 +
3.89 pass
3.90
3.91 def reply(self):