1.1 --- a/imiptools/data.py Sun May 17 21:41:27 2015 +0200
1.2 +++ b/imiptools/data.py Sun May 17 22:35:39 2015 +0200
1.3 @@ -126,10 +126,6 @@
1.4 def get_periods(self, tzid, end):
1.5 return get_periods(self, tzid, end)
1.6
1.7 - def get_periods_for_freebusy(self, tzid, end):
1.8 - periods = self.get_periods(tzid, end)
1.9 - return get_periods_for_freebusy(self, periods, tzid)
1.10 -
1.11 def get_tzid(self):
1.12 dtstart, dtstart_attr = self.get_datetime_item("DTSTART")
1.13 dtend, dtend_attr = self.get_datetime_item("DTEND")
1.14 @@ -478,25 +474,4 @@
1.15
1.16 return periods
1.17
1.18 -def get_periods_for_freebusy(obj, periods, tzid):
1.19 -
1.20 - """
1.21 - Get free/busy-compliant periods employed by 'obj' from the given 'periods',
1.22 - using the indicated 'tzid' to convert dates to datetimes.
1.23 - """
1.24 -
1.25 - tzid = obj.get_tzid() or tzid
1.26 -
1.27 - l = []
1.28 -
1.29 - for p in periods:
1.30 - start, end = get_freebusy_period(p.get_start(), p.get_end(), tzid)
1.31 -
1.32 - # Create a new period for free/busy purposes with the converted
1.33 - # datetime information.
1.34 -
1.35 - l.append(p.__class__(start, end, *p.as_tuple()[2:]))
1.36 -
1.37 - return l
1.38 -
1.39 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imiptools/handlers/__init__.py Sun May 17 21:41:27 2015 +0200
2.2 +++ b/imiptools/handlers/__init__.py Sun May 17 22:35:39 2015 +0200
2.3 @@ -223,7 +223,7 @@
2.4
2.5 # Obtain the affected periods.
2.6
2.7 - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
2.8 + periods = obj.get_periods(self.get_tzid(), self.get_window_end())
2.9
2.10 # Record in the free/busy details unless a non-participating attendee.
2.11 # Use any attendee information for an organiser, not the organiser's own
3.1 --- a/imiptools/handlers/person_outgoing.py Sun May 17 21:41:27 2015 +0200
3.2 +++ b/imiptools/handlers/person_outgoing.py Sun May 17 22:35:39 2015 +0200
3.3 @@ -93,7 +93,7 @@
3.4
3.5 # Interpretation of periods can depend on the time zone.
3.6
3.7 - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
3.8 + periods = obj.get_periods(self.get_tzid(), self.get_window_end())
3.9
3.10 # Obtain the attendance attributes for this user, if available.
3.11
4.1 --- a/imiptools/handlers/resource.py Sun May 17 21:41:27 2015 +0200
4.2 +++ b/imiptools/handlers/resource.py Sun May 17 22:35:39 2015 +0200
4.3 @@ -72,7 +72,7 @@
4.4 # If newer than any old version, discard old details from the
4.5 # free/busy record and check for suitability.
4.6
4.7 - periods = self.obj.get_periods_for_freebusy(tzid, self.get_window_end())
4.8 + periods = self.obj.get_periods(tzid, self.get_window_end())
4.9 freebusy = self.store.get_freebusy(self.user)
4.10 scheduled = self.can_schedule(freebusy, periods)
4.11
5.1 --- a/imiptools/period.py Sun May 17 21:41:27 2015 +0200
5.2 +++ b/imiptools/period.py Sun May 17 22:35:39 2015 +0200
5.3 @@ -56,8 +56,8 @@
5.4
5.5 if isinstance(other, Period):
5.6 return cmp(
5.7 - (to_utc_datetime(self.get_start(), self.get_tzid()), to_utc_datetime(self.get_end(), self.get_tzid())),
5.8 - (to_utc_datetime(other.get_start(), self.get_tzid()), to_utc_datetime(other.get_end(), self.get_tzid()))
5.9 + (self.get_start_point(), self.get_end_point()),
5.10 + (other.get_start_point(), other.get_end_point())
5.11 )
5.12 else:
5.13 return 1
5.14 @@ -85,6 +85,12 @@
5.15 def get_end_item(self):
5.16 return self.end, get_datetime_attributes(self.end)
5.17
5.18 + def get_start_point(self):
5.19 + return to_utc_datetime(self.get_start(), self.get_tzid())
5.20 +
5.21 + def get_end_point(self):
5.22 + return to_utc_datetime(self.get_end(), self.get_tzid())
5.23 +
5.24 class FreeBusyPeriod(Period):
5.25
5.26 "A free/busy record abstraction."
5.27 @@ -105,7 +111,9 @@
5.28 self.organiser = organiser
5.29
5.30 def as_tuple(self):
5.31 - return format_datetime(self.start), format_datetime(self.end), self.uid, self.transp, self.recurrenceid, self.summary, self.organiser
5.32 + return format_datetime(self.get_start_point()), \
5.33 + format_datetime(self.get_end_point()), \
5.34 + self.uid, self.transp, self.recurrenceid, self.summary, self.organiser
5.35
5.36 def __cmp__(self, other):
5.37
5.38 @@ -136,10 +144,10 @@
5.39 self.end_attr = end_attr
5.40
5.41 def get_start_item(self):
5.42 - return self.start, self.start_attr
5.43 + return self.get_start(), self.start_attr
5.44
5.45 def get_end_item(self):
5.46 - return self.end, self.end_attr
5.47 + return self.get_end(), self.end_attr
5.48
5.49 def get_tzid(self):
5.50 return get_tzid(self.start_attr, self.end_attr) or self.tzid
5.51 @@ -249,7 +257,7 @@
5.52
5.53 # Stop looking if the start no longer matches the recurrence identifier.
5.54
5.55 - if fb.get_start() != start:
5.56 + if fb.get_start_point() != start:
5.57 return
5.58
5.59 # If the period belongs to the parent object, remove it and return.
5.60 @@ -272,21 +280,21 @@
5.61 # Find the range of periods potentially overlapping the period in the
5.62 # free/busy collection.
5.63
5.64 - last = bisect_right(freebusy, Period(period.get_end(), period.get_end()))
5.65 + last = bisect_right(freebusy, Period(period.get_end(), period.get_end(), period.get_tzid()))
5.66 startpoints = freebusy[:last]
5.67
5.68 # Find the range of periods potentially overlapping the period in a version
5.69 # of the free/busy collection sorted according to end datetimes.
5.70
5.71 - endpoints = [(fb.get_end(), fb.get_start(), fb) for fb in startpoints]
5.72 + endpoints = [(fb.get_end_point(), fb.get_start_point(), fb) for fb in startpoints]
5.73 endpoints.sort()
5.74 - first = bisect_left(endpoints, (period.get_start(),))
5.75 + first = bisect_left(endpoints, (period.get_start_point(),))
5.76 endpoints = endpoints[first:]
5.77
5.78 overlapping = set()
5.79
5.80 for end, start, fb in endpoints:
5.81 - if end > period.get_start() and start < period.get_end():
5.82 + if end > period.get_start_point() and start < period.get_end_point():
5.83 overlapping.add(fb)
5.84
5.85 overlapping = list(overlapping)
5.86 @@ -595,6 +603,6 @@
5.87 remove_period(freebusy, uid, recurrenceid)
5.88
5.89 for p in periods:
5.90 - insert_period(freebusy, FreeBusyPeriod(p.get_start(), p.get_end(), uid, transp, recurrenceid, summary, organiser))
5.91 + insert_period(freebusy, FreeBusyPeriod(p.get_start(), p.get_end(), uid, transp, recurrenceid, summary, organiser, p.get_tzid()))
5.92
5.93 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/imipweb/event.py Sun May 17 21:41:27 2015 +0200
6.2 +++ b/imipweb/event.py Sun May 17 22:35:39 2015 +0200
6.3 @@ -23,8 +23,7 @@
6.4 from imiptools.client import update_attendees, update_participation
6.5 from imiptools.data import get_uri, uri_dict, uri_values
6.6 from imiptools.dates import format_datetime, get_datetime_item, \
6.7 - get_period_item, get_recurrence_start, to_date, \
6.8 - to_timezone
6.9 + get_period_item, to_date, to_timezone
6.10 from imiptools.mail import Messenger
6.11 from imiptools.period import have_conflict
6.12 from imipweb.data import EventPeriod, \
6.13 @@ -64,21 +63,6 @@
6.14 def is_organiser(self, obj):
6.15 return get_uri(obj.get_value("ORGANIZER")) == self.user
6.16
6.17 - def is_replaced(self, period, recurrenceids):
6.18 - for s in recurrenceids:
6.19 - dt = get_recurrence_start(s, self.get_tzid())
6.20 - if period.get_start() == dt:
6.21 - return s
6.22 - return None
6.23 -
6.24 - def is_affected(self, period, recurrenceid):
6.25 - if not recurrenceid:
6.26 - return None
6.27 - dt = get_recurrence_start(recurrenceid, self.get_tzid())
6.28 - if period.get_start() == dt:
6.29 - return recurrenceid
6.30 - return None
6.31 -
6.32 # Request logic methods.
6.33
6.34 def handle_request(self, obj):
6.35 @@ -854,7 +838,7 @@
6.36 # Obtain the user's timezone.
6.37
6.38 tzid = self.get_tzid()
6.39 - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
6.40 + periods = obj.get_periods(self.get_tzid(), self.get_window_end())
6.41
6.42 # Indicate whether there are conflicting events.
6.43
7.1 --- a/imipweb/handler.py Sun May 17 21:41:27 2015 +0200
7.2 +++ b/imipweb/handler.py Sun May 17 22:35:39 2015 +0200
7.3 @@ -81,7 +81,7 @@
7.4 # free/busy details).
7.5
7.6 update_freebusy(freebusy,
7.7 - self.obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()),
7.8 + self.obj.get_periods(self.get_tzid(), self.get_window_end()),
7.9 self.obj.get_value("TRANSP") or "OPAQUE",
7.10 self.uid, self.recurrenceid,
7.11 self.obj.get_value("SUMMARY"),
8.1 --- a/imipweb/resource.py Sun May 17 21:41:27 2015 +0200
8.2 +++ b/imipweb/resource.py Sun May 17 22:35:39 2015 +0200
8.3 @@ -22,7 +22,8 @@
8.4 from datetime import datetime
8.5 from imiptools.client import Client
8.6 from imiptools.data import get_uri, get_window_end, Object, uri_values
8.7 -from imiptools.dates import format_datetime, format_time, to_recurrence_start
8.8 +from imiptools.dates import format_datetime, format_time, get_recurrence_start, \
8.9 + to_recurrence_start
8.10 from imiptools.period import FreeBusyPeriod, \
8.11 remove_period, remove_affected_period, update_freebusy
8.12 from imipweb.env import CGIEnvironment
8.13 @@ -128,7 +129,7 @@
8.14 for uid, recurrenceid in self._get_requests():
8.15 obj = self._get_object(uid, recurrenceid)
8.16 if obj:
8.17 - periods = obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end())
8.18 + periods = obj.get_periods(self.get_tzid(), self.get_window_end())
8.19 recurrenceids = self._get_recurrences(uid)
8.20
8.21 # Convert the periods to more substantial free/busy items.
8.22 @@ -138,7 +139,7 @@
8.23 # Subtract any recurrences from the free/busy details of a
8.24 # parent object.
8.25
8.26 - if recurrenceid or p.start not in recurrenceids:
8.27 + if recurrenceid or not self.is_replaced(p, recurrenceids):
8.28 summary.append(
8.29 FreeBusyPeriod(
8.30 p.get_start(),
8.31 @@ -152,6 +153,23 @@
8.32 ))
8.33 return summary
8.34
8.35 + # Period and recurrence testing.
8.36 +
8.37 + def is_replaced(self, period, recurrenceids):
8.38 + for s in recurrenceids:
8.39 + dt = get_recurrence_start(s, self.get_tzid())
8.40 + if period.get_start() == dt:
8.41 + return s
8.42 + return None
8.43 +
8.44 + def is_affected(self, period, recurrenceid):
8.45 + if not recurrenceid:
8.46 + return None
8.47 + dt = get_recurrence_start(recurrenceid, self.get_tzid())
8.48 + if period.get_start() == dt:
8.49 + return recurrenceid
8.50 + return None
8.51 +
8.52 # Preference methods.
8.53
8.54 def get_user_locale(self):
8.55 @@ -195,7 +213,7 @@
8.56 freebusy = self.store.get_freebusy(self.user)
8.57
8.58 update_freebusy(freebusy,
8.59 - obj.get_periods_for_freebusy(self.get_tzid(), self.get_window_end()),
8.60 + obj.get_periods(self.get_tzid(), self.get_window_end()),
8.61 is_only_organiser and "ORG" or obj.get_value("TRANSP"),
8.62 uid, recurrenceid,
8.63 obj.get_value("SUMMARY"),