1.1 --- a/imiptools/client.py Sun Sep 06 02:17:33 2015 +0200
1.2 +++ b/imiptools/client.py Sun Sep 06 17:59:02 2015 +0200
1.3 @@ -339,7 +339,7 @@
1.4 """
1.5
1.6 attendees = uri_dict((obj or self.obj).get_value_map("ATTENDEE"))
1.7 - return attendees.get(user or self.user) or {}
1.8 + return attendees.get(user or self.user)
1.9
1.10 def is_participating(self, user, as_organiser=False, obj=None):
1.11
1.12 @@ -349,8 +349,11 @@
1.13 participating in the current object event.
1.14 """
1.15
1.16 + # Use any attendee property information for an organiser, not the
1.17 + # organiser property attributes.
1.18 +
1.19 attr = self.get_attendance(user, obj=obj)
1.20 - return as_organiser or not attr or attr.get("PARTSTAT") != "DECLINED"
1.21 + return as_organiser or attr is not None and not attr or attr and attr.get("PARTSTAT") != "DECLINED"
1.22
1.23 def get_overriding_transparency(self, user, as_organiser=False):
1.24
1.25 @@ -567,18 +570,32 @@
1.26 """
1.27
1.28 # Record in the free/busy details unless a non-participating attendee.
1.29 - # Use any attendee property information for an organiser, not the
1.30 - # organiser property attributes.
1.31 + # Remove periods for non-participating attendees.
1.32
1.33 if self.is_participating(user, for_organiser and not updating_other):
1.34 self.update_freebusy(freebusy, user, for_organiser)
1.35 else:
1.36 self.remove_from_freebusy(freebusy)
1.37
1.38 + def remove_freebusy_for_participant(self, freebusy, user, for_organiser=False,
1.39 + updating_other=False):
1.40 +
1.41 + """
1.42 + Remove details from the 'freebusy' collection for the given 'user',
1.43 + indicating whether the modification is 'for_organiser' (being done for
1.44 + the organiser of an event) or not, and whether it is 'updating_other'
1.45 + (meaning another user's details).
1.46 + """
1.47 +
1.48 + # Remove from the free/busy details if a specified attendee.
1.49 +
1.50 + if self.is_participating(user, for_organiser and not updating_other):
1.51 + self.remove_from_freebusy(freebusy)
1.52 +
1.53 # Convenience methods for updating stored free/busy information received
1.54 # from other users.
1.55
1.56 - def update_freebusy_from_participant(self, user, for_organiser):
1.57 + def update_freebusy_from_participant(self, user, for_organiser, fn=None):
1.58
1.59 """
1.60 For the current user, record the free/busy information for another
1.61 @@ -586,6 +603,8 @@
1.62 maintaining a separate record of their free/busy details.
1.63 """
1.64
1.65 + fn = fn or self.update_freebusy_for_participant
1.66 +
1.67 # A user does not store free/busy information for themself as another
1.68 # party.
1.69
1.70 @@ -593,7 +612,7 @@
1.71 return
1.72
1.73 freebusy = self.store.get_freebusy_for_other(self.user, user)
1.74 - self.update_freebusy_for_participant(freebusy, user, for_organiser, True)
1.75 + fn(freebusy, user, for_organiser, True)
1.76
1.77 # Tidy up any obsolete recurrences.
1.78
1.79 @@ -613,4 +632,17 @@
1.80 for attendee in attendees.keys():
1.81 self.update_freebusy_from_participant(attendee, False)
1.82
1.83 + def remove_freebusy_from_organiser(self, organiser):
1.84 +
1.85 + "For the current user, remove free/busy information from 'organiser'."
1.86 +
1.87 + self.update_freebusy_from_participant(organiser, True, self.remove_freebusy_for_participant)
1.88 +
1.89 + def remove_freebusy_from_attendees(self, attendees):
1.90 +
1.91 + "For the current user, remove free/busy information from 'attendees'."
1.92 +
1.93 + for attendee in attendees.keys():
1.94 + self.update_freebusy_from_participant(attendee, False, self.remove_freebusy_for_participant)
1.95 +
1.96 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imiptools/handlers/person.py Sun Sep 06 02:17:33 2015 +0200
2.2 +++ b/imiptools/handlers/person.py Sun Sep 06 17:59:02 2015 +0200
2.3 @@ -91,14 +91,6 @@
2.4 if not self.have_new_object() or not self.is_attendee(self.user):
2.5 return False
2.6
2.7 - # Indicate the organiser's implicit attendance if mentioned in the
2.8 - # cancellation message.
2.9 -
2.10 - if cancel:
2.11 - obj_attendees = uri_dict(self.obj.get_value_map("ATTENDEE"))
2.12 - if obj_attendees.has_key(organiser):
2.13 - obj_attendees[organiser]["PARTSTAT"] = "DECLINED"
2.14 -
2.15 # Remove additional recurrences if handling a complete event.
2.16
2.17 if not self.recurrenceid:
2.18 @@ -112,7 +104,7 @@
2.19 # Cancel complete events or particular occurrences in recurring
2.20 # events.
2.21
2.22 - elif cancel:
2.23 + if cancel:
2.24 self.store.cancel_event(self.user, self.uid, self.recurrenceid)
2.25
2.26 # Remove any associated request.
2.27 @@ -125,9 +117,12 @@
2.28
2.29 self.remove_event_from_freebusy()
2.30
2.31 - # Update the recipient's record of the organiser's schedule.
2.32 + # Update the recipient's record of the organiser's schedule.
2.33
2.34 - self.update_freebusy_from_organiser(organiser)
2.35 + self.remove_freebusy_from_organiser(organiser)
2.36 +
2.37 + else:
2.38 + self.update_freebusy_from_organiser(organiser)
2.39
2.40 # Set the complete event or an additional occurrence.
2.41
3.1 --- a/imiptools/handlers/person_outgoing.py Sun Sep 06 02:17:33 2015 +0200
3.2 +++ b/imiptools/handlers/person_outgoing.py Sun Sep 06 17:59:02 2015 +0200
3.3 @@ -116,14 +116,14 @@
3.4
3.5 return True
3.6
3.7 - def _remove(self, from_organiser=True):
3.8 + def _remove(self):
3.9
3.10 """
3.11 Remove details from the current object given a message originating
3.12 from an organiser if 'from_organiser' is set to a true value.
3.13 """
3.14
3.15 - self.set_identity(from_organiser)
3.16 + self.set_identity(True)
3.17
3.18 # Check for event using UID.
3.19
3.20 @@ -146,6 +146,10 @@
3.21 given_attendees = set(uri_values(self.obj.get_values("ATTENDEE")))
3.22 cancel_entire_event = not all_attendees.difference(given_attendees)
3.23
3.24 + # Update the recipient's record of the organiser's schedule.
3.25 +
3.26 + self.remove_freebusy_from_organiser(self.obj.get_value("ORGANIZER"))
3.27 +
3.28 # Otherwise, remove the given attendees and update the event.
3.29
3.30 if not cancel_entire_event and obj:
3.31 @@ -196,7 +200,7 @@
3.32
3.33 "Remove an event or a recurrence."
3.34
3.35 - self._remove(True)
3.36 + self._remove()
3.37
3.38 def counter(self):
3.39
4.1 --- a/tests/templates/event-request-person-recurring-day-floating.txt Sun Sep 06 02:17:33 2015 +0200
4.2 +++ b/tests/templates/event-request-person-recurring-day-floating.txt Sun Sep 06 17:59:02 2015 +0200
4.3 @@ -9,7 +9,7 @@
4.4 MIME-Version: 1.0
4.5 Content-Transfer-Encoding: 7bit
4.6
4.7 -This message contains an event.
4.8 +This message contains an event. Note that the organiser is not attending!
4.9 --===============0047278175==
4.10 MIME-Version: 1.0
4.11 Content-Transfer-Encoding: 7bit
5.1 --- a/tests/templates/event-request-person-recurring-reschedule-instance.txt Sun Sep 06 02:17:33 2015 +0200
5.2 +++ b/tests/templates/event-request-person-recurring-reschedule-instance.txt Sun Sep 06 17:59:02 2015 +0200
5.3 @@ -22,6 +22,7 @@
5.4 BEGIN:VEVENT
5.5 ORGANIZER:mailto:paul.boddie@example.com
5.6 ATTENDEE;RSVP=TRUE:mailto:vincent.vole@example.com
5.7 +ATTENDEE;RSVP=TRUE:mailto:paul.boddie@example.com
5.8 DTSTAMP:20141009T182500Z
5.9 DTSTART;TZID=Europe/Oslo:20141011T100000
5.10 DTEND;TZID=Europe/Oslo:20141011T110000
6.1 --- a/tests/templates/event-request-person-recurring.txt Sun Sep 06 02:17:33 2015 +0200
6.2 +++ b/tests/templates/event-request-person-recurring.txt Sun Sep 06 17:59:02 2015 +0200
6.3 @@ -9,7 +9,7 @@
6.4 MIME-Version: 1.0
6.5 Content-Transfer-Encoding: 7bit
6.6
6.7 -This message contains an event. Note that the organiser is not attending!
6.8 +This message contains an event.
6.9
6.10 --===============0047278175==
6.11 MIME-Version: 1.0
6.12 @@ -23,6 +23,7 @@
6.13 BEGIN:VEVENT
6.14 ORGANIZER:mailto:paul.boddie@example.com
6.15 ATTENDEE;RSVP=TRUE:mailto:vincent.vole@example.com
6.16 +ATTENDEE;RSVP=TRUE:mailto:paul.boddie@example.com
6.17 DTSTAMP:20141009T182400Z
6.18 DTSTART;TZID=Europe/Oslo:20141010T100000
6.19 DTEND;TZID=Europe/Oslo:20141010T110000