1 #!/usr/bin/env python 2 3 from bisect import bisect_left, insort_left 4 5 # Time management. 6 7 def have_conflict(freebusy, periods, get_conflicts=False): 8 9 """ 10 Return whether any period in 'freebusy' overlaps with the given 'periods', 11 returning a collection of such overlapping periods if 'get_conflicts' is 12 set to a true value. 13 """ 14 15 conflicts = [] 16 for start, end in periods: 17 overlapping = period_overlaps(freebusy, (start, end), get_conflicts) 18 if overlapping: 19 if get_conflicts: 20 conflicts += overlapping 21 else: 22 return True 23 24 if get_conflicts: 25 return conflicts 26 else: 27 return False 28 29 def insert_period(freebusy, period): 30 insort_left(freebusy, period) 31 32 def remove_period(freebusy, uid): 33 i = 0 34 while i < len(freebusy): 35 t = freebusy[i] 36 if len(t) >= 3 and t[2] == uid: 37 del freebusy[i] 38 else: 39 i += 1 40 41 def period_overlaps(freebusy, period, get_periods=False): 42 43 """ 44 Return whether any period in 'freebusy' overlaps with the given 'period', 45 returning a collection of overlapping periods if 'get_periods' is set to a 46 true value. 47 """ 48 49 dtstart, dtend = period[:2] 50 found = bisect_left(freebusy, (dtstart, dtend, None, None)) 51 52 overlapping = [] 53 54 # Find earlier overlapping periods. 55 56 i = found 57 58 while i > 0 and freebusy[i - 1][1] > dtstart: 59 if get_periods: 60 overlapping.insert(0, freebusy[i - 1]) 61 else: 62 return True 63 i -= 1 64 65 # Find later overlapping periods. 66 67 i = found 68 69 while i < len(freebusy) and (dtend is None or freebusy[i][0] < dtend): 70 if get_periods: 71 overlapping.append(freebusy[i]) 72 else: 73 return True 74 i += 1 75 76 if get_periods: 77 return overlapping 78 else: 79 return False 80 81 # vim: tabstop=4 expandtab shiftwidth=4