1.1 --- a/imiptools/data.py Sun May 17 17:16:23 2015 +0200
1.2 +++ b/imiptools/data.py Sun May 17 17:59:06 2015 +0200
1.3 @@ -411,8 +411,8 @@
1.4
1.5 "A period with origin information from the object."
1.6
1.7 - def __init__(self, start, end, origin, start_attr=None, end_attr=None):
1.8 - Period.__init__(self, start, end, origin)
1.9 + def __init__(self, start, end, tzid=None, origin=None, start_attr=None, end_attr=None):
1.10 + Period.__init__(self, start, end, tzid, origin)
1.11 self.start_attr = start_attr
1.12 self.end_attr = end_attr
1.13
1.14 @@ -423,13 +423,13 @@
1.15 return self.end, self.end_attr
1.16
1.17 def get_tzid(self):
1.18 - return get_tzid(self.start_attr, self.end_attr)
1.19 + return get_tzid(self.start_attr, self.end_attr) or self.tzid
1.20
1.21 def as_tuple(self):
1.22 - return self.start, self.end, self.origin, self.start_attr, self.end_attr
1.23 + return self.start, self.end, self.tzid, self.origin, self.start_attr, self.end_attr
1.24
1.25 def __repr__(self):
1.26 - return "RecurringPeriod(%r, %r, %r, %r, %r)" % (self.start, self.end, self.origin, self.start_attr, self.end_attr)
1.27 + return "RecurringPeriod(%r)" % (self.as_tuple(),)
1.28
1.29 def get_periods(obj, tzid, window_end, inclusive=False):
1.30
1.31 @@ -458,7 +458,7 @@
1.32 tzid = get_tzid(dtstart_attr, dtend_attr) or tzid
1.33
1.34 if not rrule:
1.35 - periods = [RecurringPeriod(dtstart, dtend, "DTSTART", dtstart_attr, dtend_attr)]
1.36 + periods = [RecurringPeriod(dtstart, dtend, tzid, "DTSTART", dtstart_attr, dtend_attr)]
1.37 else:
1.38 # Recurrence rules create multiple instances to be checked.
1.39 # Conflicts may only be assessed within a period defined by policy
1.40 @@ -477,7 +477,7 @@
1.41 for start in selector.materialise(dtstart, window_end, parameters.get("COUNT"), parameters.get("BYSETPOS"), inclusive):
1.42 start = to_timezone(datetime(*start), tzid)
1.43 end = start + duration
1.44 - periods.append(RecurringPeriod(start, end, "RRULE"))
1.45 + periods.append(RecurringPeriod(start, end, tzid, "RRULE"))
1.46
1.47 # Add recurrence dates.
1.48
1.49 @@ -486,9 +486,9 @@
1.50 if rdates:
1.51 for rdate, rdate_attr in rdates:
1.52 if isinstance(rdate, tuple):
1.53 - periods.append(RecurringPeriod(rdate[0], rdate[1], "RDATE", rdate_attr))
1.54 + periods.append(RecurringPeriod(rdate[0], rdate[1], tzid, "RDATE", rdate_attr))
1.55 else:
1.56 - periods.append(RecurringPeriod(rdate, rdate + duration, "RDATE", rdate_attr))
1.57 + periods.append(RecurringPeriod(rdate, rdate + duration, tzid, "RDATE", rdate_attr))
1.58
1.59 # Return a sorted list of the periods.
1.60
2.1 --- a/imiptools/period.py Sun May 17 17:16:23 2015 +0200
2.2 +++ b/imiptools/period.py Sun May 17 17:59:06 2015 +0200
2.3 @@ -23,26 +23,42 @@
2.4 from datetime import date, datetime, timedelta
2.5 from imiptools.dates import format_datetime, get_datetime, \
2.6 get_datetime_attributes, \
2.7 - get_start_of_day, to_timezone
2.8 + get_start_of_day, to_timezone, to_utc_datetime
2.9
2.10 class Period:
2.11
2.12 "A basic period abstraction."
2.13
2.14 - def __init__(self, start, end, origin=None):
2.15 + def __init__(self, start, end, tzid=None, origin=None):
2.16 +
2.17 + """
2.18 + Initialise a period with the given 'start' and 'end', having a
2.19 + contextual 'tzid', if specified, and an indicated 'origin'.
2.20 + """
2.21 +
2.22 self.start = isinstance(start, date) and start or get_datetime(start)
2.23 self.end = isinstance(end, date) and end or get_datetime(end)
2.24 + self.tzid = tzid
2.25 self.origin = origin
2.26
2.27 def as_tuple(self):
2.28 - return self.start, self.end
2.29 + return self.start, self.end, self.tzid, self.origin
2.30
2.31 def __hash__(self):
2.32 return hash((self.get_start(), self.get_end()))
2.33
2.34 def __cmp__(self, other):
2.35 +
2.36 + """
2.37 + Return a comparison result against 'other' using points in time,
2.38 + employing the time zone context to convert dates.
2.39 + """
2.40 +
2.41 if isinstance(other, Period):
2.42 - return cmp((self.get_start(), self.get_end()), (other.get_start(), other.get_end()))
2.43 + return cmp(
2.44 + (to_utc_datetime(self.get_start(), self.get_tzid()), to_utc_datetime(self.get_end(), self.get_tzid())),
2.45 + (to_utc_datetime(other.get_start(), self.get_tzid()), to_utc_datetime(other.get_end(), self.get_tzid()))
2.46 + )
2.47 else:
2.48 return 1
2.49
2.50 @@ -50,7 +66,7 @@
2.51 return self.get_start(), self.get_end()
2.52
2.53 def __repr__(self):
2.54 - return "Period(%r, %r)" % (self.start, self.end)
2.55 + return "Period(%r)" % (self.as_tuple(),)
2.56
2.57 # Datetime metadata methods.
2.58
2.59 @@ -60,6 +76,9 @@
2.60 def get_end(self):
2.61 return self.end
2.62
2.63 + def get_tzid(self):
2.64 + return self.tzid
2.65 +
2.66 def get_start_item(self):
2.67 return self.start, get_datetime_attributes(self.start)
2.68
2.69 @@ -70,15 +89,15 @@
2.70
2.71 "A free/busy record abstraction."
2.72
2.73 - def __init__(self, start, end, uid=None, transp=None, recurrenceid=None, summary=None, organiser=None):
2.74 + def __init__(self, start, end, uid=None, transp=None, recurrenceid=None, summary=None, organiser=None, tzid=None):
2.75
2.76 """
2.77 - Initialise a free/busy period with 'start' and 'end' datetime string
2.78 - representations, employing UTC, plus any 'uid', 'transp',
2.79 - 'recurrenceid', 'summary' and 'organiser' details.
2.80 + Initialise a free/busy period with the given 'start' and 'end' limits,
2.81 + with an optional 'tzid', plus any 'uid', 'transp', 'recurrenceid',
2.82 + 'summary' and 'organiser' details.
2.83 """
2.84
2.85 - Period.__init__(self, start, end)
2.86 + Period.__init__(self, start, end, tzid)
2.87 self.uid = uid
2.88 self.transp = transp
2.89 self.recurrenceid = recurrenceid
2.90 @@ -89,18 +108,23 @@
2.91 return format_datetime(self.start), format_datetime(self.end), self.uid, self.transp, self.recurrenceid, self.summary, self.organiser
2.92
2.93 def __cmp__(self, other):
2.94 - if isinstance(other, FreeBusyPeriod):
2.95 - return cmp((self.get_start(), self.get_end(), self.uid), (other.get_start(), other.get_end(), other.uid))
2.96 +
2.97 + """
2.98 + Compare this object to 'other', employing the uid if the periods
2.99 + involved are the same.
2.100 + """
2.101 +
2.102 + result = Period.__cmp__(self, other)
2.103 + if result == 0 and isinstance(other, FreeBusyPeriod):
2.104 + return cmp(self.uid, other.uid)
2.105 else:
2.106 - return Period.__cmp__(self, other)
2.107 + return result
2.108
2.109 def get_key(self):
2.110 - return self.uid, self.recurrenceid, self.start
2.111 + return self.uid, self.recurrenceid, self.get_start()
2.112
2.113 def __repr__(self):
2.114 - return "FreeBusyPeriod(%r, %r, %r, %r, %r, %r, %r)" % (
2.115 - self.start, self.end, self.uid, self.transp, self.recurrenceid,
2.116 - self.summary, self.organiser)
2.117 + return "FreeBusyPeriod(%r)" % (self.as_tuple(),)
2.118
2.119 # Time and period management.
2.120
3.1 --- a/imipweb/data.py Sun May 17 17:16:23 2015 +0200
3.2 +++ b/imipweb/data.py Sun May 17 17:59:06 2015 +0200
3.3 @@ -36,7 +36,7 @@
3.4 intended to represent information obtained from an iCalendar resource.
3.5 """
3.6
3.7 - def __init__(self, start, end, start_attr=None, end_attr=None, form_start=None, form_end=None, origin=None):
3.8 + def __init__(self, start, end, tzid=None, origin=None, start_attr=None, end_attr=None, form_start=None, form_end=None):
3.9
3.10 """
3.11 Initialise a period with the given 'start' and 'end' datetimes, together
3.12 @@ -45,15 +45,15 @@
3.13 'origin' indicating the kind of period this object describes.
3.14 """
3.15
3.16 - RecurringPeriod.__init__(self, start, end, origin, start_attr, end_attr)
3.17 + RecurringPeriod.__init__(self, start, end, tzid, origin, start_attr, end_attr)
3.18 self.form_start = form_start
3.19 self.form_end = form_end
3.20
3.21 def as_tuple(self):
3.22 - return self.start, self.end, self.start_attr, self.end_attr, self.form_start, self.form_end, self.origin
3.23 + return self.start, self.end, self.tzid, self.origin, self.start_attr, self.end_attr, self.form_start, self.form_end
3.24
3.25 def __repr__(self):
3.26 - return "EventPeriod(%r, %r, %r, %r, %r, %r, %r)" % self.as_tuple()
3.27 + return "EventPeriod(%r)" % (self.as_tuple(),)
3.28
3.29 def as_event_period(self):
3.30 return self
3.31 @@ -76,6 +76,7 @@
3.32 self.get_form_end(),
3.33 isinstance(self.end, datetime) or self.get_start() != self.get_end(),
3.34 isinstance(self.start, datetime) or isinstance(self.end, datetime),
3.35 + self.tzid,
3.36 self.origin
3.37 )
3.38
3.39 @@ -93,18 +94,19 @@
3.40
3.41 "A period whose information originates from a form."
3.42
3.43 - def __init__(self, start, end, end_enabled=True, times_enabled=True, origin=None):
3.44 + def __init__(self, start, end, end_enabled=True, times_enabled=True, tzid=None, origin=None):
3.45 self.start = start
3.46 self.end = end
3.47 self.end_enabled = end_enabled
3.48 self.times_enabled = times_enabled
3.49 + self.tzid = tzid
3.50 self.origin = origin
3.51
3.52 def as_tuple(self):
3.53 - return self.start, self.end, self.end_enabled, self.times_enabled, self.origin
3.54 + return self.start, self.end, self.end_enabled, self.times_enabled, self.tzid, self.origin
3.55
3.56 def __repr__(self):
3.57 - return "FormPeriod(%r, %r, %r, %r, %r)" % self.as_tuple()
3.58 + return "FormPeriod(%r)" % (self.as_tuple(),)
3.59
3.60 def _get_start(self):
3.61 return self.start.as_datetime(self.times_enabled), self.start.get_attributes(self.times_enabled)
3.62 @@ -158,7 +160,7 @@
3.63 index is not None and ("dtend", index) or "dtend"
3.64 ])
3.65
3.66 - return EventPeriod(dtstart, end_date_to_calendar(dtend), dtstart_attr, dtend_attr, self.start, self.end, self.origin)
3.67 + return EventPeriod(dtstart, end_date_to_calendar(dtend), self.origin, self.tzid, dtstart_attr, dtend_attr, self.start, self.end)
3.68
3.69 # Period data methods.
3.70
3.71 @@ -204,7 +206,7 @@
3.72 return self.date, self.hour, self.minute, self.second, self.tzid, self.dt, self.attr
3.73
3.74 def __repr__(self):
3.75 - return "FormDate(%r, %r, %r, %r, %r, %r, %r)" % self.as_tuple()
3.76 + return "FormDate(%r)" % (self.as_tuple(),)
3.77
3.78 def get_component(self, value):
3.79 return (value or "").rjust(2, "0")[:2]
3.80 @@ -292,7 +294,7 @@
3.81 dtend, dtend_attr = period.get_end_item()
3.82 if not isinstance(period, RecurringPeriod):
3.83 dtend = end_date_to_calendar(dtend)
3.84 - return EventPeriod(dtstart, dtend, dtstart_attr, dtend_attr, origin=period.origin)
3.85 + return EventPeriod(dtstart, dtend, period.tzid, period.origin, dtstart_attr, dtend_attr)
3.86
3.87 def form_period_from_period(period):
3.88 if isinstance(period, EventPeriod):
4.1 --- a/imipweb/event.py Sun May 17 17:16:23 2015 +0200
4.2 +++ b/imipweb/event.py Sun May 17 17:59:06 2015 +0200
4.3 @@ -334,7 +334,7 @@
4.4 else:
4.5 dtend, dtend_attr = dtstart, dtstart_attr
4.6
4.7 - return EventPeriod(dtstart, dtend, dtstart_attr, dtend_attr)
4.8 + return EventPeriod(dtstart, dtend, self.get_tzid(), None, dtstart_attr, dtend_attr)
4.9
4.10 def get_main_period(self):
4.11
4.12 @@ -347,7 +347,7 @@
4.13 start = self.get_date_control_values("dtstart")
4.14 end = self.get_date_control_values("dtend")
4.15
4.16 - return FormPeriod(start, end, dtend_enabled, dttimes_enabled)
4.17 + return FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid())
4.18
4.19 def get_current_recurrences(self, obj):
4.20
4.21 @@ -393,7 +393,7 @@
4.22
4.23 dtend_enabled = str(index) in all_dtend_enabled
4.24 dttimes_enabled = str(index) in all_dttimes_enabled
4.25 - period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, origin)
4.26 + period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid(), origin)
4.27 periods.append(period)
4.28
4.29 return periods
5.1 --- a/imipweb/resource.py Sun May 17 17:16:23 2015 +0200
5.2 +++ b/imipweb/resource.py Sun May 17 17:59:06 2015 +0200
5.3 @@ -147,7 +147,8 @@
5.4 obj.get_value("TRANSP"),
5.5 recurrenceid,
5.6 obj.get_value("SUMMARY"),
5.7 - obj.get_value("ORGANIZER")
5.8 + obj.get_value("ORGANIZER"),
5.9 + self.get_tzid()
5.10 ))
5.11 return summary
5.12