# HG changeset patch # User Paul Boddie # Date 1427155828 -3600 # Node ID c28146a67ca280447afd2a4f5082281e396822c1 # Parent 21f7421c806afae71fa3195c4fd34f4917f54d14 Changed the get_periods function to convert date periods and plain dates to datetime periods, partly to avoid problems sorting the periods before potentially excluding some of them. Renamed get_date to to_date and added a to_datetime function in the dates module. Added various convenience functions related to iCalendar item generation. diff -r 21f7421c806a -r c28146a67ca2 imiptools/data.py --- a/imiptools/data.py Mon Mar 23 00:39:26 2015 +0100 +++ b/imiptools/data.py Tue Mar 24 01:10:28 2015 +0100 @@ -23,8 +23,8 @@ from datetime import datetime, timedelta from email.mime.text import MIMEText from imiptools.dates import format_datetime, get_datetime, get_duration, \ - get_freebusy_period, get_period, to_timezone, \ - to_utc_datetime + get_freebusy_period, get_period, to_datetime, \ + to_timezone, to_utc_datetime from imiptools.period import period_overlaps from pytz import timezone from vCalendar import iterwrite, parse, ParseError, to_dict, to_node @@ -426,8 +426,12 @@ origin_value = origin and ("RDATE",) or () for rdate in rdates: if isinstance(rdate, tuple): - periods.add(rdate + origin_value) + start, end = rdate + start = to_datetime(start, tzid) + end = to_datetime(end, tzid) + periods.add((start, end) + origin_value) else: + rdate = to_datetime(rdate, tzid) periods.add((rdate, rdate + duration) + origin_value) # Return a sorted list of the periods. @@ -442,8 +446,12 @@ if exdates: for exdate in exdates: if isinstance(exdate, tuple): - period = exdate + start, end = exdate + start = to_datetime(start, tzid) + end = to_datetime(end, tzid) + period = start, end else: + exdate = to_datetime(exdate, tzid) period = (exdate, exdate + duration) i = bisect_left(periods, period) while i < len(periods) and periods[i][:2] == period: diff -r 21f7421c806a -r c28146a67ca2 imiptools/dates.py --- a/imiptools/dates.py Mon Mar 23 00:39:26 2015 +0100 +++ b/imiptools/dates.py Tue Mar 24 01:10:28 2015 +0100 @@ -137,20 +137,61 @@ else: return None +def get_datetime_attributes(dt, tzid=None): + + "Return attributes for 'dt' and 'tzid'." + + if isinstance(dt, datetime): + attr = {"VALUE" : "DATE-TIME"} + if tzid: + attr["TZID"] = tzid + return attr + else: + return {"VALUE" : "DATE"} + + return {} + +def get_period_attributes(tzid=None): + + "Return attributes for 'tzid'." + + attr = {"VALUE" : "PERIOD"} + if tzid: + attr["TZID"] = tzid + return attr + def get_datetime_item(dt, tzid=None): "Return an iCalendar-compatible string and attributes for 'dt' and 'tzid'." if not dt: return None, None + dt = to_timezone(dt, tzid) value = format_datetime(dt) - if isinstance(dt, datetime): - attr = {"VALUE" : "DATE-TIME"} - if tzid: - attr["TZID"] = tzid + attr = get_datetime_attributes(dt, tzid) + return value, attr + +def get_period_item(start, end, tzid=None): + + """ + Return an iCalendar-compatible string and attributes for 'start', 'end' and + 'tzid'. + """ + + start = start and to_timezone(start, tzid) + end = end and to_timezone(end, tzid) + + start_value = start and format_datetime(start) or None + end_value = end and format_datetime(end) or None + + if start and end: + attr = get_period_attributes(tzid) + return "%s/%s" % (start_value, end_value), attr + elif start: + attr = get_datetime_attributes(start, tzid) + return start_value, attr else: - attr = {"VALUE" : "DATE"} - return value, attr + return None, None def get_datetime(value, attr=None): @@ -243,12 +284,24 @@ else: return None -def get_date(dt): +def to_date(dt): "Return the date of 'dt'." return date(dt.year, dt.month, dt.day) +def to_datetime(dt, tzid): + + """ + Return a datetime for 'dt', using the start of day for dates, and using the + 'tzid' for the conversion. + """ + + if isinstance(dt, datetime): + return dt + else: + return get_start_of_day(dt, tzid) + def get_start_of_day(dt, tzid): """