1""" 2 Slixmpp: The Slick XMPP Library 3 Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout 4 This file is part of Slixmpp. 5 6 See the file LICENSE for copying permission. 7""" 8 9import datetime as dt 10 11from slixmpp.plugins import BasePlugin, register_plugin 12from slixmpp.thirdparty import tzutc, tzoffset, parse_iso 13 14 15# ===================================================================== 16# To make it easier for stanzas without direct access to plugin objects 17# to use the XEP-0082 utility methods, we will define them as top-level 18# functions and then just reference them in the plugin itself. 19 20def parse(time_str): 21 """ 22 Convert a string timestamp into a datetime object. 23 24 Arguments: 25 time_str -- A formatted timestamp string. 26 """ 27 return parse_iso(time_str) 28 29 30def format_date(time_obj): 31 """ 32 Return a formatted string version of a date object. 33 34 Format: 35 YYYY-MM-DD 36 37 Arguments: 38 time_obj -- A date or datetime object. 39 """ 40 if isinstance(time_obj, dt.datetime): 41 time_obj = time_obj.date() 42 return time_obj.isoformat() 43 44 45def format_time(time_obj): 46 """ 47 Return a formatted string version of a time object. 48 49 format: 50 hh:mm:ss[.sss][TZD] 51 52 arguments: 53 time_obj -- A time or datetime object. 54 """ 55 if isinstance(time_obj, dt.datetime): 56 time_obj = time_obj.timetz() 57 timestamp = time_obj.isoformat() 58 if time_obj.tzinfo == tzutc(): 59 timestamp = timestamp[:-6] 60 return '%sZ' % timestamp 61 return timestamp 62 63 64def format_datetime(time_obj): 65 """ 66 Return a formatted string version of a datetime object. 67 68 Format: 69 YYYY-MM-DDThh:mm:ss[.sss]TZD 70 71 arguments: 72 time_obj -- A datetime object. 73 """ 74 timestamp = time_obj.isoformat('T') 75 if time_obj.tzinfo == tzutc(): 76 timestamp = timestamp[:-6] 77 return '%sZ' % timestamp 78 return timestamp 79 80 81def date(year=None, month=None, day=None, obj=False): 82 """ 83 Create a date only timestamp for the given instant. 84 85 Unspecified components default to their current counterparts. 86 87 Arguments: 88 year -- Integer value of the year (4 digits) 89 month -- Integer value of the month 90 day -- Integer value of the day of the month. 91 obj -- If True, return the date object instead 92 of a formatted string. Defaults to False. 93 """ 94 today = dt.datetime.utcnow() 95 if year is None: 96 year = today.year 97 if month is None: 98 month = today.month 99 if day is None: 100 day = today.day 101 value = dt.date(year, month, day) 102 if obj: 103 return value 104 return format_date(value) 105 106 107def time(hour=None, min=None, sec=None, micro=None, offset=None, obj=False): 108 """ 109 Create a time only timestamp for the given instant. 110 111 Unspecified components default to their current counterparts. 112 113 Arguments: 114 hour -- Integer value of the hour. 115 min -- Integer value of the number of minutes. 116 sec -- Integer value of the number of seconds. 117 micro -- Integer value of the number of microseconds. 118 offset -- Either a positive or negative number of seconds 119 to offset from UTC to match a desired timezone, 120 or a tzinfo object. 121 obj -- If True, return the time object instead 122 of a formatted string. Defaults to False. 123 """ 124 now = dt.datetime.utcnow() 125 if hour is None: 126 hour = now.hour 127 if min is None: 128 min = now.minute 129 if sec is None: 130 sec = now.second 131 if micro is None: 132 micro = now.microsecond 133 if offset in (None, 0): 134 offset = tzutc() 135 elif not isinstance(offset, dt.tzinfo): 136 offset = tzoffset(None, offset) 137 value = dt.time(hour, min, sec, micro, offset) 138 if obj: 139 return value 140 return format_time(value) 141 142 143def datetime(year=None, month=None, day=None, hour=None, 144 min=None, sec=None, micro=None, offset=None, 145 separators=True, obj=False): 146 """ 147 Create a datetime timestamp for the given instant. 148 149 Unspecified components default to their current counterparts. 150 151 Arguments: 152 year -- Integer value of the year (4 digits) 153 month -- Integer value of the month 154 day -- Integer value of the day of the month. 155 hour -- Integer value of the hour. 156 min -- Integer value of the number of minutes. 157 sec -- Integer value of the number of seconds. 158 micro -- Integer value of the number of microseconds. 159 offset -- Either a positive or negative number of seconds 160 to offset from UTC to match a desired timezone, 161 or a tzinfo object. 162 obj -- If True, return the datetime object instead 163 of a formatted string. Defaults to False. 164 """ 165 now = dt.datetime.utcnow() 166 if year is None: 167 year = now.year 168 if month is None: 169 month = now.month 170 if day is None: 171 day = now.day 172 if hour is None: 173 hour = now.hour 174 if min is None: 175 min = now.minute 176 if sec is None: 177 sec = now.second 178 if micro is None: 179 micro = now.microsecond 180 if offset in (None, 0): 181 offset = tzutc() 182 elif not isinstance(offset, dt.tzinfo): 183 offset = tzoffset(None, offset) 184 185 value = dt.datetime(year, month, day, hour, 186 min, sec, micro, offset) 187 if obj: 188 return value 189 return format_datetime(value) 190 191 192class XEP_0082(BasePlugin): 193 194 """ 195 XEP-0082: XMPP Date and Time Profiles 196 197 XMPP uses a subset of the formats allowed by ISO 8601 as a matter of 198 pragmatism based on the relatively few formats historically used by 199 the XMPP. 200 201 Also see <http://www.xmpp.org/extensions/xep-0082.html>. 202 203 Methods: 204 date -- Create a time stamp using the Date profile. 205 datetime -- Create a time stamp using the DateTime profile. 206 time -- Create a time stamp using the Time profile. 207 format_date -- Format an existing date object. 208 format_datetime -- Format an existing datetime object. 209 format_time -- Format an existing time object. 210 parse -- Convert a time string into a Python datetime object. 211 """ 212 213 name = 'xep_0082' 214 description = 'XEP-0082: XMPP Date and Time Profiles' 215 dependencies = set() 216 217 def plugin_init(self): 218 """Start the XEP-0082 plugin.""" 219 self.date = date 220 self.datetime = datetime 221 self.time = time 222 self.format_date = format_date 223 self.format_datetime = format_datetime 224 self.format_time = format_time 225 self.parse = parse 226 227 228register_plugin(XEP_0082) 229