# HG changeset patch # User Paul Boddie # Date 1421185193 -3600 # Node ID e835f990697abe21f366cf7178cb4ad9f135ce32 # Parent d8a56ee98d47752150c171d1095deedb2c35610c Moved date-related functions into a separate module for period module usage. diff -r d8a56ee98d47 -r e835f990697a imiptools/content.py --- a/imiptools/content.py Tue Jan 13 00:18:53 2015 +0100 +++ b/imiptools/content.py Tue Jan 13 22:39:53 2015 +0100 @@ -20,33 +20,21 @@ this program. If not, see . """ -from datetime import date, datetime, timedelta +from datetime import datetime, timedelta from email.mime.text import MIMEText +from imiptools.dates import * from imiptools.period import have_conflict, insert_period, remove_period -from pytz import timezone, UnknownTimeZoneError +from pytz import timezone from vCalendar import parse, ParseError, to_dict from vRecurrence import get_parameters, get_rule import email.utils import imip_store -import re try: from cStringIO import StringIO except ImportError: from StringIO import StringIO -# iCalendar date and datetime parsing (from DateSupport in MoinSupport). - -date_icalendar_regexp_str = ur'(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{2})' -datetime_icalendar_regexp_str = date_icalendar_regexp_str + \ - ur'(?:' \ - ur'T(?P[0-2][0-9])(?P[0-5][0-9])(?P[0-6][0-9])' \ - ur'(?PZ)?' \ - ur')?' - -match_date_icalendar = re.compile(date_icalendar_regexp_str, re.UNICODE).match -match_datetime_icalendar = re.compile(datetime_icalendar_regexp_str, re.UNICODE).match - # Content interpretation. def get_items(d, name, all=True): @@ -101,38 +89,6 @@ dt = get_datetime(value, attr) return to_utc_datetime(dt) -def to_utc_datetime(dt): - if not dt: - return None - elif isinstance(dt, datetime): - return dt.astimezone(timezone("UTC")) - else: - return dt - -def to_timezone(dt, name): - try: - tz = name and timezone(name) or None - except UnknownTimeZoneError: - tz = None - if tz is not None: - if not dt.tzinfo: - return tz.localize(dt) - else: - return dt.astimezone(tz) - else: - return dt - -def format_datetime(dt): - if not dt: - return None - elif isinstance(dt, datetime): - if dt.tzname() == "UTC": - return dt.strftime("%Y%m%dT%H%M%SZ") - else: - return dt.strftime("%Y%m%dT%H%M%S") - else: - return dt.strftime("%Y%m%d") - def get_addresses(values): return [address for name, address in email.utils.getaddresses(values)] @@ -151,34 +107,6 @@ def uri_items(items): return [(get_uri(value), attr) for value, attr in items] -def get_datetime(value, attr=None): - - """ - Return a datetime object from the given 'value' in iCalendar format, using - the 'attr' mapping (if specified) to control the conversion. - """ - - 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")) - ) - - # 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")) - ) - return None - # NOTE: Need to expose the 100 day window for recurring events in the # NOTE: configuration. diff -r d8a56ee98d47 -r e835f990697a imiptools/dates.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imiptools/dates.py Tue Jan 13 22:39:53 2015 +0100 @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +""" +Date processing functions. + +Copyright (C) 2014, 2015 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from datetime import date, datetime +from pytz import timezone, UnknownTimeZoneError +import re + +# iCalendar date and datetime parsing (from DateSupport in MoinSupport). + +date_icalendar_regexp_str = ur'(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{2})' +datetime_icalendar_regexp_str = date_icalendar_regexp_str + \ + ur'(?:' \ + ur'T(?P[0-2][0-9])(?P[0-5][0-9])(?P[0-6][0-9])' \ + ur'(?PZ)?' \ + ur')?' + +match_date_icalendar = re.compile(date_icalendar_regexp_str, re.UNICODE).match +match_datetime_icalendar = re.compile(datetime_icalendar_regexp_str, re.UNICODE).match + +def to_utc_datetime(dt): + if not dt: + return None + elif isinstance(dt, datetime): + return dt.astimezone(timezone("UTC")) + else: + return dt + +def to_timezone(dt, name): + try: + tz = name and timezone(name) or None + except UnknownTimeZoneError: + tz = None + if tz is not None: + if not dt.tzinfo: + return tz.localize(dt) + else: + return dt.astimezone(tz) + else: + return dt + +def format_datetime(dt): + if not dt: + return None + elif isinstance(dt, datetime): + if dt.tzname() == "UTC": + return dt.strftime("%Y%m%dT%H%M%SZ") + else: + return dt.strftime("%Y%m%dT%H%M%S") + else: + return dt.strftime("%Y%m%d") + +def get_datetime(value, attr=None): + + """ + Return a datetime object from the given 'value' in iCalendar format, using + the 'attr' mapping (if specified) to control the conversion. + """ + + 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")) + ) + + # 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")) + ) + return None + +def get_start_of_day(dt): + return datetime(dt.year, dt.month, dt.day, 0, 0, tzinfo=dt.tzinfo) + +# vim: tabstop=4 expandtab shiftwidth=4