# HG changeset patch # User Paul Boddie # Date 1422902594 -3600 # Node ID 58602ad6f673f95d20f7055d8127dd09f7683031 # Parent 6d8045a9b66e4a88d60ae005929b40cd11dd1800 Added some support for full day events, particularly in the manager interface. diff -r 6d8045a9b66e -r 58602ad6f673 imip_manager.py --- a/imip_manager.py Mon Feb 02 18:46:59 2015 +0100 +++ b/imip_manager.py Mon Feb 02 19:43:14 2015 +0100 @@ -24,7 +24,7 @@ LIBRARY_PATH = "/var/lib/imip-agent" -from datetime import datetime +from datetime import date, datetime, timedelta import babel.dates import cgi, os, sys @@ -295,7 +295,14 @@ return self._format_datetime(babel.dates.format_time, dt, format) def format_datetime(self, dt, format): - return self._format_datetime(babel.dates.format_datetime, dt, format) + return self._format_datetime( + isinstance(dt, datetime) and babel.dates.format_datetime or babel.dates.format_date, + dt, format) + + def format_end_datetime(self, dt, format): + if isinstance(dt, date): + dt = dt - timedelta(1) + return self.format_datetime(dt, format) def _format_datetime(self, fn, dt, format): return fn(dt, format=format, locale=self.get_user_locale()) @@ -543,7 +550,9 @@ if name in ["DTSTART", "DTEND"]: value, attr = obj.get_item(name) tzid = attr.get("TZID", tzid) - value = self.format_datetime(to_timezone(get_datetime(value), tzid), "full") + value = ( + name == "DTSTART" and self.format_datetime or self.format_end_datetime + )(to_timezone(get_datetime(value), tzid), "full") page.th(label, class_="objectheading") page.td(value) page.tr.close() diff -r 6d8045a9b66e -r 58602ad6f673 imiptools/dates.py --- a/imiptools/dates.py Mon Feb 02 18:46:59 2015 +0100 +++ b/imiptools/dates.py Mon Feb 02 19:43:14 2015 +0100 @@ -51,7 +51,7 @@ return to_tz(dt, tz) def to_tz(dt, tz): - if tz is not None: + if tz is not None and isinstance(dt, datetime): if not dt.tzinfo: return tz.localize(dt) else: @@ -80,29 +80,33 @@ if not attr or attr.get("VALUE") in (None, "DATE-TIME"): m = match_datetime_icalendar(value) if m: - dt = datetime( - int(m.group("year")), int(m.group("month")), int(m.group("day")), - int(m.group("hour")), int(m.group("minute")), int(m.group("second")) - ) + year, month, day, hour, minute, second = map(m.group, [ + "year", "month", "day", "hour", "minute", "second" + ]) - # Impose the indicated timezone. - # NOTE: This needs an ambiguity policy for DST changes. + if hour and minute and second: + dt = datetime( + int(year), int(month), int(day), int(hour), int(minute), int(second) + ) - return to_timezone(dt, m.group("utc") and "UTC" or attr and attr.get("TZID") or None) + # Impose the indicated timezone. + # NOTE: This needs an ambiguity policy for DST changes. + + return to_timezone(dt, m.group("utc") and "UTC" or attr and attr.get("TZID") or None) if not attr or attr.get("VALUE") == "DATE": m = match_date_icalendar(value) if m: - return date( - int(m.group("year")), int(m.group("month")), int(m.group("day")) - ) + year, month, day = map(m.group, ["year", "month", "day"]) + return date(int(year), int(month), int(day)) + return None -def get_start_of_day(dt): - return datetime(dt.year, dt.month, dt.day, 0, 0, tzinfo=dt.tzinfo) +def get_start_of_day(dt, tzid=None): + return datetime(dt.year, dt.month, dt.day, 0, 0, tzinfo=(tzid and timezone(tzid) or dt.tzinfo)) -def get_end_of_day(dt): - return get_start_of_day(dt + timedelta(1)) +def get_end_of_day(dt, tzid=None): + return get_start_of_day(dt + timedelta(1), tzid) def ends_on_same_day(dt, end): return ( diff -r 6d8045a9b66e -r 58602ad6f673 imiptools/period.py --- a/imiptools/period.py Mon Feb 02 18:46:59 2015 +0100 +++ b/imiptools/period.py Mon Feb 02 19:43:14 2015 +0100 @@ -20,6 +20,7 @@ """ from bisect import bisect_left, insort_left +from datetime import datetime from imiptools.dates import get_datetime, get_start_of_day, to_timezone # Time management. @@ -124,9 +125,16 @@ start, end = t[:2] # NOTE: This only really works if the datetimes are UTC already. + # NOTE: Since the periods should originate from the free/busy data, + # NOTE: and since that data should employ UTC times, this should not be + # NOTE: an immediate problem. - start = to_timezone(get_datetime(start), tzid) - end = to_timezone(get_datetime(end), tzid) + start = get_datetime(start) + end = get_datetime(end) + + start = isinstance(start, datetime) and to_timezone(start, tzid) or get_start_of_day(start, tzid) + end = isinstance(end, datetime) and to_timezone(end, tzid) or get_start_of_day(end, tzid) + l.append((start, end) + tuple(t[2:])) return l