1.1 --- a/imiptools/period.py Fri Mar 27 17:28:50 2015 +0100
1.2 +++ b/imiptools/period.py Fri Mar 27 17:35:05 2015 +0100
1.3 @@ -259,14 +259,20 @@
1.4
1.5 return scale
1.6
1.7 +POINT, REPEATED = 0, 1
1.8 +
1.9 def get_slots(scale):
1.10
1.11 """
1.12 Return an ordered list of time slots from the given 'scale'.
1.13
1.14 - Each slot is a tuple containing a point in time for the start of the slot,
1.15 - together with a list of parallel event tuples, each tuple containing the
1.16 - original details of an event.
1.17 + Each slot is a tuple containing details of a point in time for the start of
1.18 + the slot, together with a list of parallel event tuples, each tuple
1.19 + containing the original details of an event.
1.20 +
1.21 + Each point in time is described as a tuple containing the actual time point
1.22 + plus an indicator (0 as POINT or 1 as REPEATED), with REPEATED being used to
1.23 + indicate repeated points used for the end of "instant" events.
1.24 """
1.25
1.26 slots = []
1.27 @@ -301,7 +307,9 @@
1.28 while active and active[-1] is None:
1.29 active.pop()
1.30
1.31 - slots.append((point, active[:]))
1.32 + # Add an entry for the time point before "instants".
1.33 +
1.34 + slots.append(((point, POINT), active[:]))
1.35
1.36 # Discard events ending at the same time as they began.
1.37
1.38 @@ -315,9 +323,9 @@
1.39 while active and active[-1] is None:
1.40 active.pop()
1.41
1.42 - # Add another entry for the time point without "instants".
1.43 + # Add another entry for the time point after "instants".
1.44
1.45 - slots.append((point, active[:]))
1.46 + slots.append(((point, REPEATED), active[:]))
1.47
1.48 return slots
1.49
1.50 @@ -333,7 +341,7 @@
1.51 current_date = None
1.52 previously_active = []
1.53
1.54 - for point, active in slots:
1.55 + for (point, indicator), active in slots:
1.56 start_of_day = get_start_of_day(point, tzid)
1.57 this_date = point.date()
1.58
1.59 @@ -347,7 +355,7 @@
1.60 if current_date:
1.61 current_date += timedelta(1)
1.62 while current_date < this_date:
1.63 - new_slots.append((get_start_of_day(current_date, tzid), previously_active))
1.64 + new_slots.append(((get_start_of_day(current_date, tzid), POINT), previously_active))
1.65 current_date += timedelta(1)
1.66 else:
1.67 current_date = this_date
1.68 @@ -355,7 +363,7 @@
1.69 # Add any continuing periods.
1.70
1.71 if point != start_of_day:
1.72 - new_slots.append((start_of_day, previously_active))
1.73 + new_slots.append(((start_of_day, POINT), previously_active))
1.74
1.75 # Add the currently active periods at this point in time.
1.76
1.77 @@ -375,7 +383,7 @@
1.78 new_slots = []
1.79
1.80 for point in points:
1.81 - i = bisect_left(slots, (point,))
1.82 + i = bisect_left(slots, (point,)) # slots is [(point, active)...]
1.83 if i < len(slots) and slots[i][0] == point:
1.84 continue
1.85
1.86 @@ -392,11 +400,11 @@
1.87
1.88 d = {}
1.89
1.90 - for point, value in slots:
1.91 + for (point, indicator), value in slots:
1.92 day = point.date()
1.93 if not d.has_key(day):
1.94 d[day] = []
1.95 - d[day].append((point, value))
1.96 + d[day].append(((point, indicator), value))
1.97
1.98 return d
1.99
1.100 @@ -412,7 +420,7 @@
1.101 if last_day:
1.102 empty_day = last_day + timedelta(1)
1.103 while empty_day < day:
1.104 - days[empty_day] = [(get_start_of_day(empty_day, tzid), None)]
1.105 + days[empty_day] = [((get_start_of_day(empty_day, tzid), POINT), None)]
1.106 empty_day += timedelta(1)
1.107 last_day = day
1.108
1.109 @@ -420,7 +428,7 @@
1.110
1.111 "Inspect the given 'slots', returning a mapping of event uids to spans."
1.112
1.113 - points = [point for point, active in slots]
1.114 + all_point_details = [point_details for point_details, active in slots]
1.115 spans = {}
1.116
1.117 for _point, active in slots:
1.118 @@ -428,8 +436,8 @@
1.119 if t and len(t) >= 2:
1.120 start, end, uid, recurrenceid, summary, organiser, key = get_freebusy_details(t)
1.121
1.122 - start_slot = bisect_left(points, (start,))
1.123 - end_slot = bisect_left(points, (end,))
1.124 + start_slot = bisect_left(all_point_details, (start,))
1.125 + end_slot = bisect_left(all_point_details, (end,))
1.126 spans[key] = end_slot - start_slot
1.127
1.128 return spans
2.1 --- a/imipweb/calendar.py Fri Mar 27 17:28:50 2015 +0100
2.2 +++ b/imipweb/calendar.py Fri Mar 27 17:35:05 2015 +0100
2.3 @@ -27,7 +27,8 @@
2.4 to_timezone
2.5 from imiptools.period import add_day_start_points, add_empty_days, add_slots, \
2.6 convert_periods, get_freebusy_details, \
2.7 - get_scale, get_slots, get_spans, partition_by_day
2.8 + get_scale, get_slots, get_spans, partition_by_day, \
2.9 + POINT
2.10 from imipweb.resource import Resource
2.11
2.12 class CalendarPage(Resource):
2.13 @@ -334,7 +335,7 @@
2.14 # Record the slots and all time points employed.
2.15
2.16 groups.append(slots)
2.17 - all_points.update([point for point, active in slots])
2.18 + all_points.update([point_details for point_details, active in slots])
2.19
2.20 # Partition the groups into days.
2.21
2.22 @@ -370,18 +371,15 @@
2.23
2.24 last = None
2.25
2.26 - for point, active in day_slots:
2.27 + for point_details, active in day_slots:
2.28 + point, indicator = point_details
2.29 columns = max(columns, len(active))
2.30 -
2.31 - # Qualify points in the day with an extra indicator to
2.32 - # handle repeated time points due to instant events.
2.33 -
2.34 - day_points[(point, last == point and 1 or 0)] = active
2.35 + day_points[point_details] = active
2.36
2.37 if last:
2.38 intervals.append((last, point))
2.39
2.40 - last = point
2.41 + last = point_details
2.42
2.43 if last:
2.44 intervals.append((last, None))
2.45 @@ -548,10 +546,7 @@
2.46
2.47 last = None
2.48
2.49 - for point, endpoint in intervals:
2.50 - indicator = point == last and 1 or 0
2.51 - last = point
2.52 -
2.53 + for (point, indicator), endpoint in intervals:
2.54 continuation = point == get_start_of_day(point, tzid)
2.55
2.56 # Some rows contain no period details and are marked as such.
2.57 @@ -577,7 +572,7 @@
2.58
2.59 page.tr(class_=css)
2.60 page.th(class_="timeslot")
2.61 - if indicator == 0:
2.62 + if indicator == POINT:
2.63 self._time_point(point, endpoint)
2.64 page.th.close()
2.65