Improve Entity Time parsing
- Use parse_datetime() - Improve tzo node validation
This commit is contained in:
parent
00c7715c01
commit
9bf88c1f65
|
@ -16,11 +16,13 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
from datetime import tzinfo
|
from datetime import tzinfo
|
||||||
|
|
||||||
|
log = logging.getLogger('gajim.c.m.date_and_time')
|
||||||
|
|
||||||
PATTERN_DATETIME = re.compile(
|
PATTERN_DATETIME = re.compile(
|
||||||
r'([0-9]{4}-[0-9]{2}-[0-9]{2})'
|
r'([0-9]{4}-[0-9]{2}-[0-9]{2})'
|
||||||
|
@ -94,7 +96,30 @@ class LocalTimezone(tzinfo):
|
||||||
return tt.tm_isdst > 0
|
return tt.tm_isdst > 0
|
||||||
|
|
||||||
|
|
||||||
def create_tzinfo(hours=0, minutes=0):
|
def create_tzinfo(hours=0, minutes=0, tz_string=None):
|
||||||
|
if tz_string is None:
|
||||||
|
return timezone(timedelta(hours=hours, minutes=minutes))
|
||||||
|
|
||||||
|
if tz_string.lower() == 'z':
|
||||||
|
return timezone.utc
|
||||||
|
|
||||||
|
try:
|
||||||
|
hours, minutes = map(int, tz_string.split(':'))
|
||||||
|
except Exception:
|
||||||
|
log.warning('Wrong tz string: %s', tz_string)
|
||||||
|
return
|
||||||
|
|
||||||
|
if hours not in range(-24, 24):
|
||||||
|
log.warning('Wrong tz string: %s', tz_string)
|
||||||
|
return
|
||||||
|
|
||||||
|
if minutes not in range(0, 59):
|
||||||
|
log.warning('Wrong tz string: %s', tz_string)
|
||||||
|
return
|
||||||
|
|
||||||
|
if hours in (24, -24) and minutes != 0:
|
||||||
|
log.warning('Wrong tz string: %s', tz_string)
|
||||||
|
return
|
||||||
return timezone(timedelta(hours=hours, minutes=minutes))
|
return timezone(timedelta(hours=hours, minutes=minutes))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
# XEP-0202: Entity Time
|
# XEP-0202: Entity Time
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.date_and_time import parse_datetime
|
||||||
|
from gajim.common.modules.date_and_time import create_tzinfo
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.entity_time')
|
log = logging.getLogger('gajim.c.m.entity_time')
|
||||||
|
|
||||||
|
@ -61,10 +62,10 @@ class EntityTime:
|
||||||
log.info('Received: %s %s',
|
log.info('Received: %s %s',
|
||||||
stanza.getFrom(), time_info)
|
stanza.getFrom(), time_info)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(NetworkEvent('time-result-received',
|
||||||
TimeResultReceivedEvent(None, conn=self._con,
|
conn=self._con,
|
||||||
jid=stanza.getFrom(),
|
jid=stanza.getFrom(),
|
||||||
time_info=time_info))
|
time_info=time_info))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_info(stanza):
|
def _extract_info(stanza):
|
||||||
|
@ -74,42 +75,24 @@ class EntityTime:
|
||||||
return
|
return
|
||||||
|
|
||||||
tzo = time_.getTag('tzo').getData()
|
tzo = time_.getTag('tzo').getData()
|
||||||
if tzo.lower() == 'z':
|
if not tzo:
|
||||||
tzo = '0:0'
|
|
||||||
try:
|
|
||||||
tzoh, tzom = tzo.split(':')
|
|
||||||
except Exception:
|
|
||||||
log.warning('Wrong tzo node: %s', stanza)
|
log.warning('Wrong tzo node: %s', stanza)
|
||||||
return
|
return
|
||||||
utc_time = time_.getTag('utc').getData()
|
|
||||||
|
|
||||||
if utc_time[-1:] == 'Z':
|
remote_tz = create_tzinfo(tz_string=tzo)
|
||||||
# Remove the trailing 'Z'
|
if remote_tz is None:
|
||||||
utc_time = utc_time[:-1]
|
log.warning('Wrong tzo node: %s', stanza)
|
||||||
elif utc_time[-6:] == "+00:00":
|
return
|
||||||
# Remove the trailing "+00:00"
|
|
||||||
utc_time = utc_time[:-6]
|
utc_time = time_.getTag('utc').getData()
|
||||||
else:
|
date_time = parse_datetime(utc_time, check_utc=True)
|
||||||
|
if date_time is None:
|
||||||
log.warning('Wrong timezone defintion: %s %s',
|
log.warning('Wrong timezone defintion: %s %s',
|
||||||
utc_time, stanza.getFrom())
|
utc_time, stanza.getFrom())
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
date_time = date_time.astimezone(remote_tz)
|
||||||
dtime = datetime.datetime.strptime(utc_time, '%Y-%m-%dT%H:%M:%S')
|
return date_time.strftime('%c %Z')
|
||||||
except ValueError:
|
|
||||||
try:
|
|
||||||
dtime = datetime.datetime.strptime(utc_time,
|
|
||||||
'%Y-%m-%dT%H:%M:%S.%f')
|
|
||||||
except ValueError as error:
|
|
||||||
log.warning('Wrong time format: %s %s',
|
|
||||||
error, stanza.getFrom())
|
|
||||||
return
|
|
||||||
|
|
||||||
utc = datetime.timezone(datetime.timedelta(0))
|
|
||||||
dtime = dtime.replace(tzinfo=utc)
|
|
||||||
utc_offset = datetime.timedelta(hours=int(tzoh), minutes=int(tzom))
|
|
||||||
contact_tz = datetime.timezone(utc_offset, "remote timezone")
|
|
||||||
return dtime.astimezone(contact_tz).strftime('%c')
|
|
||||||
|
|
||||||
def _answer_request(self, _con, stanza):
|
def _answer_request(self, _con, stanza):
|
||||||
log.info('%s asked for the time', stanza.getFrom())
|
log.info('%s asked for the time', stanza.getFrom())
|
||||||
|
@ -132,9 +115,5 @@ class EntityTime:
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
|
|
||||||
class TimeResultReceivedEvent(NetworkIncomingEvent):
|
|
||||||
name = 'time-result-received'
|
|
||||||
|
|
||||||
|
|
||||||
def get_instance(*args, **kwargs):
|
def get_instance(*args, **kwargs):
|
||||||
return EntityTime(*args, **kwargs), 'EntityTime'
|
return EntityTime(*args, **kwargs), 'EntityTime'
|
||||||
|
|
Loading…
Reference in New Issue