# HG changeset patch # User Paul Boddie # Date 1495570505 -7200 # Node ID 13b96d1200609348732ee17b322546b1d661d14d # Parent 4fc327b8d31cbd87ac1306d036e3457242db55bf Extended free/busy removal operations to consider attendee details, thus simplifying and optimising removal-from-quota operations. diff -r 4fc327b8d31c -r 13b96d120060 imiptools/client.py --- a/imiptools/client.py Tue May 23 16:34:09 2017 +0200 +++ b/imiptools/client.py Tue May 23 22:15:05 2017 +0200 @@ -1036,13 +1036,16 @@ return self.obj.get_recurrence_start_point(recurrenceid, self.get_tzid()) - def remove_from_freebusy(self, freebusy): - - "Remove this event from the given 'freebusy' collection." + def remove_from_freebusy(self, freebusy, participant=None): - removed = freebusy.remove_event_periods(self.uid, self.recurrenceid) + """ + Remove this event from the given 'freebusy' collection. If 'participant' + is specified, only remove this event if the participant is attending. + """ + + removed = freebusy.remove_event_periods(self.uid, self.recurrenceid, participant) if not removed and self.recurrenceid: - return freebusy.remove_affected_period(self.uid, self.get_recurrence_start_point(self.recurrenceid)) + return freebusy.remove_affected_period(self.uid, self.get_recurrence_start_point(self.recurrenceid), participant) else: return removed diff -r 4fc327b8d31c -r 13b96d120060 imiptools/freebusy.py --- a/imiptools/freebusy.py Tue May 23 16:34:09 2017 +0200 +++ b/imiptools/freebusy.py Tue May 23 22:15:05 2017 +0200 @@ -21,6 +21,7 @@ from bisect import bisect_left, bisect_right from imiptools.dates import format_datetime +from imiptools.period import get_overlapping, Period, PeriodBase from imiptools.sql import DatabaseOperations def from_string(s, encoding): @@ -35,8 +36,6 @@ else: return s -from imiptools.period import get_overlapping, Period, PeriodBase - class FreeBusyPeriod(PeriodBase): "A free/busy record abstraction." @@ -548,13 +547,16 @@ if i < len(self.periods) and self.periods[i] == period: del self.periods[i] - def remove_event_periods(self, uid, recurrenceid=None): + def remove_event_periods(self, uid, recurrenceid=None, participant=None): """ Remove from the collection all periods associated with 'uid' and 'recurrenceid' (which if omitted causes the "parent" object's periods to be referenced). + If 'participant' is specified, only remove periods for which the + participant is given as attending. + Return the removed periods. """ @@ -564,7 +566,10 @@ i = 0 while i < len(self.periods): fb = self.periods[i] - if fb.uid == uid and fb.recurrenceid == recurrenceid: + + if fb.uid == uid and fb.recurrenceid == recurrenceid and \ + (not participant or participant == fb.attendee): + removed.append(self.periods[i]) del self.periods[i] else: @@ -605,7 +610,7 @@ return removed - def remove_affected_period(self, uid, start): + def remove_affected_period(self, uid, start, participant=None): """ Remove from the collection the period associated with 'uid' that @@ -614,6 +619,9 @@ is used to provide an alternative time period whilst also acting as a reference to the originally-defined occurrence. + If 'participant' is specified, only remove periods for which the + participant is given as attending. + Return any removed period in a list. """ @@ -634,7 +642,9 @@ # If the period belongs to the parent object, remove it and return. - if not fb.recurrenceid and uid == fb.uid: + if not fb.recurrenceid and uid == fb.uid and \ + (not participant or participant == fb.attendee): + removed.append(self.periods[found]) del self.periods[found] break @@ -797,22 +807,32 @@ self.cursor.execute(query, values) - def remove_event_periods(self, uid, recurrenceid=None): + def remove_event_periods(self, uid, recurrenceid=None, participant=None): """ Remove from the collection all periods associated with 'uid' and 'recurrenceid' (which if omitted causes the "parent" object's periods to be referenced). + If 'participant' is specified, only remove periods for which the + participant is given as attending. + Return the removed periods. """ self._check_mutable() + columns, values = ["object_uid"], [uid] + if recurrenceid: - columns, values = ["object_uid", "object_recurrenceid"], [uid, recurrenceid] + columns.append("object_recurrenceid") + values.append(recurrenceid) else: - columns, values = ["object_uid", "object_recurrenceid is null"], [uid] + columns.append("object_recurrenceid is null") + + if participant: + columns.append("attendee") + values.append(participant) query, _values = self.get_query( "select %(columns)s from %(table)s :condition" % { @@ -877,7 +897,7 @@ return map(lambda t: self.make_period(t), removed) - def remove_affected_period(self, uid, start): + def remove_affected_period(self, uid, start, participant=None): """ Remove from the collection the period associated with 'uid' that @@ -886,6 +906,9 @@ is used to provide an alternative time period whilst also acting as a reference to the originally-defined occurrence. + If 'participant' is specified, only remove periods for which the + participant is given as attending. + Return any removed period in a list. """ @@ -895,6 +918,10 @@ columns, values = ["object_uid", "start", "object_recurrenceid is null"], [uid, start] + if participant: + columns.append("attendee") + values.append(participant) + query, _values = self.get_query( "select %(columns)s from %(table)s :condition" % { "columns" : self.columnlist(self.period_columns), diff -r 4fc327b8d31c -r 13b96d120060 imiptools/handlers/scheduling/quota.py --- a/imiptools/handlers/scheduling/quota.py Tue May 23 16:34:09 2017 +0200 +++ b/imiptools/handlers/scheduling/quota.py Tue May 23 22:15:05 2017 +0200 @@ -260,10 +260,7 @@ # Remove only the entries associated with this recipient. - removed = handler.remove_from_freebusy(freebusy) - for p in removed: - if p.attendee != participant: - freebusy.insert_period(p) + handler.remove_from_freebusy(freebusy, participant) # Update free/busy provider information if the event may recur indefinitely.