# Slixmpp: The Slick XMPP Library # Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout # This file is part of Slixmpp. # See the file LICENSE for copying permission. import datetime as dt from slixmpp.plugins import BasePlugin, register_plugin from slixmpp.thirdparty import tzutc, tzoffset, parse_iso # ===================================================================== # To make it easier for stanzas without direct access to plugin objects # to use the XEP-0082 utility methods, we will define them as top-level # functions and then just reference them in the plugin itself. def parse(time_str): """ Convert a string timestamp into a datetime object. Arguments: time_str -- A formatted timestamp string. """ return parse_iso(time_str) def format_date(time_obj): """ Return a formatted string version of a date object. Format: YYYY-MM-DD Arguments: time_obj -- A date or datetime object. """ if isinstance(time_obj, dt.datetime): time_obj = time_obj.date() return time_obj.isoformat() def format_time(time_obj): """ Return a formatted string version of a time object. format: hh:mm:ss[.sss][TZD] arguments: time_obj -- A time or datetime object. """ if isinstance(time_obj, dt.datetime): time_obj = time_obj.timetz() timestamp = time_obj.isoformat() if time_obj.tzinfo == tzutc(): timestamp = timestamp[:-6] return '%sZ' % timestamp return timestamp def format_datetime(time_obj): """ Return a formatted string version of a datetime object. Format: YYYY-MM-DDThh:mm:ss[.sss]TZD arguments: time_obj -- A datetime object. """ timestamp = time_obj.isoformat('T') if time_obj.tzinfo == tzutc(): timestamp = timestamp[:-6] return '%sZ' % timestamp return timestamp def date(year=None, month=None, day=None, obj=False): """ Create a date only timestamp for the given instant. Unspecified components default to their current counterparts. Arguments: year -- Integer value of the year (4 digits) month -- Integer value of the month day -- Integer value of the day of the month. obj -- If True, return the date object instead of a formatted string. Defaults to False. """ today = dt.datetime.utcnow() if year is None: year = today.year if month is None: month = today.month if day is None: day = today.day value = dt.date(year, month, day) if obj: return value return format_date(value) def time(hour=None, min=None, sec=None, micro=None, offset=None, obj=False): """ Create a time only timestamp for the given instant. Unspecified components default to their current counterparts. Arguments: hour -- Integer value of the hour. min -- Integer value of the number of minutes. sec -- Integer value of the number of seconds. micro -- Integer value of the number of microseconds. offset -- Either a positive or negative number of seconds to offset from UTC to match a desired timezone, or a tzinfo object. obj -- If True, return the time object instead of a formatted string. Defaults to False. """ now = dt.datetime.utcnow() if hour is None: hour = now.hour if min is None: min = now.minute if sec is None: sec = now.second if micro is None: micro = now.microsecond if offset in (None, 0): offset = tzutc() elif not isinstance(offset, dt.tzinfo): offset = tzoffset(None, offset) value = dt.time(hour, min, sec, micro, offset) if obj: return value return format_time(value) def datetime(year=None, month=None, day=None, hour=None, min=None, sec=None, micro=None, offset=None, separators=True, obj=False): """ Create a datetime timestamp for the given instant. Unspecified components default to their current counterparts. Arguments: year -- Integer value of the year (4 digits) month -- Integer value of the month day -- Integer value of the day of the month. hour -- Integer value of the hour. min -- Integer value of the number of minutes. sec -- Integer value of the number of seconds. micro -- Integer value of the number of microseconds. offset -- Either a positive or negative number of seconds to offset from UTC to match a desired timezone, or a tzinfo object. obj -- If True, return the datetime object instead of a formatted string. Defaults to False. """ now = dt.datetime.utcnow() if year is None: year = now.year if month is None: month = now.month if day is None: day = now.day if hour is None: hour = now.hour if min is None: min = now.minute if sec is None: sec = now.second if micro is None: micro = now.microsecond if offset in (None, 0): offset = tzutc() elif not isinstance(offset, dt.tzinfo): offset = tzoffset(None, offset) value = dt.datetime(year, month, day, hour, min, sec, micro, offset) if obj: return value return format_datetime(value) class XEP_0082(BasePlugin): """ XEP-0082: XMPP Date and Time Profiles XMPP uses a subset of the formats allowed by ISO 8601 as a matter of pragmatism based on the relatively few formats historically used by the XMPP. Also see . Methods: date -- Create a time stamp using the Date profile. datetime -- Create a time stamp using the DateTime profile. time -- Create a time stamp using the Time profile. format_date -- Format an existing date object. format_datetime -- Format an existing datetime object. format_time -- Format an existing time object. parse -- Convert a time string into a Python datetime object. """ name = 'xep_0082' description = 'XEP-0082: XMPP Date and Time Profiles' dependencies = set() def plugin_init(self): """Start the XEP-0082 plugin.""" self.date = date self.datetime = datetime self.time = time self.format_date = format_date self.format_datetime = format_datetime self.format_time = format_time self.parse = parse register_plugin(XEP_0082)