# HG changeset patch # User Paul Boddie # Date 1508189879 -7200 # Node ID ec5023f5529982f1caa9d3951bbf9470729591ff # Parent 867279f45f02ba7c3a6317b8dfa2777c4edc677e# Parent fe50d2b3760a4a707934cf23e0dae85825c2c28b Merged changes from the default branch. diff -r 867279f45f02 -r ec5023f55299 imiptools/client.py --- a/imiptools/client.py Mon Oct 16 22:10:22 2017 +0200 +++ b/imiptools/client.py Mon Oct 16 23:37:59 2017 +0200 @@ -22,11 +22,13 @@ from collections import OrderedDict from datetime import datetime, timedelta from imiptools.config import settings -from imiptools.data import check_delegation, get_address, get_uri, \ +from imiptools.data import check_delegation, get_address, \ get_recurrence_periods, \ + get_sender_identities, get_uri, \ get_window_end, is_new_object, make_freebusy, \ - make_uid, new_object, to_part, uri_dict, uri_item, \ - uri_items, uri_parts, uri_values + make_uid, new_object, to_part, \ + update_attendees_with_delegates, \ + uri_dict, uri_item, uri_items, uri_parts, uri_values from imiptools.dates import check_permitted_values, format_datetime, \ get_datetime, get_default_timezone, \ get_duration, get_time, get_timestamp, \ @@ -585,12 +587,21 @@ # Search for the sender of the message or the calendar system address. - senders = self.senders or self.messenger and [self.messenger.sender] or [] + senders = set(uri_values(self.senders or self.messenger and [self.messenger.sender] or [])) + + if senders: + + # Obtain a mapping from sender URI to attendee URI, where the sender + # is taken from the SENT-BY attribute if present, or from the + # attendee value otherwise. - for attendee, attendee_attr in uri_items(self.obj.get_items("ATTENDEE") or []): - if get_address(attendee) in senders or \ - get_address(attendee_attr.get("SENT-BY")) in senders: - return get_uri(attendee) + sent_by = get_sender_identities(uri_dict(self.obj.get_value_map("ATTENDEE"))) + + # Obtain the attendee for the first sender matching the SENT-BY or + # attendee value. + + for sender in senders.intersection(sent_by.keys()): + return sent_by[sender][0] return None @@ -634,32 +645,21 @@ # Get attendee details in a usable form. - attendee_map = uri_dict(obj.get_value_map("ATTENDEE")) + stored_attendees = uri_dict(obj.get_value_map("ATTENDEE")) for attendee, attendee_attr in attendees.items(): # Update attendance in the loaded object for any recognised # attendees. - if attendee_map.has_key(attendee): - attendee_map[attendee] = attendee_attr - - # Check for delegated attendees. - - for attendee, attendee_attr in attendees.items(): + if stored_attendees.has_key(attendee): + stored_attendees[attendee] = attendee_attr - # Identify delegates and check the delegation using the updated - # attendee information. - - if not attendee_map.has_key(attendee) and \ - attendee_attr.has_key("DELEGATED-FROM") and \ - check_delegation(attendee_map, attendee, attendee_attr): - - attendee_map[attendee] = attendee_attr + update_attendees_with_delegates(stored_attendees, attendees) # Set the new details and store the object. - obj["ATTENDEE"] = attendee_map.items() + obj["ATTENDEE"] = stored_attendees.items() # Set a specific recurrence or the complete event if not an additional # occurrence. diff -r 867279f45f02 -r ec5023f55299 imiptools/data.py --- a/imiptools/data.py Mon Oct 16 22:10:22 2017 +0200 +++ b/imiptools/data.py Mon Oct 16 23:37:59 2017 +0200 @@ -1319,7 +1319,8 @@ """ Return a mapping from actual senders to the identities for which they have provided data, extracting this information from the given - 'mapping'. + 'mapping'. The SENT-BY attribute provides sender information in preference + to the property values given as the mapping keys. """ senders = {} @@ -1348,4 +1349,24 @@ return to_timezone(start or datetime.now(), tzid) + timedelta(days) +def update_attendees_with_delegates(stored_attendees, attendees): + + """ + Update the 'stored_attendees' mapping with delegate information from the + given 'attendees' mapping. + """ + + # Check for delegated attendees. + + for attendee, attendee_attr in attendees.items(): + + # Identify delegates and check the delegation using the updated + # attendee information. + + if not stored_attendees.has_key(attendee) and \ + attendee_attr.has_key("DELEGATED-FROM") and \ + check_delegation(stored_attendees, attendee, attendee_attr): + + stored_attendees[attendee] = attendee_attr + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 867279f45f02 -r ec5023f55299 imiptools/handlers/__init__.py --- a/imiptools/handlers/__init__.py Mon Oct 16 22:10:22 2017 +0200 +++ b/imiptools/handlers/__init__.py Mon Oct 16 23:37:59 2017 +0200 @@ -145,7 +145,13 @@ # Return the true identities. - return reduce(lambda a, b: a + b, [identities[get_uri(address)] for address in valid], []) + attendees = [] + for address in valid: + attendees += identities[get_uri(address)] + return attendees + + # Rely on the mapping keys being accessible as a sequence. + else: return mapping @@ -159,6 +165,9 @@ if self.recipient: addresses = set(map(get_address, mapping)) return map(get_uri, addresses.intersection([self.recipient])) + + # Rely on the mapping keys being accessible as a sequence. + else: return mapping