mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Cleaned up Python library imports: googleapiclient, iso8601. #1829
This commit is contained in:
@@ -19,7 +19,6 @@ dependencies = [
|
|||||||
"google-auth-oauthlib>=1.2.2",
|
"google-auth-oauthlib>=1.2.2",
|
||||||
"google-auth>=2.39.0",
|
"google-auth>=2.39.0",
|
||||||
"httplib2>=0.22.0",
|
"httplib2>=0.22.0",
|
||||||
"iso8601",
|
|
||||||
"lxml>=5.4.0",
|
"lxml>=5.4.0",
|
||||||
"passlib>=1.7.4",
|
"passlib>=1.7.4",
|
||||||
"pathvalidate>=3.2.3",
|
"pathvalidate>=3.2.3",
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
7.20.04
|
||||||
|
|
||||||
|
Cleaned up Python library imports: googleapiclient, iso8601.
|
||||||
|
|
||||||
7.20.03
|
7.20.03
|
||||||
|
|
||||||
Rebranded license SKU `1010470004` from `Gemini Education` to `Google AI Pro for Education`.
|
Rebranded license SKU `1010470004` from `Gemini Education` to `Google AI Pro for Education`.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ datas += [('gam/contactdelegation-v1.json', '.')]
|
|||||||
datas += [('gam/datastudio-v1.json', '.')]
|
datas += [('gam/datastudio-v1.json', '.')]
|
||||||
datas += [('gam/meet-v2beta.json', '.')]
|
datas += [('gam/meet-v2beta.json', '.')]
|
||||||
datas += [('gam/serviceaccountlookup-v1.json', '.')]
|
datas += [('gam/serviceaccountlookup-v1.json', '.')]
|
||||||
#datas += [('cacerts.pem', '.')]
|
datas += [('cacerts.pem', '.')]
|
||||||
hiddenimports = [
|
hiddenimports = [
|
||||||
'gam.gamlib.yubikey',
|
'gam.gamlib.yubikey',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.20.03'
|
__version__ = '7.20.04'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
#pylint: disable=wrong-import-position
|
#pylint: disable=wrong-import-position
|
||||||
@@ -120,6 +120,10 @@ from google.auth.jwt import Credentials as JWTCredentials
|
|||||||
import google.oauth2.service_account
|
import google.oauth2.service_account
|
||||||
import google_auth_oauthlib.flow
|
import google_auth_oauthlib.flow
|
||||||
import google_auth_httplib2
|
import google_auth_httplib2
|
||||||
|
import googleapiclient
|
||||||
|
import googleapiclient.discovery
|
||||||
|
import googleapiclient.errors
|
||||||
|
import googleapiclient.http
|
||||||
import httplib2
|
import httplib2
|
||||||
|
|
||||||
httplib2.RETRIES = 5
|
httplib2.RETRIES = 5
|
||||||
@@ -139,6 +143,7 @@ from gamlib import glgapi as GAPI
|
|||||||
from gamlib import glgdata as GDATA
|
from gamlib import glgdata as GDATA
|
||||||
from gamlib import glglobals as GM
|
from gamlib import glglobals as GM
|
||||||
from gamlib import glindent
|
from gamlib import glindent
|
||||||
|
from gamlib import gliso8601 as iso8601
|
||||||
from gamlib import glmsgs as Msg
|
from gamlib import glmsgs as Msg
|
||||||
from gamlib import glskus as SKU
|
from gamlib import glskus as SKU
|
||||||
from gamlib import gluprop as UProp
|
from gamlib import gluprop as UProp
|
||||||
@@ -149,12 +154,6 @@ import gdata.apps.audit
|
|||||||
import gdata.apps.audit.service
|
import gdata.apps.audit.service
|
||||||
import gdata.apps.contacts
|
import gdata.apps.contacts
|
||||||
import gdata.apps.contacts.service
|
import gdata.apps.contacts.service
|
||||||
# Import local library, does not include discovery documents
|
|
||||||
import googleapiclient
|
|
||||||
import googleapiclient.discovery
|
|
||||||
import googleapiclient.errors
|
|
||||||
import googleapiclient.http
|
|
||||||
from iso8601 import iso8601
|
|
||||||
|
|
||||||
IS08601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S%:z'
|
IS08601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S%:z'
|
||||||
RFC2822_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S %z'
|
RFC2822_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S %z'
|
||||||
|
|||||||
159
src/gam/gamlib/gliso8601.py
Normal file
159
src/gam/gamlib/gliso8601.py
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""ISO 8601 date time string parsing
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datetime import (datetime, timedelta, tzinfo)
|
||||||
|
import time as _time
|
||||||
|
import re
|
||||||
|
|
||||||
|
ISO8601_REGEX = re.compile(r'^(?P<year>[0-9]{4})-(?P<month>[0-9]{2})-(?P<day>[0-9]{2})(?P<separator>[ T])(?P<hour>[0-9]{2}):(?P<minute>[0-9]{2}):(?P<second>[0-9]{2})([.,](?P<second_fraction>[0-9]+)){0,1}(?P<timezone>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9]{2}):(?P<tz_minute>[0-9]{2}))$')
|
||||||
|
ISO8601_TZ_REGEX = re.compile(r'^(?P<timezone>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9]{2}):(?P<tz_minute>[0-9]{2}))$')
|
||||||
|
|
||||||
|
class ParseError(Exception):
|
||||||
|
"""Raised when there is a problem parsing a date string"""
|
||||||
|
|
||||||
|
# Yoinked from python docs
|
||||||
|
ZERO = timedelta(0)
|
||||||
|
class Utc(tzinfo):
|
||||||
|
"""UTC Timezone
|
||||||
|
|
||||||
|
"""
|
||||||
|
def utcoffset(self, dt):
|
||||||
|
return ZERO
|
||||||
|
|
||||||
|
def tzname(self, dt):
|
||||||
|
return "UTC"
|
||||||
|
|
||||||
|
def dst(self, dt):
|
||||||
|
return ZERO
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<iso8601.Utc>"
|
||||||
|
|
||||||
|
UTC = Utc()
|
||||||
|
|
||||||
|
class FixedOffset(tzinfo):
|
||||||
|
"""Fixed offset in hours and minutes from UTC
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, offset_hours, offset_minutes, name):
|
||||||
|
self.__offset_hours = offset_hours # Keep for later __getinitargs__
|
||||||
|
self.__offset_minutes = offset_minutes # Keep for later __getinitargs__
|
||||||
|
self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes)
|
||||||
|
self.__name = name
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, FixedOffset):
|
||||||
|
return (other.__offset == self.__offset) and (other.__name == self.__name)
|
||||||
|
if isinstance(other, tzinfo):
|
||||||
|
return other == self
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __getinitargs__(self):
|
||||||
|
return (self.__offset_hours, self.__offset_minutes, self.__name)
|
||||||
|
|
||||||
|
def utcoffset(self, dt):
|
||||||
|
return self.__offset
|
||||||
|
|
||||||
|
def tzname(self, dt):
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
def dst(self, dt):
|
||||||
|
return ZERO
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<FixedOffset %r %r>" % (self.__name, self.__offset)
|
||||||
|
|
||||||
|
# A class capturing the platform's idea of local time.
|
||||||
|
|
||||||
|
STDOFFSET = timedelta(seconds = -_time.timezone)
|
||||||
|
if _time.daylight:
|
||||||
|
DSTOFFSET = timedelta(seconds = -_time.altzone)
|
||||||
|
else:
|
||||||
|
DSTOFFSET = STDOFFSET
|
||||||
|
|
||||||
|
DSTDIFF = DSTOFFSET - STDOFFSET
|
||||||
|
|
||||||
|
class LocalTimezone(tzinfo):
|
||||||
|
"""Local time zone
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def utcoffset(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return DSTOFFSET
|
||||||
|
else:
|
||||||
|
return STDOFFSET
|
||||||
|
|
||||||
|
def dst(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return DSTDIFF
|
||||||
|
else:
|
||||||
|
return ZERO
|
||||||
|
|
||||||
|
def tzname(self, dt):
|
||||||
|
return _time.tzname[self._isdst(dt)]
|
||||||
|
|
||||||
|
def _isdst(self, dt):
|
||||||
|
tt = (dt.year, dt.month, dt.day,
|
||||||
|
dt.hour, dt.minute, dt.second,
|
||||||
|
dt.weekday(), 0, 0)
|
||||||
|
stamp = _time.mktime(tt)
|
||||||
|
tt = _time.localtime(stamp)
|
||||||
|
return tt.tm_isdst > 0
|
||||||
|
|
||||||
|
Local = LocalTimezone()
|
||||||
|
|
||||||
|
def parse_timezone(matches):
|
||||||
|
"""Parses ISO 8601 time zone specs into tzinfo offsets
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if matches["timezone"] == "Z":
|
||||||
|
return UTC
|
||||||
|
sign = matches["tz_sign"]
|
||||||
|
hours = int(matches['tz_hour'])
|
||||||
|
minutes = int(matches['tz_minute'])
|
||||||
|
description = "%s%02d:%02d" % (sign, hours, minutes)
|
||||||
|
if sign == "-":
|
||||||
|
hours = -hours
|
||||||
|
minutes = -minutes
|
||||||
|
return FixedOffset(hours, minutes, description)
|
||||||
|
|
||||||
|
def parse_timezone_str(tzstring):
|
||||||
|
m = ISO8601_TZ_REGEX.match(tzstring)
|
||||||
|
if not m:
|
||||||
|
raise ParseError("Unable to parse timezone string %r" % tzstring)
|
||||||
|
groups = m.groupdict()
|
||||||
|
return parse_timezone(groups)
|
||||||
|
|
||||||
|
def parse_date(datestring):
|
||||||
|
"""Parses ISO 8601 dates into datetime objects
|
||||||
|
|
||||||
|
The timezone is parsed from the date string. However it is quite common to
|
||||||
|
have dates without a timezone (not strictly correct). In this case the
|
||||||
|
default timezone specified in default_timezone is used. This is UTC by
|
||||||
|
default.
|
||||||
|
|
||||||
|
:param datestring: The date to parse as a string
|
||||||
|
:returns: A datetime.datetime instance
|
||||||
|
:raises: ParseError when there is a problem parsing the date or
|
||||||
|
constructing the datetime instance.
|
||||||
|
|
||||||
|
"""
|
||||||
|
m = ISO8601_REGEX.match(datestring)
|
||||||
|
if not m:
|
||||||
|
raise ParseError("Unable to parse date string %r" % datestring)
|
||||||
|
groups = m.groupdict()
|
||||||
|
tz = parse_timezone(groups)
|
||||||
|
try:
|
||||||
|
return datetime(year=int(groups['year']),
|
||||||
|
month=int(groups['month']),
|
||||||
|
day=int(groups['day']),
|
||||||
|
hour=int(groups['hour']),
|
||||||
|
minute=int(groups['minute']),
|
||||||
|
second=int(groups['second']),
|
||||||
|
tzinfo=tz)
|
||||||
|
except Exception as e:
|
||||||
|
raise ParseError(e)
|
||||||
Reference in New Issue
Block a user