1.1 --- a/imiptools/handlers/person_outgoing.py Sun Mar 01 00:20:17 2015 +0100
1.2 +++ b/imiptools/handlers/person_outgoing.py Sun Mar 01 00:24:11 2015 +0100
1.3 @@ -21,8 +21,8 @@
1.4 """
1.5
1.6 from imiptools.content import Handler
1.7 -from imiptools.data import uri_dict, uri_item, uri_values
1.8 -from imiptools.dates import get_default_timezone
1.9 +from imiptools.data import get_window_end, uri_dict, uri_item, uri_values
1.10 +from imiptools.dates import format_datetime, get_default_timezone, to_timezone
1.11 from imiptools.profile import Preferences
1.12
1.13 class PersonHandler(Handler):
1.14 @@ -72,35 +72,75 @@
1.15
1.16 self.store.dequeue_request(identity, self.uid, self.recurrenceid)
1.17
1.18 + # Interpretation of periods can depend on the time zone.
1.19 +
1.20 + preferences = Preferences(identity)
1.21 + tzid = preferences.get("TZID") or get_default_timezone()
1.22 +
1.23 + # Where a recurring object is updated by a specific occurrence, the
1.24 + # details of the recurring "parent" must be changed.
1.25 +
1.26 + if self.recurrenceid:
1.27 + obj = self.get_parent_object(identity)
1.28 + recurrence = self.obj.get_datetime("RECURRENCE-ID")
1.29 +
1.30 + if obj.has_recurrence(tzid, recurrence):
1.31 + item = obj.get_item("EXDATE")
1.32 + if item:
1.33 + exdates, exdate_attr = item
1.34 + if not isinstance(exdates, list):
1.35 + exdates = [exdates]
1.36 + else:
1.37 + exdates, exdate_attr = [], {}
1.38 +
1.39 + # Convert the occurrence to the same time regime as the other
1.40 + # exceptions.
1.41 +
1.42 + exdate_tzid = exdate_attr.get("TZID")
1.43 + exdate = recurrence
1.44 + if exdate_tzid:
1.45 + exdate = to_timezone(exdate, exdate_tzid)
1.46 + else:
1.47 + exdate = to_timezone(exdate, "UTC")
1.48 +
1.49 + # Update the exceptions and store the modified parent event.
1.50 +
1.51 + exdates.append(format_datetime(exdate))
1.52 + obj["EXDATE"] = [(exdates, exdate_attr)]
1.53 +
1.54 + self.store.set_event(identity, self.uid, None, obj.to_node())
1.55 +
1.56 # Update free/busy information.
1.57
1.58 if update_freebusy:
1.59
1.60 - # Use the stored event for non-organiser messages in case the reply
1.61 - # is incomplete, as is seen when Claws sends a REPLY for an object
1.62 - # originally employing recurrence information.
1.63 + freebusy = self.store.get_freebusy(identity)
1.64
1.65 - if not from_organiser:
1.66 - obj = self.get_object(identity)
1.67 - else:
1.68 - obj = self.obj
1.69 + # Use the stored event in case the reply is incomplete, as is seen
1.70 + # when Claws sends a REPLY for an object originally employing
1.71 + # recurrence information. Additionally, parent object details will
1.72 + # also be consulted if available.
1.73
1.74 - # Interpretation of periods can depend on the time zone.
1.75 -
1.76 - preferences = Preferences(identity)
1.77 - tzid = preferences.get("TZID") or get_default_timezone()
1.78 + obj = self.get_object(identity)
1.79
1.80 # If newer than any old version, discard old details from the
1.81 # free/busy record and check for suitability.
1.82
1.83 - periods = obj.get_periods_for_freebusy(tzid)
1.84 - freebusy = self.store.get_freebusy(identity)
1.85 + periods = obj.get_periods_for_freebusy(tzid, get_window_end(tzid))
1.86
1.87 if attr.get("PARTSTAT") != "DECLINED":
1.88 self.update_freebusy(freebusy, identity, periods)
1.89 else:
1.90 self.remove_from_freebusy(freebusy, identity)
1.91
1.92 + # For any parent object, refresh the updated periods.
1.93 +
1.94 + if self.recurrenceid:
1.95 + obj = self.get_parent_object(identity)
1.96 + periods = obj.get_periods_for_freebusy(tzid, get_window_end(tzid))
1.97 +
1.98 + self._update_freebusy(freebusy, identity, periods, None)
1.99 +
1.100 if self.publisher:
1.101 self.publisher.set_freebusy(identity, freebusy)
1.102