1.1 --- a/imiptools/handlers/__init__.py Tue Mar 31 19:09:11 2015 +0200
1.2 +++ b/imiptools/handlers/__init__.py Tue Mar 31 19:12:21 2015 +0200
1.3 @@ -21,11 +21,12 @@
1.4
1.5 from datetime import datetime
1.6 from email.mime.text import MIMEText
1.7 +from imiptools.client import Client
1.8 from imiptools.config import MANAGER_PATH, MANAGER_URL
1.9 from imiptools.data import Object, \
1.10 - get_address, get_uri, get_value, get_window_end, \
1.11 + get_address, get_uri, get_value, \
1.12 is_new_object, uri_dict, uri_item, uri_values
1.13 -from imiptools.dates import format_datetime, get_default_timezone, to_timezone
1.14 +from imiptools.dates import format_datetime, to_timezone
1.15 from imiptools.period import can_schedule, remove_period, \
1.16 remove_additional_periods, remove_affected_period, \
1.17 update_freebusy
1.18 @@ -45,7 +46,7 @@
1.19 recurrenceid and "/%s" % recurrenceid or ""
1.20 )
1.21
1.22 -class Handler:
1.23 +class Handler(Client):
1.24
1.25 "General handler support."
1.26
1.27 @@ -56,6 +57,8 @@
1.28 'recipient' of the object (if specifically indicated).
1.29 """
1.30
1.31 + Client.__init__(self, recipient and get_uri(recipient))
1.32 +
1.33 self.senders = senders and set(map(get_address, senders))
1.34 self.recipient = recipient and get_address(recipient)
1.35 self.messenger = messenger
1.36 @@ -186,65 +189,66 @@
1.37
1.38 # Convenience methods for updating stored free/busy information.
1.39
1.40 - def update_freebusy_from_participant(self, user, participant_item, for_organiser):
1.41 + def update_freebusy_from_participant(self, participant_item, for_organiser):
1.42
1.43 """
1.44 - For the given 'user', record the free/busy information for the
1.45 + For the calendar user, record the free/busy information for the
1.46 'participant_item' (a value plus attributes) representing a different
1.47 identity, thus maintaining a separate record of their free/busy details.
1.48 """
1.49
1.50 participant, participant_attr = participant_item
1.51
1.52 - if participant == user:
1.53 + if participant == self.user:
1.54 return
1.55
1.56 - freebusy = self.store.get_freebusy_for_other(user, participant)
1.57 - tzid = self.get_tzid(user)
1.58 - window_end = get_window_end(tzid)
1.59 + freebusy = self.store.get_freebusy_for_other(self.user, participant)
1.60
1.61 # Obtain the stored object if the current object is not issued by the
1.62 # organiser.
1.63
1.64 - obj = for_organiser and self.obj or self.get_object(user)
1.65 + obj = for_organiser and self.obj or self.get_object()
1.66 if not obj:
1.67 return
1.68
1.69 # Obtain the affected periods.
1.70
1.71 - periods = obj.get_periods_for_freebusy(tzid, window_end)
1.72 + periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
1.73
1.74 # Record in the free/busy details unless a non-participating attendee.
1.75
1.76 self.update_freebusy_for_participant(freebusy, periods, participant_attr,
1.77 - for_organiser and self.is_not_attendee(participant, self.obj))
1.78 + for_organiser and not self.is_attendee(participant))
1.79
1.80 - self.remove_freebusy_for_recurrences(freebusy, self.store.get_recurrences(user, self.uid))
1.81 - self.store.set_freebusy_for_other(user, freebusy, participant)
1.82 + self.remove_freebusy_for_recurrences(freebusy, self.store.get_recurrences(self.user, self.uid))
1.83 + self.store.set_freebusy_for_other(self.user, freebusy, participant)
1.84
1.85 - def update_freebusy_from_organiser(self, attendee, organiser_item):
1.86 + def update_freebusy_from_organiser(self, organiser_item):
1.87
1.88 """
1.89 - For the 'attendee', record free/busy information from the
1.90 + For the current user, record free/busy information from the
1.91 'organiser_item' (a value plus attributes).
1.92 """
1.93
1.94 - self.update_freebusy_from_participant(attendee, organiser_item, True)
1.95 + self.update_freebusy_from_participant(organiser_item, True)
1.96
1.97 - def update_freebusy_from_attendees(self, organiser, attendees):
1.98 + def update_freebusy_from_attendees(self, attendees):
1.99
1.100 - "For the 'organiser', record free/busy information from 'attendees'."
1.101 + "For the current user, record free/busy information from 'attendees'."
1.102
1.103 for attendee_item in attendees.items():
1.104 - self.update_freebusy_from_participant(organiser, attendee_item, False)
1.105 + self.update_freebusy_from_participant(attendee_item, False)
1.106
1.107 # Logic, filtering and access to calendar structures and other data.
1.108
1.109 - def is_not_attendee(self, identity, obj):
1.110 + def is_attendee(self, identity, obj=None):
1.111
1.112 - "Return whether 'identity' is not an attendee in 'obj'."
1.113 + """
1.114 + Return whether 'identity' is an attendee in the current object, or in
1.115 + 'obj' if specified.
1.116 + """
1.117
1.118 - return identity not in uri_values(obj.get_values("ATTENDEE"))
1.119 + return identity in uri_values((obj or self.obj).get_values("ATTENDEE"))
1.120
1.121 def can_schedule(self, freebusy, periods):
1.122 return can_schedule(freebusy, periods, self.uid, self.recurrenceid)
1.123 @@ -362,41 +366,42 @@
1.124
1.125 return senders
1.126
1.127 - def _get_object(self, user, uid, recurrenceid):
1.128 + def _get_object(self, uid, recurrenceid):
1.129
1.130 """
1.131 - Return the stored object for the given 'user', 'uid' and 'recurrenceid'.
1.132 + Return the stored object for the current user, with the given 'uid' and
1.133 + 'recurrenceid'.
1.134 """
1.135
1.136 - fragment = self.store.get_event(user, uid, recurrenceid)
1.137 + fragment = self.store.get_event(self.user, uid, recurrenceid)
1.138 return fragment and Object(fragment)
1.139
1.140 - def get_object(self, user):
1.141 + def get_object(self):
1.142
1.143 """
1.144 Return the stored object to which the current object refers for the
1.145 - given 'user'.
1.146 + current user.
1.147 """
1.148
1.149 - return self._get_object(user, self.uid, self.recurrenceid)
1.150 + return self._get_object(self.uid, self.recurrenceid)
1.151
1.152 - def get_parent_object(self, user):
1.153 + def get_parent_object(self):
1.154
1.155 """
1.156 Return the parent object to which the current object refers for the
1.157 - given 'user'.
1.158 + current user.
1.159 """
1.160
1.161 - return self.recurrenceid and self._get_object(user, self.uid, None) or None
1.162 + return self.recurrenceid and self._get_object(self.uid, None) or None
1.163
1.164 - def have_new_object(self, attendee, obj=None):
1.165 + def have_new_object(self, obj=None):
1.166
1.167 """
1.168 - Return whether the current object is new to the 'attendee' (or if the
1.169 + Return whether the current object is new to the current user (or if the
1.170 given 'obj' is new).
1.171 """
1.172
1.173 - obj = obj or self.get_object(attendee)
1.174 + obj = obj or self.get_object()
1.175
1.176 # If found, compare SEQUENCE and potentially DTSTAMP.
1.177
1.178 @@ -438,16 +443,16 @@
1.179
1.180 return False
1.181
1.182 - def merge_attendance(self, attendees, identity):
1.183 + def merge_attendance(self, attendees):
1.184
1.185 """
1.186 Merge attendance from the current object's 'attendees' into the version
1.187 - stored for the given 'identity'.
1.188 + stored for the current user.
1.189 """
1.190
1.191 - obj = self.get_object(identity)
1.192 + obj = self.get_object()
1.193
1.194 - if not obj or not self.have_new_object(identity, obj=obj):
1.195 + if not obj or not self.have_new_object(obj):
1.196 return False
1.197
1.198 # Get attendee details in a usable form.
1.199 @@ -469,7 +474,7 @@
1.200 event = obj.to_node()
1.201 recurrenceid = format_datetime(obj.get_utc_datetime("RECURRENCE-ID"))
1.202
1.203 - self.store.set_event(identity, self.uid, self.recurrenceid, event)
1.204 + self.store.set_event(self.user, self.uid, self.recurrenceid, event)
1.205
1.206 return True
1.207
1.208 @@ -488,11 +493,4 @@
1.209 sequence = self.obj.get_value("SEQUENCE") or "0"
1.210 self.obj["SEQUENCE"] = [(str(int(sequence) + (increment and 1 or 0)), {})]
1.211
1.212 - def get_tzid(self, identity):
1.213 -
1.214 - "Return the time regime applicable for the given 'identity'."
1.215 -
1.216 - preferences = Preferences(identity)
1.217 - return preferences.get("TZID") or get_default_timezone()
1.218 -
1.219 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imiptools/handlers/person.py Tue Mar 31 19:09:11 2015 +0200
2.2 +++ b/imiptools/handlers/person.py Tue Mar 31 19:12:21 2015 +0200
2.3 @@ -19,7 +19,7 @@
2.4 this program. If not, see <http://www.gnu.org/licenses/>.
2.5 """
2.6
2.7 -from imiptools.data import get_uri
2.8 +from imiptools.data import get_uri, uri_values, values_from_items
2.9 from imiptools.dates import format_datetime
2.10 from imiptools.handlers import Handler
2.11 from imiptools.handlers.common import CommonFreebusy
2.12 @@ -51,47 +51,45 @@
2.13
2.14 if from_organiser:
2.15
2.16 - # Process each attendee separately.
2.17 -
2.18 - for attendee, attendee_attr in attendees.items():
2.19 + # Process for the current user, an attendee.
2.20
2.21 - if not self.have_new_object(attendee):
2.22 - continue
2.23 + if not self.have_new_object() or not self.is_attendee(self.user):
2.24 + return False
2.25
2.26 - # Set the complete event or an additional occurrence.
2.27 + # Set the complete event or an additional occurrence.
2.28
2.29 - self.store.set_event(attendee, self.uid, self.recurrenceid, self.obj.to_node())
2.30 + self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
2.31
2.32 - # Remove additional recurrences if handling a complete event.
2.33 + # Remove additional recurrences if handling a complete event.
2.34
2.35 - if not self.recurrenceid:
2.36 - self.store.remove_recurrences(attendee, self.uid)
2.37 + if not self.recurrenceid:
2.38 + self.store.remove_recurrences(self.user, self.uid)
2.39
2.40 - # Queue any request.
2.41 + # Queue any request.
2.42
2.43 - if queue:
2.44 - self.store.queue_request(attendee, self.uid, self.recurrenceid)
2.45 - elif cancel:
2.46 - self.store.cancel_event(attendee, self.uid, self.recurrenceid)
2.47 + if queue:
2.48 + self.store.queue_request(self.user, self.uid, self.recurrenceid)
2.49 + elif cancel:
2.50 + self.store.cancel_event(self.user, self.uid, self.recurrenceid)
2.51
2.52 - # No return message will occur to update the free/busy
2.53 - # information, so this is done here.
2.54 + # No return message will occur to update the free/busy
2.55 + # information, so this is done here.
2.56
2.57 - freebusy = self.store.get_freebusy(attendee)
2.58 - self.remove_from_freebusy(freebusy)
2.59 + freebusy = self.store.get_freebusy(self.user)
2.60 + self.remove_from_freebusy(freebusy)
2.61
2.62 - self.store.set_freebusy(attendee, freebusy)
2.63 + self.store.set_freebusy(self.user, freebusy)
2.64
2.65 - if self.publisher:
2.66 - self.publisher.set_freebusy(attendee, freebusy)
2.67 + if self.publisher and self.is_sharing():
2.68 + self.publisher.set_freebusy(self.user, freebusy)
2.69
2.70 - self.update_freebusy_from_organiser(attendee, organiser_item)
2.71 + self.update_freebusy_from_organiser(organiser_item)
2.72
2.73 # As organiser, update attendance from valid attendees.
2.74
2.75 else:
2.76 - if self.merge_attendance(attendees, organiser):
2.77 - self.update_freebusy_from_attendees(organiser, attendees)
2.78 + if self.merge_attendance(attendees):
2.79 + self.update_freebusy_from_attendees(attendees)
2.80
2.81 return True
2.82
2.83 @@ -133,12 +131,11 @@
2.84
2.85 dtstart = format_datetime(self.obj.get_utc_datetime("DTSTART"))
2.86 dtend = format_datetime(self.obj.get_utc_datetime("DTEND"))
2.87 - user = get_uri(self.recipient)
2.88
2.89 for sender, sender_attr in senders:
2.90 - stored_freebusy = self.store.get_freebusy_for_other(user, sender)
2.91 + stored_freebusy = self.store.get_freebusy_for_other(self.user, sender)
2.92 replace_overlapping(stored_freebusy, Period(dtstart, dtend), freebusy)
2.93 - self.store.set_freebusy_for_other(user, stored_freebusy, sender)
2.94 + self.store.set_freebusy_for_other(self.user, stored_freebusy, sender)
2.95
2.96 class Event(PersonHandler):
2.97
2.98 @@ -210,8 +207,7 @@
2.99
2.100 # Produce a message if configured to do so.
2.101
2.102 - preferences = Preferences(get_uri(self.recipient))
2.103 - if preferences.get("freebusy_messages") == "notify":
2.104 + if self.is_notifying():
2.105 return self.wrap("A free/busy update has been received.", link=False)
2.106
2.107 def reply(self):
2.108 @@ -222,21 +218,19 @@
2.109
2.110 # Produce a message if configured to do so.
2.111
2.112 - preferences = Preferences(get_uri(self.recipient))
2.113 - if preferences.get("freebusy_messages") == "notify":
2.114 + if self.is_notifying():
2.115 return self.wrap("A reply to a free/busy request has been received.", link=False)
2.116
2.117 def request(self):
2.118
2.119 """
2.120 Respond to a request by preparing a reply containing free/busy
2.121 - information for each indicated attendee.
2.122 + information for the recipient.
2.123 """
2.124
2.125 # Produce a reply if configured to do so.
2.126
2.127 - preferences = Preferences(get_uri(self.recipient))
2.128 - if preferences.get("freebusy_sharing") == "share":
2.129 + if self.is_sharing():
2.130 return CommonFreebusy.request(self)
2.131
2.132 # Handler registry.
3.1 --- a/imiptools/handlers/person_outgoing.py Tue Mar 31 19:09:11 2015 +0200
3.2 +++ b/imiptools/handlers/person_outgoing.py Tue Mar 31 19:12:21 2015 +0200
3.3 @@ -20,28 +20,22 @@
3.4 this program. If not, see <http://www.gnu.org/licenses/>.
3.5 """
3.6
3.7 -from imiptools.data import get_window_end, uri_dict, uri_item, uri_values
3.8 +from imiptools.data import uri_dict, uri_item, uri_values
3.9 from imiptools.handlers import Handler
3.10
3.11 class PersonHandler(Handler):
3.12
3.13 "Handling mechanisms specific to people."
3.14
3.15 - def _get_identity(self, from_organiser=True):
3.16 + def set_identity(self, from_organiser=True):
3.17
3.18 """
3.19 - Get the identity of interest in a usable form for any unprocessed
3.20 - object.
3.21 + Set the current user for the current object. Return attributes for the
3.22 + user if the
3.23 """
3.24
3.25 - identity, attr = item = uri_item(self.obj.get_item(from_organiser and "ORGANIZER" or "ATTENDEE"))
3.26 -
3.27 - # Check for event using UID.
3.28 -
3.29 - if not self.have_new_object(identity):
3.30 - return None
3.31 -
3.32 - return item
3.33 + self.user, attr = uri_item(self.obj.get_item(from_organiser and "ORGANIZER" or "ATTENDEE"))
3.34 + return attr
3.35
3.36 def _record(self, from_organiser=True, update_freebusy=False):
3.37
3.38 @@ -51,71 +45,70 @@
3.39 free/busy information if 'update_freebusy' is set to a true value.
3.40 """
3.41
3.42 - item = self._get_identity(from_organiser)
3.43 - if not item:
3.44 + attr = self.set_identity(from_organiser)
3.45 +
3.46 + # Check for event using UID.
3.47 +
3.48 + if not self.have_new_object():
3.49 return False
3.50
3.51 - identity, attr = item
3.52 -
3.53 # Update the object.
3.54
3.55 if from_organiser:
3.56
3.57 # Set the complete event or an additional occurrence.
3.58
3.59 - self.store.set_event(identity, self.uid, self.recurrenceid, self.obj.to_node())
3.60 + self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
3.61
3.62 # Remove additional recurrences if handling a complete event.
3.63
3.64 if not self.recurrenceid:
3.65 - self.store.remove_recurrences(identity, self.uid)
3.66 + self.store.remove_recurrences(self.user, self.uid)
3.67
3.68 else:
3.69 # Obtain valid attendees, merging their attendance with the stored
3.70 # object.
3.71
3.72 attendees = self.require_attendees(from_organiser)
3.73 - self.merge_attendance(attendees, identity)
3.74 + self.merge_attendance(attendees)
3.75
3.76 # Remove any associated request.
3.77
3.78 - self.store.dequeue_request(identity, self.uid, self.recurrenceid)
3.79 + self.store.dequeue_request(self.user, self.uid, self.recurrenceid)
3.80
3.81 # Update free/busy information.
3.82
3.83 if update_freebusy:
3.84
3.85 - freebusy = self.store.get_freebusy(identity)
3.86 -
3.87 - # Interpretation of periods can depend on the time zone.
3.88 -
3.89 - tzid = self.get_tzid(identity)
3.90 + freebusy = self.store.get_freebusy(self.user)
3.91
3.92 # Use the stored event in case the reply is incomplete, as is seen
3.93 # when Claws sends a REPLY for an object originally employing
3.94 # recurrence information.
3.95
3.96 - obj = self.get_object(identity)
3.97 + obj = self.get_object()
3.98 if not obj:
3.99 return False # although this should not happen
3.100
3.101 # If newer than any old version, discard old details from the
3.102 # free/busy record and check for suitability.
3.103
3.104 - periods = obj.get_periods_for_freebusy(tzid, get_window_end(tzid))
3.105 + # Interpretation of periods can depend on the time zone.
3.106 +
3.107 + periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
3.108
3.109 self.update_freebusy_for_participant(freebusy, periods, attr,
3.110 - from_organiser and self.is_not_attendee(identity, obj))
3.111 + from_organiser and not self.is_attendee(self.user, obj))
3.112
3.113 # Remove either original recurrence or additional recurrence
3.114 # details depending on whether an additional recurrence or a
3.115 # complete event are being handled, respectively.
3.116
3.117 - self.remove_freebusy_for_recurrences(freebusy, self.store.get_recurrences(identity, self.uid))
3.118 - self.store.set_freebusy(identity, freebusy)
3.119 + self.remove_freebusy_for_recurrences(freebusy, self.store.get_recurrences(self.user, self.uid))
3.120 + self.store.set_freebusy(self.user, freebusy)
3.121
3.122 - if self.publisher:
3.123 - self.publisher.set_freebusy(identity, freebusy)
3.124 + if self.publisher and self.is_sharing():
3.125 + self.publisher.set_freebusy(self.user, freebusy)
3.126
3.127 return True
3.128
3.129 @@ -123,17 +116,18 @@
3.130
3.131 "Remove free/busy information for any unprocessed object."
3.132
3.133 - item = self._get_identity(from_organiser)
3.134 - if not item:
3.135 + self.set_identity(from_organiser)
3.136 +
3.137 + # Check for event using UID.
3.138 +
3.139 + if not self.have_new_object():
3.140 return False
3.141
3.142 - identity, attr = item
3.143 -
3.144 # Only cancel the event completely if all attendees are given.
3.145 # NOTE: Need to also check for recurrence identifiers and selective
3.146 # NOTE: cancellations.
3.147
3.148 - obj = self.get_object(identity)
3.149 + obj = self.get_object()
3.150 if not obj:
3.151 return False
3.152
3.153 @@ -142,7 +136,7 @@
3.154 given_attendees = set(uri_values(self.obj.get_values("ATTENDEE")))
3.155
3.156 if given_attendees == all_attendees:
3.157 - self.store.cancel_event(identity, self.uid, self.recurrenceid)
3.158 + self.store.cancel_event(self.user, self.uid, self.recurrenceid)
3.159
3.160 # Otherwise, remove the given attendees and update the event.
3.161
3.162 @@ -159,21 +153,21 @@
3.163
3.164 # Set the complete event if not an additional occurrence.
3.165
3.166 - self.store.set_event(identity, self.uid, self.recurrenceid, obj.to_node())
3.167 + self.store.set_event(self.user, self.uid, self.recurrenceid, obj.to_node())
3.168
3.169 # Remove any associated request.
3.170
3.171 - self.store.dequeue_request(identity, self.uid, self.recurrenceid)
3.172 + self.store.dequeue_request(self.user, self.uid, self.recurrenceid)
3.173
3.174 # Update free/busy information.
3.175
3.176 if update_freebusy:
3.177 - freebusy = self.store.get_freebusy(identity)
3.178 + freebusy = self.store.get_freebusy(self.user)
3.179 self.remove_from_freebusy(freebusy)
3.180 - self.store.set_freebusy(identity, freebusy)
3.181 + self.store.set_freebusy(self.user, freebusy)
3.182
3.183 - if self.publisher:
3.184 - self.publisher.set_freebusy(identity, freebusy)
3.185 + if self.publisher and self.is_sharing():
3.186 + self.publisher.set_freebusy(self.user, freebusy)
3.187
3.188 return True
3.189
4.1 --- a/imiptools/handlers/resource.py Tue Mar 31 19:09:11 2015 +0200
4.2 +++ b/imiptools/handlers/resource.py Tue Mar 31 19:12:21 2015 +0200
4.3 @@ -19,8 +19,7 @@
4.4 this program. If not, see <http://www.gnu.org/licenses/>.
4.5 """
4.6
4.7 -from imiptools.data import get_address, get_uri, get_window_end, to_part
4.8 -from imiptools.dates import get_default_timezone
4.9 +from imiptools.data import get_address, get_uri, to_part
4.10 from imiptools.handlers import Handler
4.11 from imiptools.handlers.common import CommonFreebusy
4.12 from imiptools.period import remove_affected_period
4.13 @@ -47,48 +46,47 @@
4.14
4.15 calendar = []
4.16
4.17 - for attendee, attendee_attr in attendees.items():
4.18 + # Process for the current user, a resource as attendee.
4.19
4.20 - # Check for event using UID.
4.21 + if not self.have_new_object() or not self.is_attendee(self.user):
4.22 + return None
4.23
4.24 - if not self.have_new_object(attendee):
4.25 - continue
4.26 + # Collect response objects produced when handling the request.
4.27
4.28 - # Collect response objects produced when handling the request.
4.29 -
4.30 - response = handle_for_attendee(attendee, attendee_attr)
4.31 - if response:
4.32 - calendar.append(response)
4.33 + response = handle_for_attendee()
4.34 + if response:
4.35 + calendar.append(response)
4.36
4.37 return calendar
4.38
4.39 - def _schedule_for_attendee(self, attendee, attendee_attr):
4.40 + def _schedule_for_attendee(self):
4.41
4.42 """
4.43 - Schedule for the given 'attendee' and accompanying 'attendee_attr' the
4.44 - current object.
4.45 + Schedule the current object for the current user.
4.46 """
4.47
4.48 # Interpretation of periods can depend on the time zone.
4.49
4.50 - tzid = self.get_tzid(attendee)
4.51 + tzid = self.get_tzid()
4.52
4.53 # If newer than any old version, discard old details from the
4.54 # free/busy record and check for suitability.
4.55
4.56 - periods = self.obj.get_periods_for_freebusy(tzid, get_window_end(tzid))
4.57 - freebusy = self.store.get_freebusy(attendee)
4.58 + periods = self.obj.get_periods_for_freebusy(tzid, self.get_window_end())
4.59 + freebusy = self.store.get_freebusy(self.user)
4.60 scheduled = self.can_schedule(freebusy, periods)
4.61
4.62 + attendee_attr = self.obj.get_value_map("ATTENDEE").get(self.user)
4.63 +
4.64 attendee_attr["PARTSTAT"] = scheduled and "ACCEPTED" or "DECLINED"
4.65 if attendee_attr.has_key("RSVP"):
4.66 del attendee_attr["RSVP"]
4.67 - if self.messenger and self.messenger.sender != get_address(attendee):
4.68 + if self.messenger and self.messenger.sender != get_address(self.user):
4.69 attendee_attr["SENT-BY"] = get_uri(self.messenger.sender)
4.70
4.71 # Make a version of the request with just this attendee.
4.72
4.73 - self.obj["ATTENDEE"] = [(attendee, attendee_attr)]
4.74 + self.obj["ATTENDEE"] = [(self.user, attendee_attr)]
4.75
4.76 # Update the DTSTAMP.
4.77
4.78 @@ -97,12 +95,12 @@
4.79 # Set the complete event or an additional occurrence.
4.80
4.81 event = self.obj.to_node()
4.82 - self.store.set_event(attendee, self.uid, self.recurrenceid, event)
4.83 + self.store.set_event(self.user, self.uid, self.recurrenceid, event)
4.84
4.85 # Remove additional recurrences if handling a complete event.
4.86
4.87 if not self.recurrenceid:
4.88 - self.store.remove_recurrences(attendee, self.uid)
4.89 + self.store.remove_recurrences(self.user, self.uid)
4.90
4.91 # Only update free/busy details if the event is scheduled.
4.92
4.93 @@ -116,29 +114,28 @@
4.94 # complete event are being handled, respectively.
4.95
4.96 self.remove_freebusy_for_recurrences(freebusy)
4.97 - self.store.set_freebusy(attendee, freebusy)
4.98 + self.store.set_freebusy(self.user, freebusy)
4.99
4.100 - if self.publisher:
4.101 - self.publisher.set_freebusy(attendee, freebusy)
4.102 + if self.publisher and self.is_sharing():
4.103 + self.publisher.set_freebusy(self.user, freebusy)
4.104
4.105 return event
4.106
4.107 - def _cancel_for_attendee(self, attendee, attendee_attr):
4.108 + def _cancel_for_attendee(self):
4.109
4.110 """
4.111 - Cancel for the given 'attendee' and accompanying 'attendee_attr' their
4.112 - attendance of the event described by the current object.
4.113 + Cancel for the current user their attendance of the event described by
4.114 + the current object.
4.115 """
4.116
4.117 - self.store.cancel_event(attendee, self.uid, self.recurrenceid)
4.118 -
4.119 - freebusy = self.store.get_freebusy(attendee)
4.120 - self.remove_from_freebusy(freebusy)
4.121 + self.store.cancel_event(self.user, self.uid, self.recurrenceid)
4.122
4.123 - self.store.set_freebusy(attendee, freebusy)
4.124 + freebusy = self.store.get_freebusy(self.user)
4.125 + self.remove_from_freebusy(freebusy)
4.126 + self.store.set_freebusy(self.user, freebusy)
4.127
4.128 - if self.publisher:
4.129 - self.publisher.set_freebusy(attendee, freebusy)
4.130 + if self.publisher and self.is_sharing():
4.131 + self.publisher.set_freebusy(self.user, freebusy)
4.132
4.133 return None
4.134
4.135 @@ -186,7 +183,7 @@
4.136
4.137 """
4.138 Respond to a request by preparing a reply containing accept/decline
4.139 - information for each indicated attendee.
4.140 + information for the recipient.
4.141
4.142 No support for countering requests is implemented.
4.143 """
5.1 --- a/imipweb/handler.py Tue Mar 31 19:09:11 2015 +0200
5.2 +++ b/imipweb/handler.py Tue Mar 31 19:12:21 2015 +0200
5.3 @@ -26,7 +26,7 @@
5.4 from imiptools.handlers import Handler
5.5 from imiptools.period import update_freebusy
5.6
5.7 -class ManagerHandler(Client, Handler):
5.8 +class ManagerHandler(Handler):
5.9
5.10 """
5.11 A content handler for use by the manager, as opposed to operating within the
5.12 @@ -35,7 +35,7 @@
5.13
5.14 def __init__(self, obj, user, messenger):
5.15 Handler.__init__(self, messenger=messenger)
5.16 - Client.__init__(self, user)
5.17 + Client.__init__(self, user) # this redefines the Handler initialisation
5.18
5.19 self.set_object(obj)
5.20
6.1 --- a/imipweb/resource.py Tue Mar 31 19:09:11 2015 +0200
6.2 +++ b/imipweb/resource.py Tue Mar 31 19:12:21 2015 +0200
6.3 @@ -205,13 +205,19 @@
6.4 remove_affected_period(freebusy, uid, recurrenceid)
6.5
6.6 self.store.set_freebusy(self.user, freebusy)
6.7 -
6.8 - if self.publisher:
6.9 - self.publisher.set_freebusy(self.user, freebusy)
6.10 + self.publish_freebusy(freebusy)
6.11
6.12 def remove_from_freebusy(self, uid, recurrenceid=None):
6.13 freebusy = self.store.get_freebusy(self.user)
6.14 remove_period(freebusy, uid, recurrenceid)
6.15 self.store.set_freebusy(self.user, freebusy)
6.16 + self.publish_freebusy(freebusy)
6.17 +
6.18 + def publish_freebusy(self, freebusy):
6.19 +
6.20 + "Publish the details if configured to share them."
6.21 +
6.22 + if self.publisher and self.is_sharing():
6.23 + self.publisher.set_freebusy(self.user, freebusy)
6.24
6.25 # vim: tabstop=4 expandtab shiftwidth=4