1.1 --- a/imiptools/period.py Fri Mar 27 18:23:41 2015 +0100
1.2 +++ b/imiptools/period.py Fri Mar 27 20:02:10 2015 +0100
1.3 @@ -259,7 +259,47 @@
1.4
1.5 return scale
1.6
1.7 -POINT, REPEATED = 0, 1
1.8 +class Point:
1.9 +
1.10 + "A qualified point in time."
1.11 +
1.12 + PRINCIPAL, REPEATED = 0, 1
1.13 +
1.14 + def __init__(self, point, indicator=None):
1.15 + self.point = point
1.16 + self.indicator = indicator or self.PRINCIPAL
1.17 +
1.18 + def __hash__(self):
1.19 + return hash((self.point, self.indicator))
1.20 +
1.21 + def __cmp__(self, other):
1.22 + if isinstance(other, Point):
1.23 + return cmp((self.point, self.indicator), (other.point, other.indicator))
1.24 + elif isinstance(other, datetime):
1.25 + return cmp(self.point, other)
1.26 + else:
1.27 + return 1
1.28 +
1.29 + def __eq__(self, other):
1.30 + return self.__cmp__(other) == 0
1.31 +
1.32 + def __ne__(self, other):
1.33 + return not self == other
1.34 +
1.35 + def __lt__(self, other):
1.36 + return self.__cmp__(other) < 0
1.37 +
1.38 + def __le__(self, other):
1.39 + return self.__cmp__(other) <= 0
1.40 +
1.41 + def __gt__(self, other):
1.42 + return not self <= other
1.43 +
1.44 + def __ge__(self, other):
1.45 + return not self < other
1.46 +
1.47 + def __repr__(self):
1.48 + return "Point(%r, Point.%s)" % (self.point, self.indicator and "REPEATED" or "PRINCIPAL")
1.49
1.50 def get_slots(scale):
1.51
1.52 @@ -270,9 +310,10 @@
1.53 the slot, together with a list of parallel event tuples, each tuple
1.54 containing the original details of an event.
1.55
1.56 - Each point in time is described as a tuple containing the actual time point
1.57 - plus an indicator (0 as POINT or 1 as REPEATED), with REPEATED being used to
1.58 - indicate repeated points used for the end of "instant" events.
1.59 + Each point in time is described as a Point representing the actual point in
1.60 + time together with an indicator of the nature of the point in time (as a
1.61 + principal point in a time scale or as a repeated point used to terminate
1.62 + events occurring for an instant in time).
1.63 """
1.64
1.65 slots = []
1.66 @@ -309,7 +350,7 @@
1.67
1.68 # Add an entry for the time point before "instants".
1.69
1.70 - slots.append(((point, POINT), active[:]))
1.71 + slots.append((Point(point), active[:]))
1.72
1.73 # Discard events ending at the same time as they began.
1.74
1.75 @@ -325,7 +366,7 @@
1.76
1.77 # Add another entry for the time point after "instants".
1.78
1.79 - slots.append(((point, REPEATED), active[:]))
1.80 + slots.append((Point(point, Point.REPEATED), active[:]))
1.81
1.82 return slots
1.83
1.84 @@ -341,9 +382,9 @@
1.85 current_date = None
1.86 previously_active = []
1.87
1.88 - for (point, indicator), active in slots:
1.89 - start_of_day = get_start_of_day(point, tzid)
1.90 - this_date = point.date()
1.91 + for point, active in slots:
1.92 + start_of_day = get_start_of_day(point.point, tzid)
1.93 + this_date = point.point.date()
1.94
1.95 # For each new day, add a slot for the start of the day where periods
1.96 # are active and where no such slot already exists.
1.97 @@ -355,15 +396,15 @@
1.98 if current_date:
1.99 current_date += timedelta(1)
1.100 while current_date < this_date:
1.101 - new_slots.append(((get_start_of_day(current_date, tzid), POINT), previously_active))
1.102 + new_slots.append((Point(get_start_of_day(current_date, tzid)), previously_active))
1.103 current_date += timedelta(1)
1.104 else:
1.105 current_date = this_date
1.106
1.107 # Add any continuing periods.
1.108
1.109 - if point != start_of_day:
1.110 - new_slots.append(((start_of_day, POINT), previously_active))
1.111 + if point.point != start_of_day:
1.112 + new_slots.append((Point(start_of_day), previously_active))
1.113
1.114 # Add the currently active periods at this point in time.
1.115
1.116 @@ -400,11 +441,11 @@
1.117
1.118 d = {}
1.119
1.120 - for (point, indicator), value in slots:
1.121 - day = point.date()
1.122 + for point, value in slots:
1.123 + day = point.point.date()
1.124 if not d.has_key(day):
1.125 d[day] = []
1.126 - d[day].append(((point, indicator), value))
1.127 + d[day].append((point, value))
1.128
1.129 return d
1.130
1.131 @@ -420,7 +461,7 @@
1.132 if last_day:
1.133 empty_day = last_day + timedelta(1)
1.134 while empty_day < day:
1.135 - days[empty_day] = [((get_start_of_day(empty_day, tzid), POINT), None)]
1.136 + days[empty_day] = [(Point(get_start_of_day(empty_day, tzid)), None)]
1.137 empty_day += timedelta(1)
1.138 last_day = day
1.139
1.140 @@ -428,7 +469,7 @@
1.141
1.142 "Inspect the given 'slots', returning a mapping of event uids to spans."
1.143
1.144 - all_point_details = [point_details for point_details, active in slots]
1.145 + points = [point for point, active in slots]
1.146 spans = {}
1.147
1.148 for _point, active in slots:
1.149 @@ -436,8 +477,8 @@
1.150 if t and len(t) >= 2:
1.151 start, end, uid, recurrenceid, summary, organiser, key = get_freebusy_details(t)
1.152
1.153 - start_slot = bisect_left(all_point_details, (start,))
1.154 - end_slot = bisect_left(all_point_details, (end,))
1.155 + start_slot = bisect_left(points, start)
1.156 + end_slot = bisect_left(points, end)
1.157 spans[key] = end_slot - start_slot
1.158
1.159 return spans