# HG changeset patch # User Paul Boddie # Date 1421948466 -3600 # Node ID 6a4c7cc21fbb5ec6b65dafa90a9e2c6a0e372794 # Parent bb9494547de1d617bf1bdc10542e1e9d613d5020 Made a separate function for testing if objects are new, making use of PARTSTAT for objects prepared by apparently non-compliant calendar clients. diff -r bb9494547de1 -r 6a4c7cc21fbb imiptools/content.py --- a/imiptools/content.py Thu Jan 22 17:50:54 2015 +0100 +++ b/imiptools/content.py Thu Jan 22 18:41:06 2015 +0100 @@ -107,6 +107,28 @@ def uri_items(items): return [(get_uri(value), attr) for value, attr in items] +def is_new_object(old_sequence, new_sequence, old_dtstamp, new_dtstamp, partstat_set): + + """ + Return for the given 'old_sequence' and 'new_sequence', 'old_dtstamp' and + 'new_dtstamp', and the 'partstat_set' indication, whether the object + providing the new information is really newer than the object providing the + old information. + """ + + have_sequence = old_sequence is not None and new_sequence is not None + is_same_sequence = have_sequence and int(new_sequence) == int(old_sequence) + + have_dtstamp = old_dtstamp and new_dtstamp + is_old_dtstamp = have_dtstamp and new_dtstamp < old_dtstamp or old_dtstamp and not new_dtstamp + + is_old_sequence = have_sequence and ( + int(new_sequence) < int(old_sequence) or + is_same_sequence and is_old_dtstamp + ) + + return is_same_sequence and partstat_set or not is_old_sequence + # NOTE: Need to expose the 100 day window for recurring events in the # NOTE: configuration. @@ -426,19 +448,22 @@ sequence = get_value(obj, "SEQUENCE") dtstamp = get_value(obj, "DTSTAMP") + # NOTE: Some clients like Claws Mail erase time information from DTSTAMP + # NOTE: and make it invalid. Thus, attendance information may also be + # NOTE: checked. + + _attendee, old_attr = get_item(obj, "ATTENDEE") + _attendee, new_attr = self.get_item("ATTENDEE") + old_partstat = old_attr.get("PARTSTAT") + new_partstat = new_attr.get("PARTSTAT") + + partstat_set = old_partstat == "NEEDS-ACTION" and new_partstat and \ + new_partstat != old_partstat + # If the request refers to an older version of the object, ignore # it. - old_dtstamp = self.dtstamp < dtstamp - - have_sequence = sequence is not None and self.sequence is not None - - if have_sequence and ( - int(self.sequence) < int(sequence) or - int(self.sequence) == int(sequence) and old_dtstamp - ) or not have_sequence and old_dtstamp: - - return False + return is_new_object(sequence, self.sequence, dtstamp, self.dtstamp, partstat_set) return True