mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-07 10:33:38 +00:00
Merge pull request #617 from JackDandy/feature/UpdateDateutil
Update dateutil library 2.4.2 (083f666) to 2.4.2 (d4baf97).
This commit is contained in:
commit
d32327576e
10 changed files with 497 additions and 289 deletions
|
@ -11,6 +11,7 @@
|
||||||
* Update cachecontrol library 0.11.2 to 0.11.5
|
* Update cachecontrol library 0.11.2 to 0.11.5
|
||||||
* Update Certifi to 2015.11.20.1 (385476b)
|
* Update Certifi to 2015.11.20.1 (385476b)
|
||||||
* Update chardet packages 2.3.0 (26982c5) to 2.3.0 (d7fae98)
|
* Update chardet packages 2.3.0 (26982c5) to 2.3.0 (d7fae98)
|
||||||
|
* Update dateutil library 2.4.2 (083f666) to 2.4.2 (d4baf97)
|
||||||
|
|
||||||
|
|
||||||
### 0.11.0 (2016-01-10 22:30:00 UTC)
|
### 0.11.0 (2016-01-10 22:30:00 UTC)
|
||||||
|
|
|
@ -71,12 +71,6 @@ class _timelex(object):
|
||||||
instream = StringIO(instream)
|
instream = StringIO(instream)
|
||||||
|
|
||||||
self.instream = instream
|
self.instream = instream
|
||||||
self.wordchars = ('abcdfeghijklmnopqrstuvwxyz'
|
|
||||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
|
|
||||||
'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
|
|
||||||
'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ')
|
|
||||||
self.numchars = '0123456789'
|
|
||||||
self.whitespace = ' \t\r\n'
|
|
||||||
self.charstack = []
|
self.charstack = []
|
||||||
self.tokenstack = []
|
self.tokenstack = []
|
||||||
self.eof = False
|
self.eof = False
|
||||||
|
@ -101,9 +95,6 @@ class _timelex(object):
|
||||||
seenletters = False
|
seenletters = False
|
||||||
token = None
|
token = None
|
||||||
state = None
|
state = None
|
||||||
wordchars = self.wordchars
|
|
||||||
numchars = self.numchars
|
|
||||||
whitespace = self.whitespace
|
|
||||||
|
|
||||||
while not self.eof:
|
while not self.eof:
|
||||||
# We only realize that we've reached the end of a token when we
|
# We only realize that we've reached the end of a token when we
|
||||||
|
@ -124,11 +115,11 @@ class _timelex(object):
|
||||||
# First character of the token - determines if we're starting
|
# First character of the token - determines if we're starting
|
||||||
# to parse a word, a number or something else.
|
# to parse a word, a number or something else.
|
||||||
token = nextchar
|
token = nextchar
|
||||||
if nextchar in wordchars:
|
if self.isword(nextchar):
|
||||||
state = 'a'
|
state = 'a'
|
||||||
elif nextchar in numchars:
|
elif self.isnum(nextchar):
|
||||||
state = '0'
|
state = '0'
|
||||||
elif nextchar in whitespace:
|
elif self.isspace(nextchar):
|
||||||
token = ' '
|
token = ' '
|
||||||
break # emit token
|
break # emit token
|
||||||
else:
|
else:
|
||||||
|
@ -137,7 +128,7 @@ class _timelex(object):
|
||||||
# If we've already started reading a word, we keep reading
|
# If we've already started reading a word, we keep reading
|
||||||
# letters until we find something that's not part of a word.
|
# letters until we find something that's not part of a word.
|
||||||
seenletters = True
|
seenletters = True
|
||||||
if nextchar in wordchars:
|
if self.isword(nextchar):
|
||||||
token += nextchar
|
token += nextchar
|
||||||
elif nextchar == '.':
|
elif nextchar == '.':
|
||||||
token += nextchar
|
token += nextchar
|
||||||
|
@ -148,7 +139,7 @@ class _timelex(object):
|
||||||
elif state == '0':
|
elif state == '0':
|
||||||
# If we've already started reading a number, we keep reading
|
# If we've already started reading a number, we keep reading
|
||||||
# numbers until we find something that doesn't fit.
|
# numbers until we find something that doesn't fit.
|
||||||
if nextchar in numchars:
|
if self.isnum(nextchar):
|
||||||
token += nextchar
|
token += nextchar
|
||||||
elif nextchar == '.' or (nextchar == ',' and len(token) >= 2):
|
elif nextchar == '.' or (nextchar == ',' and len(token) >= 2):
|
||||||
token += nextchar
|
token += nextchar
|
||||||
|
@ -160,9 +151,9 @@ class _timelex(object):
|
||||||
# If we've seen some letters and a dot separator, continue
|
# If we've seen some letters and a dot separator, continue
|
||||||
# parsing, and the tokens will be broken up later.
|
# parsing, and the tokens will be broken up later.
|
||||||
seenletters = True
|
seenletters = True
|
||||||
if nextchar == '.' or nextchar in wordchars:
|
if nextchar == '.' or self.isword(nextchar):
|
||||||
token += nextchar
|
token += nextchar
|
||||||
elif nextchar in numchars and token[-1] == '.':
|
elif self.isnum(nextchar) and token[-1] == '.':
|
||||||
token += nextchar
|
token += nextchar
|
||||||
state = '0.'
|
state = '0.'
|
||||||
else:
|
else:
|
||||||
|
@ -171,9 +162,9 @@ class _timelex(object):
|
||||||
elif state == '0.':
|
elif state == '0.':
|
||||||
# If we've seen at least one dot separator, keep going, we'll
|
# If we've seen at least one dot separator, keep going, we'll
|
||||||
# break up the tokens later.
|
# break up the tokens later.
|
||||||
if nextchar == '.' or nextchar in numchars:
|
if nextchar == '.' or self.isnum(nextchar):
|
||||||
token += nextchar
|
token += nextchar
|
||||||
elif nextchar in wordchars and token[-1] == '.':
|
elif self.isword(nextchar) and token[-1] == '.':
|
||||||
token += nextchar
|
token += nextchar
|
||||||
state = 'a.'
|
state = 'a.'
|
||||||
else:
|
else:
|
||||||
|
@ -206,9 +197,24 @@ class _timelex(object):
|
||||||
def next(self):
|
def next(self):
|
||||||
return self.__next__() # Python 2.x support
|
return self.__next__() # Python 2.x support
|
||||||
|
|
||||||
|
@classmethod
|
||||||
def split(cls, s):
|
def split(cls, s):
|
||||||
return list(cls(s))
|
return list(cls(s))
|
||||||
split = classmethod(split)
|
|
||||||
|
@classmethod
|
||||||
|
def isword(cls, nextchar):
|
||||||
|
""" Whether or not the next character is part of a word """
|
||||||
|
return nextchar.isalpha()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def isnum(cls, nextchar):
|
||||||
|
""" Whether the next character is part of a number """
|
||||||
|
return nextchar.isdigit()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def isspace(cls, nextchar):
|
||||||
|
""" Whether the next character is whitespace """
|
||||||
|
return nextchar.isspace()
|
||||||
|
|
||||||
|
|
||||||
class _resultbase(object):
|
class _resultbase(object):
|
||||||
|
@ -462,7 +468,7 @@ class parser(object):
|
||||||
:class:`tzinfo` is not in a valid format, or if an invalid date
|
:class:`tzinfo` is not in a valid format, or if an invalid date
|
||||||
would be created.
|
would be created.
|
||||||
|
|
||||||
:raises OverFlowError:
|
:raises OverflowError:
|
||||||
Raised if the parsed date exceeds the largest valid C integer on
|
Raised if the parsed date exceeds the largest valid C integer on
|
||||||
your system.
|
your system.
|
||||||
"""
|
"""
|
||||||
|
@ -643,7 +649,7 @@ class parser(object):
|
||||||
|
|
||||||
>>> from dateutil.parser import parse
|
>>> from dateutil.parser import parse
|
||||||
>>> parse("Today is January 1, 2047 at 8:21:00AM", fuzzy_with_tokens=True)
|
>>> parse("Today is January 1, 2047 at 8:21:00AM", fuzzy_with_tokens=True)
|
||||||
(datetime.datetime(2011, 1, 1, 8, 21), (u'Today is ', u' ', u'at '))
|
(datetime.datetime(2047, 1, 1, 8, 21), (u'Today is ', u' ', u'at '))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fuzzy_with_tokens:
|
if fuzzy_with_tokens:
|
||||||
|
@ -1202,7 +1208,7 @@ def parse(timestr, parserinfo=None, **kwargs):
|
||||||
:class:`tzinfo` is not in a valid format, or if an invalid date
|
:class:`tzinfo` is not in a valid format, or if an invalid date
|
||||||
would be created.
|
would be created.
|
||||||
|
|
||||||
:raises OverFlowError:
|
:raises OverflowError:
|
||||||
Raised if the parsed date exceeds the largest valid C integer on
|
Raised if the parsed date exceeds the largest valid C integer on
|
||||||
your system.
|
your system.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -40,75 +40,75 @@ MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)])
|
||||||
|
|
||||||
class relativedelta(object):
|
class relativedelta(object):
|
||||||
"""
|
"""
|
||||||
The relativedelta type is based on the specification of the excellent
|
The relativedelta type is based on the specification of the excellent
|
||||||
work done by M.-A. Lemburg in his
|
work done by M.-A. Lemburg in his
|
||||||
`mx.DateTime <http://www.egenix.com/files/python/mxDateTime.html>`_ extension.
|
`mx.DateTime <http://www.egenix.com/files/python/mxDateTime.html>`_ extension.
|
||||||
However, notice that this type does *NOT* implement the same algorithm as
|
However, notice that this type does *NOT* implement the same algorithm as
|
||||||
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
|
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
|
||||||
|
|
||||||
There are two different ways to build a relativedelta instance. The
|
There are two different ways to build a relativedelta instance. The
|
||||||
first one is passing it two date/datetime classes::
|
first one is passing it two date/datetime classes::
|
||||||
|
|
||||||
relativedelta(datetime1, datetime2)
|
relativedelta(datetime1, datetime2)
|
||||||
|
|
||||||
The second one is passing it any number of the following keyword arguments::
|
The second one is passing it any number of the following keyword arguments::
|
||||||
|
|
||||||
relativedelta(arg1=x,arg2=y,arg3=z...)
|
relativedelta(arg1=x,arg2=y,arg3=z...)
|
||||||
|
|
||||||
year, month, day, hour, minute, second, microsecond:
|
year, month, day, hour, minute, second, microsecond:
|
||||||
Absolute information (argument is singular); adding or subtracting a
|
Absolute information (argument is singular); adding or subtracting a
|
||||||
relativedelta with absolute information does not perform an aritmetic
|
relativedelta with absolute information does not perform an aritmetic
|
||||||
operation, but rather REPLACES the corresponding value in the
|
operation, but rather REPLACES the corresponding value in the
|
||||||
original datetime with the value(s) in relativedelta.
|
original datetime with the value(s) in relativedelta.
|
||||||
|
|
||||||
years, months, weeks, days, hours, minutes, seconds, microseconds:
|
years, months, weeks, days, hours, minutes, seconds, microseconds:
|
||||||
Relative information, may be negative (argument is plural); adding
|
Relative information, may be negative (argument is plural); adding
|
||||||
or subtracting a relativedelta with relative information performs
|
or subtracting a relativedelta with relative information performs
|
||||||
the corresponding aritmetic operation on the original datetime value
|
the corresponding aritmetic operation on the original datetime value
|
||||||
with the information in the relativedelta.
|
with the information in the relativedelta.
|
||||||
|
|
||||||
weekday:
|
weekday:
|
||||||
One of the weekday instances (MO, TU, etc). These instances may
|
One of the weekday instances (MO, TU, etc). These instances may
|
||||||
receive a parameter N, specifying the Nth weekday, which could
|
receive a parameter N, specifying the Nth weekday, which could
|
||||||
be positive or negative (like MO(+1) or MO(-2). Not specifying
|
be positive or negative (like MO(+1) or MO(-2). Not specifying
|
||||||
it is the same as specifying +1. You can also use an integer,
|
it is the same as specifying +1. You can also use an integer,
|
||||||
where 0=MO.
|
where 0=MO.
|
||||||
|
|
||||||
leapdays:
|
leapdays:
|
||||||
Will add given days to the date found, if year is a leap
|
Will add given days to the date found, if year is a leap
|
||||||
year, and the date found is post 28 of february.
|
year, and the date found is post 28 of february.
|
||||||
|
|
||||||
yearday, nlyearday:
|
yearday, nlyearday:
|
||||||
Set the yearday or the non-leap year day (jump leap days).
|
Set the yearday or the non-leap year day (jump leap days).
|
||||||
These are converted to day/month/leapdays information.
|
These are converted to day/month/leapdays information.
|
||||||
|
|
||||||
Here is the behavior of operations with relativedelta:
|
Here is the behavior of operations with relativedelta:
|
||||||
|
|
||||||
1. Calculate the absolute year, using the 'year' argument, or the
|
1. Calculate the absolute year, using the 'year' argument, or the
|
||||||
original datetime year, if the argument is not present.
|
original datetime year, if the argument is not present.
|
||||||
|
|
||||||
2. Add the relative 'years' argument to the absolute year.
|
2. Add the relative 'years' argument to the absolute year.
|
||||||
|
|
||||||
3. Do steps 1 and 2 for month/months.
|
3. Do steps 1 and 2 for month/months.
|
||||||
|
|
||||||
4. Calculate the absolute day, using the 'day' argument, or the
|
4. Calculate the absolute day, using the 'day' argument, or the
|
||||||
original datetime day, if the argument is not present. Then,
|
original datetime day, if the argument is not present. Then,
|
||||||
subtract from the day until it fits in the year and month
|
subtract from the day until it fits in the year and month
|
||||||
found after their operations.
|
found after their operations.
|
||||||
|
|
||||||
5. Add the relative 'days' argument to the absolute day. Notice
|
5. Add the relative 'days' argument to the absolute day. Notice
|
||||||
that the 'weeks' argument is multiplied by 7 and added to
|
that the 'weeks' argument is multiplied by 7 and added to
|
||||||
'days'.
|
'days'.
|
||||||
|
|
||||||
6. Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
|
6. Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
|
||||||
microsecond/microseconds.
|
microsecond/microseconds.
|
||||||
|
|
||||||
7. If the 'weekday' argument is present, calculate the weekday,
|
7. If the 'weekday' argument is present, calculate the weekday,
|
||||||
with the given (wday, nth) tuple. wday is the index of the
|
with the given (wday, nth) tuple. wday is the index of the
|
||||||
weekday (0-6, 0=Mon), and nth is the number of weeks to add
|
weekday (0-6, 0=Mon), and nth is the number of weeks to add
|
||||||
forward or backward, depending on its signal. Notice that if
|
forward or backward, depending on its signal. Notice that if
|
||||||
the calculated date is already Monday, for example, using
|
the calculated date is already Monday, for example, using
|
||||||
(0, 1) or (0, -1) won't change the day.
|
(0, 1) or (0, -1) won't change the day.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, dt1=None, dt2=None,
|
def __init__(self, dt1=None, dt2=None,
|
||||||
|
|
|
@ -10,7 +10,10 @@ import datetime
|
||||||
import calendar
|
import calendar
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from fractions import gcd
|
try:
|
||||||
|
from math import gcd
|
||||||
|
except ImportError:
|
||||||
|
from fractions import gcd
|
||||||
|
|
||||||
from six import advance_iterator, integer_types
|
from six import advance_iterator, integer_types
|
||||||
from six.moves import _thread
|
from six.moves import _thread
|
||||||
|
|
20
lib/dateutil/tz/__init__.py
Normal file
20
lib/dateutil/tz/__init__.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from .tz import *
|
||||||
|
from six import PY3
|
||||||
|
|
||||||
|
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
|
||||||
|
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]
|
||||||
|
|
||||||
|
def tzname_in_python2(namefunc):
|
||||||
|
"""Change unicode output into bytestrings in Python 2
|
||||||
|
|
||||||
|
tzname() API changed in Python 3. It used to return bytes, but was changed
|
||||||
|
to unicode strings
|
||||||
|
"""
|
||||||
|
def adjust_encoding(*args, **kwargs):
|
||||||
|
name = namefunc(*args, **kwargs)
|
||||||
|
if name is not None and not PY3:
|
||||||
|
name = name.encode()
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
return adjust_encoding
|
|
@ -14,9 +14,10 @@ import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from six import string_types, PY3
|
from six import string_types, PY3
|
||||||
|
from .__init__ import tzname_in_python2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from dateutil.tzwin import tzwin, tzwinlocal
|
from .win import tzwin, tzwinlocal
|
||||||
except ImportError:
|
except ImportError:
|
||||||
tzwin = tzwinlocal = None
|
tzwin = tzwinlocal = None
|
||||||
|
|
||||||
|
@ -24,29 +25,9 @@ relativedelta = None
|
||||||
parser = None
|
parser = None
|
||||||
rrule = None
|
rrule = None
|
||||||
|
|
||||||
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
|
|
||||||
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]
|
|
||||||
|
|
||||||
|
|
||||||
def tzname_in_python2(namefunc):
|
|
||||||
"""Change unicode output into bytestrings in Python 2
|
|
||||||
|
|
||||||
tzname() API changed in Python 3. It used to return bytes, but was changed
|
|
||||||
to unicode strings
|
|
||||||
"""
|
|
||||||
def adjust_encoding(*args, **kwargs):
|
|
||||||
name = namefunc(*args, **kwargs)
|
|
||||||
if name is not None and not PY3:
|
|
||||||
name = name.encode()
|
|
||||||
|
|
||||||
return name
|
|
||||||
|
|
||||||
return adjust_encoding
|
|
||||||
|
|
||||||
ZERO = datetime.timedelta(0)
|
ZERO = datetime.timedelta(0)
|
||||||
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
|
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()
|
||||||
|
|
||||||
|
|
||||||
class tzutc(datetime.tzinfo):
|
class tzutc(datetime.tzinfo):
|
||||||
|
|
||||||
def utcoffset(self, dt):
|
def utcoffset(self, dt):
|
187
lib/dateutil/tz/tzwin.py
Normal file
187
lib/dateutil/tz/tzwin.py
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
# This code was originally contributed by Jeffrey Harris.
|
||||||
|
import datetime
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from six.moves import winreg
|
||||||
|
|
||||||
|
from .__init__ import tzname_in_python2
|
||||||
|
|
||||||
|
__all__ = ["tzwin", "tzwinlocal"]
|
||||||
|
|
||||||
|
ONEWEEK = datetime.timedelta(7)
|
||||||
|
|
||||||
|
TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
|
||||||
|
TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
|
||||||
|
TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
|
||||||
|
|
||||||
|
|
||||||
|
def _settzkeyname():
|
||||||
|
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||||
|
try:
|
||||||
|
winreg.OpenKey(handle, TZKEYNAMENT).Close()
|
||||||
|
TZKEYNAME = TZKEYNAMENT
|
||||||
|
except WindowsError:
|
||||||
|
TZKEYNAME = TZKEYNAME9X
|
||||||
|
handle.Close()
|
||||||
|
return TZKEYNAME
|
||||||
|
|
||||||
|
TZKEYNAME = _settzkeyname()
|
||||||
|
|
||||||
|
|
||||||
|
class tzwinbase(datetime.tzinfo):
|
||||||
|
"""tzinfo class based on win32's timezones available in the registry."""
|
||||||
|
|
||||||
|
def utcoffset(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return datetime.timedelta(minutes=self._dstoffset)
|
||||||
|
else:
|
||||||
|
return datetime.timedelta(minutes=self._stdoffset)
|
||||||
|
|
||||||
|
def dst(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
minutes = self._dstoffset - self._stdoffset
|
||||||
|
return datetime.timedelta(minutes=minutes)
|
||||||
|
else:
|
||||||
|
return datetime.timedelta(0)
|
||||||
|
|
||||||
|
@tzname_in_python2
|
||||||
|
def tzname(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return self._dstname
|
||||||
|
else:
|
||||||
|
return self._stdname
|
||||||
|
|
||||||
|
def list():
|
||||||
|
"""Return a list of all time zones known to the system."""
|
||||||
|
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||||
|
tzkey = winreg.OpenKey(handle, TZKEYNAME)
|
||||||
|
result = [winreg.EnumKey(tzkey, i)
|
||||||
|
for i in range(winreg.QueryInfoKey(tzkey)[0])]
|
||||||
|
tzkey.Close()
|
||||||
|
handle.Close()
|
||||||
|
return result
|
||||||
|
list = staticmethod(list)
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
return self._display
|
||||||
|
|
||||||
|
def _isdst(self, dt):
|
||||||
|
if not self._dstmonth:
|
||||||
|
# dstmonth == 0 signals the zone has no daylight saving time
|
||||||
|
return False
|
||||||
|
dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek,
|
||||||
|
self._dsthour, self._dstminute,
|
||||||
|
self._dstweeknumber)
|
||||||
|
dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek,
|
||||||
|
self._stdhour, self._stdminute,
|
||||||
|
self._stdweeknumber)
|
||||||
|
if dston < dstoff:
|
||||||
|
return dston <= dt.replace(tzinfo=None) < dstoff
|
||||||
|
else:
|
||||||
|
return not dstoff <= dt.replace(tzinfo=None) < dston
|
||||||
|
|
||||||
|
|
||||||
|
class tzwin(tzwinbase):
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
# multiple contexts only possible in 2.7 and 3.1, we still support 2.6
|
||||||
|
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||||
|
with winreg.OpenKey(handle,
|
||||||
|
"%s\%s" % (TZKEYNAME, name)) as tzkey:
|
||||||
|
keydict = valuestodict(tzkey)
|
||||||
|
|
||||||
|
self._stdname = keydict["Std"]
|
||||||
|
self._dstname = keydict["Dlt"]
|
||||||
|
|
||||||
|
self._display = keydict["Display"]
|
||||||
|
|
||||||
|
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
||||||
|
tup = struct.unpack("=3l16h", keydict["TZI"])
|
||||||
|
self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1
|
||||||
|
self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1
|
||||||
|
|
||||||
|
# for the meaning see the win32 TIME_ZONE_INFORMATION structure docs
|
||||||
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
|
||||||
|
(self._stdmonth,
|
||||||
|
self._stddayofweek, # Sunday = 0
|
||||||
|
self._stdweeknumber, # Last = 5
|
||||||
|
self._stdhour,
|
||||||
|
self._stdminute) = tup[4:9]
|
||||||
|
|
||||||
|
(self._dstmonth,
|
||||||
|
self._dstdayofweek, # Sunday = 0
|
||||||
|
self._dstweeknumber, # Last = 5
|
||||||
|
self._dsthour,
|
||||||
|
self._dstminute) = tup[12:17]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "tzwin(%s)" % repr(self._name)
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return (self.__class__, (self._name,))
|
||||||
|
|
||||||
|
|
||||||
|
class tzwinlocal(tzwinbase):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||||
|
|
||||||
|
with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
|
||||||
|
keydict = valuestodict(tzlocalkey)
|
||||||
|
|
||||||
|
self._stdname = keydict["StandardName"]
|
||||||
|
self._dstname = keydict["DaylightName"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with winreg.OpenKey(
|
||||||
|
handle, "%s\%s" % (TZKEYNAME, self._stdname)) as tzkey:
|
||||||
|
_keydict = valuestodict(tzkey)
|
||||||
|
self._display = _keydict["Display"]
|
||||||
|
except OSError:
|
||||||
|
self._display = None
|
||||||
|
|
||||||
|
self._stdoffset = -keydict["Bias"]-keydict["StandardBias"]
|
||||||
|
self._dstoffset = self._stdoffset-keydict["DaylightBias"]
|
||||||
|
|
||||||
|
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
||||||
|
tup = struct.unpack("=8h", keydict["StandardStart"])
|
||||||
|
|
||||||
|
(self._stdmonth,
|
||||||
|
self._stddayofweek, # Sunday = 0
|
||||||
|
self._stdweeknumber, # Last = 5
|
||||||
|
self._stdhour,
|
||||||
|
self._stdminute) = tup[1:6]
|
||||||
|
|
||||||
|
tup = struct.unpack("=8h", keydict["DaylightStart"])
|
||||||
|
|
||||||
|
(self._dstmonth,
|
||||||
|
self._dstdayofweek, # Sunday = 0
|
||||||
|
self._dstweeknumber, # Last = 5
|
||||||
|
self._dsthour,
|
||||||
|
self._dstminute) = tup[1:6]
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return (self.__class__, ())
|
||||||
|
|
||||||
|
|
||||||
|
def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
|
||||||
|
"""dayofweek == 0 means Sunday, whichweek 5 means last instance"""
|
||||||
|
first = datetime.datetime(year, month, 1, hour, minute)
|
||||||
|
weekdayone = first.replace(day=((dayofweek-first.isoweekday()) % 7+1))
|
||||||
|
for n in range(whichweek):
|
||||||
|
dt = weekdayone+(whichweek-n)*ONEWEEK
|
||||||
|
if dt.month == month:
|
||||||
|
return dt
|
||||||
|
|
||||||
|
|
||||||
|
def valuestodict(key):
|
||||||
|
"""Convert a registry key's values to a dictionary."""
|
||||||
|
dict = {}
|
||||||
|
size = winreg.QueryInfoKey(key)[1]
|
||||||
|
for i in range(size):
|
||||||
|
data = winreg.EnumValue(key, i)
|
||||||
|
dict[data[0]] = data[1]
|
||||||
|
return dict
|
187
lib/dateutil/tz/win.py
Normal file
187
lib/dateutil/tz/win.py
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
# This code was originally contributed by Jeffrey Harris.
|
||||||
|
import datetime
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from six.moves import winreg
|
||||||
|
|
||||||
|
from .__init__ import tzname_in_python2
|
||||||
|
|
||||||
|
__all__ = ["tzwin", "tzwinlocal"]
|
||||||
|
|
||||||
|
ONEWEEK = datetime.timedelta(7)
|
||||||
|
|
||||||
|
TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
|
||||||
|
TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
|
||||||
|
TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
|
||||||
|
|
||||||
|
|
||||||
|
def _settzkeyname():
|
||||||
|
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||||
|
try:
|
||||||
|
winreg.OpenKey(handle, TZKEYNAMENT).Close()
|
||||||
|
TZKEYNAME = TZKEYNAMENT
|
||||||
|
except WindowsError:
|
||||||
|
TZKEYNAME = TZKEYNAME9X
|
||||||
|
handle.Close()
|
||||||
|
return TZKEYNAME
|
||||||
|
|
||||||
|
TZKEYNAME = _settzkeyname()
|
||||||
|
|
||||||
|
|
||||||
|
class tzwinbase(datetime.tzinfo):
|
||||||
|
"""tzinfo class based on win32's timezones available in the registry."""
|
||||||
|
|
||||||
|
def utcoffset(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return datetime.timedelta(minutes=self._dstoffset)
|
||||||
|
else:
|
||||||
|
return datetime.timedelta(minutes=self._stdoffset)
|
||||||
|
|
||||||
|
def dst(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
minutes = self._dstoffset - self._stdoffset
|
||||||
|
return datetime.timedelta(minutes=minutes)
|
||||||
|
else:
|
||||||
|
return datetime.timedelta(0)
|
||||||
|
|
||||||
|
@tzname_in_python2
|
||||||
|
def tzname(self, dt):
|
||||||
|
if self._isdst(dt):
|
||||||
|
return self._dstname
|
||||||
|
else:
|
||||||
|
return self._stdname
|
||||||
|
|
||||||
|
def list():
|
||||||
|
"""Return a list of all time zones known to the system."""
|
||||||
|
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||||
|
tzkey = winreg.OpenKey(handle, TZKEYNAME)
|
||||||
|
result = [winreg.EnumKey(tzkey, i)
|
||||||
|
for i in range(winreg.QueryInfoKey(tzkey)[0])]
|
||||||
|
tzkey.Close()
|
||||||
|
handle.Close()
|
||||||
|
return result
|
||||||
|
list = staticmethod(list)
|
||||||
|
|
||||||
|
def display(self):
|
||||||
|
return self._display
|
||||||
|
|
||||||
|
def _isdst(self, dt):
|
||||||
|
if not self._dstmonth:
|
||||||
|
# dstmonth == 0 signals the zone has no daylight saving time
|
||||||
|
return False
|
||||||
|
dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek,
|
||||||
|
self._dsthour, self._dstminute,
|
||||||
|
self._dstweeknumber)
|
||||||
|
dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek,
|
||||||
|
self._stdhour, self._stdminute,
|
||||||
|
self._stdweeknumber)
|
||||||
|
if dston < dstoff:
|
||||||
|
return dston <= dt.replace(tzinfo=None) < dstoff
|
||||||
|
else:
|
||||||
|
return not dstoff <= dt.replace(tzinfo=None) < dston
|
||||||
|
|
||||||
|
|
||||||
|
class tzwin(tzwinbase):
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
# multiple contexts only possible in 2.7 and 3.1, we still support 2.6
|
||||||
|
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||||
|
with winreg.OpenKey(handle,
|
||||||
|
"%s\%s" % (TZKEYNAME, name)) as tzkey:
|
||||||
|
keydict = valuestodict(tzkey)
|
||||||
|
|
||||||
|
self._stdname = keydict["Std"]
|
||||||
|
self._dstname = keydict["Dlt"]
|
||||||
|
|
||||||
|
self._display = keydict["Display"]
|
||||||
|
|
||||||
|
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
||||||
|
tup = struct.unpack("=3l16h", keydict["TZI"])
|
||||||
|
self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1
|
||||||
|
self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1
|
||||||
|
|
||||||
|
# for the meaning see the win32 TIME_ZONE_INFORMATION structure docs
|
||||||
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
|
||||||
|
(self._stdmonth,
|
||||||
|
self._stddayofweek, # Sunday = 0
|
||||||
|
self._stdweeknumber, # Last = 5
|
||||||
|
self._stdhour,
|
||||||
|
self._stdminute) = tup[4:9]
|
||||||
|
|
||||||
|
(self._dstmonth,
|
||||||
|
self._dstdayofweek, # Sunday = 0
|
||||||
|
self._dstweeknumber, # Last = 5
|
||||||
|
self._dsthour,
|
||||||
|
self._dstminute) = tup[12:17]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "tzwin(%s)" % repr(self._name)
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return (self.__class__, (self._name,))
|
||||||
|
|
||||||
|
|
||||||
|
class tzwinlocal(tzwinbase):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||||
|
|
||||||
|
with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
|
||||||
|
keydict = valuestodict(tzlocalkey)
|
||||||
|
|
||||||
|
self._stdname = keydict["StandardName"]
|
||||||
|
self._dstname = keydict["DaylightName"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with winreg.OpenKey(
|
||||||
|
handle, "%s\%s" % (TZKEYNAME, self._stdname)) as tzkey:
|
||||||
|
_keydict = valuestodict(tzkey)
|
||||||
|
self._display = _keydict["Display"]
|
||||||
|
except OSError:
|
||||||
|
self._display = None
|
||||||
|
|
||||||
|
self._stdoffset = -keydict["Bias"]-keydict["StandardBias"]
|
||||||
|
self._dstoffset = self._stdoffset-keydict["DaylightBias"]
|
||||||
|
|
||||||
|
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
||||||
|
tup = struct.unpack("=8h", keydict["StandardStart"])
|
||||||
|
|
||||||
|
(self._stdmonth,
|
||||||
|
self._stddayofweek, # Sunday = 0
|
||||||
|
self._stdweeknumber, # Last = 5
|
||||||
|
self._stdhour,
|
||||||
|
self._stdminute) = tup[1:6]
|
||||||
|
|
||||||
|
tup = struct.unpack("=8h", keydict["DaylightStart"])
|
||||||
|
|
||||||
|
(self._dstmonth,
|
||||||
|
self._dstdayofweek, # Sunday = 0
|
||||||
|
self._dstweeknumber, # Last = 5
|
||||||
|
self._dsthour,
|
||||||
|
self._dstminute) = tup[1:6]
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return (self.__class__, ())
|
||||||
|
|
||||||
|
|
||||||
|
def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
|
||||||
|
"""dayofweek == 0 means Sunday, whichweek 5 means last instance"""
|
||||||
|
first = datetime.datetime(year, month, 1, hour, minute)
|
||||||
|
weekdayone = first.replace(day=((dayofweek-first.isoweekday()) % 7+1))
|
||||||
|
for n in range(whichweek):
|
||||||
|
dt = weekdayone+(whichweek-n)*ONEWEEK
|
||||||
|
if dt.month == month:
|
||||||
|
return dt
|
||||||
|
|
||||||
|
|
||||||
|
def valuestodict(key):
|
||||||
|
"""Convert a registry key's values to a dictionary."""
|
||||||
|
dict = {}
|
||||||
|
size = winreg.QueryInfoKey(key)[1]
|
||||||
|
for i in range(size):
|
||||||
|
data = winreg.EnumValue(key, i)
|
||||||
|
dict[data[0]] = data[1]
|
||||||
|
return dict
|
|
@ -1,187 +1,2 @@
|
||||||
# This code was originally contributed by Jeffrey Harris.
|
# tzwin has moved to dateutil.tz.win
|
||||||
import datetime
|
from .tz.win import *
|
||||||
import struct
|
|
||||||
|
|
||||||
from six.moves import winreg
|
|
||||||
|
|
||||||
from .tz import tzname_in_python2
|
|
||||||
|
|
||||||
__all__ = ["tzwin", "tzwinlocal"]
|
|
||||||
|
|
||||||
ONEWEEK = datetime.timedelta(7)
|
|
||||||
|
|
||||||
TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
|
|
||||||
TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
|
|
||||||
TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
|
|
||||||
|
|
||||||
|
|
||||||
def _settzkeyname():
|
|
||||||
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
|
||||||
try:
|
|
||||||
winreg.OpenKey(handle, TZKEYNAMENT).Close()
|
|
||||||
TZKEYNAME = TZKEYNAMENT
|
|
||||||
except WindowsError:
|
|
||||||
TZKEYNAME = TZKEYNAME9X
|
|
||||||
handle.Close()
|
|
||||||
return TZKEYNAME
|
|
||||||
|
|
||||||
TZKEYNAME = _settzkeyname()
|
|
||||||
|
|
||||||
|
|
||||||
class tzwinbase(datetime.tzinfo):
|
|
||||||
"""tzinfo class based on win32's timezones available in the registry."""
|
|
||||||
|
|
||||||
def utcoffset(self, dt):
|
|
||||||
if self._isdst(dt):
|
|
||||||
return datetime.timedelta(minutes=self._dstoffset)
|
|
||||||
else:
|
|
||||||
return datetime.timedelta(minutes=self._stdoffset)
|
|
||||||
|
|
||||||
def dst(self, dt):
|
|
||||||
if self._isdst(dt):
|
|
||||||
minutes = self._dstoffset - self._stdoffset
|
|
||||||
return datetime.timedelta(minutes=minutes)
|
|
||||||
else:
|
|
||||||
return datetime.timedelta(0)
|
|
||||||
|
|
||||||
@tzname_in_python2
|
|
||||||
def tzname(self, dt):
|
|
||||||
if self._isdst(dt):
|
|
||||||
return self._dstname
|
|
||||||
else:
|
|
||||||
return self._stdname
|
|
||||||
|
|
||||||
def list():
|
|
||||||
"""Return a list of all time zones known to the system."""
|
|
||||||
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
|
||||||
tzkey = winreg.OpenKey(handle, TZKEYNAME)
|
|
||||||
result = [winreg.EnumKey(tzkey, i)
|
|
||||||
for i in range(winreg.QueryInfoKey(tzkey)[0])]
|
|
||||||
tzkey.Close()
|
|
||||||
handle.Close()
|
|
||||||
return result
|
|
||||||
list = staticmethod(list)
|
|
||||||
|
|
||||||
def display(self):
|
|
||||||
return self._display
|
|
||||||
|
|
||||||
def _isdst(self, dt):
|
|
||||||
if not self._dstmonth:
|
|
||||||
# dstmonth == 0 signals the zone has no daylight saving time
|
|
||||||
return False
|
|
||||||
dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek,
|
|
||||||
self._dsthour, self._dstminute,
|
|
||||||
self._dstweeknumber)
|
|
||||||
dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek,
|
|
||||||
self._stdhour, self._stdminute,
|
|
||||||
self._stdweeknumber)
|
|
||||||
if dston < dstoff:
|
|
||||||
return dston <= dt.replace(tzinfo=None) < dstoff
|
|
||||||
else:
|
|
||||||
return not dstoff <= dt.replace(tzinfo=None) < dston
|
|
||||||
|
|
||||||
|
|
||||||
class tzwin(tzwinbase):
|
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
self._name = name
|
|
||||||
|
|
||||||
# multiple contexts only possible in 2.7 and 3.1, we still support 2.6
|
|
||||||
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
|
||||||
with winreg.OpenKey(handle,
|
|
||||||
"%s\%s" % (TZKEYNAME, name)) as tzkey:
|
|
||||||
keydict = valuestodict(tzkey)
|
|
||||||
|
|
||||||
self._stdname = keydict["Std"]
|
|
||||||
self._dstname = keydict["Dlt"]
|
|
||||||
|
|
||||||
self._display = keydict["Display"]
|
|
||||||
|
|
||||||
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
|
||||||
tup = struct.unpack("=3l16h", keydict["TZI"])
|
|
||||||
self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1
|
|
||||||
self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1
|
|
||||||
|
|
||||||
# for the meaning see the win32 TIME_ZONE_INFORMATION structure docs
|
|
||||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
|
|
||||||
(self._stdmonth,
|
|
||||||
self._stddayofweek, # Sunday = 0
|
|
||||||
self._stdweeknumber, # Last = 5
|
|
||||||
self._stdhour,
|
|
||||||
self._stdminute) = tup[4:9]
|
|
||||||
|
|
||||||
(self._dstmonth,
|
|
||||||
self._dstdayofweek, # Sunday = 0
|
|
||||||
self._dstweeknumber, # Last = 5
|
|
||||||
self._dsthour,
|
|
||||||
self._dstminute) = tup[12:17]
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "tzwin(%s)" % repr(self._name)
|
|
||||||
|
|
||||||
def __reduce__(self):
|
|
||||||
return (self.__class__, (self._name,))
|
|
||||||
|
|
||||||
|
|
||||||
class tzwinlocal(tzwinbase):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
|
|
||||||
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
|
||||||
|
|
||||||
with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
|
|
||||||
keydict = valuestodict(tzlocalkey)
|
|
||||||
|
|
||||||
self._stdname = keydict["StandardName"]
|
|
||||||
self._dstname = keydict["DaylightName"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
with winreg.OpenKey(
|
|
||||||
handle, "%s\%s" % (TZKEYNAME, self._stdname)) as tzkey:
|
|
||||||
_keydict = valuestodict(tzkey)
|
|
||||||
self._display = _keydict["Display"]
|
|
||||||
except OSError:
|
|
||||||
self._display = None
|
|
||||||
|
|
||||||
self._stdoffset = -keydict["Bias"]-keydict["StandardBias"]
|
|
||||||
self._dstoffset = self._stdoffset-keydict["DaylightBias"]
|
|
||||||
|
|
||||||
# See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
|
|
||||||
tup = struct.unpack("=8h", keydict["StandardStart"])
|
|
||||||
|
|
||||||
(self._stdmonth,
|
|
||||||
self._stddayofweek, # Sunday = 0
|
|
||||||
self._stdweeknumber, # Last = 5
|
|
||||||
self._stdhour,
|
|
||||||
self._stdminute) = tup[1:6]
|
|
||||||
|
|
||||||
tup = struct.unpack("=8h", keydict["DaylightStart"])
|
|
||||||
|
|
||||||
(self._dstmonth,
|
|
||||||
self._dstdayofweek, # Sunday = 0
|
|
||||||
self._dstweeknumber, # Last = 5
|
|
||||||
self._dsthour,
|
|
||||||
self._dstminute) = tup[1:6]
|
|
||||||
|
|
||||||
def __reduce__(self):
|
|
||||||
return (self.__class__, ())
|
|
||||||
|
|
||||||
|
|
||||||
def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
|
|
||||||
"""dayofweek == 0 means Sunday, whichweek 5 means last instance"""
|
|
||||||
first = datetime.datetime(year, month, 1, hour, minute)
|
|
||||||
weekdayone = first.replace(day=((dayofweek-first.isoweekday()) % 7+1))
|
|
||||||
for n in range(whichweek):
|
|
||||||
dt = weekdayone+(whichweek-n)*ONEWEEK
|
|
||||||
if dt.month == month:
|
|
||||||
return dt
|
|
||||||
|
|
||||||
|
|
||||||
def valuestodict(key):
|
|
||||||
"""Convert a registry key's values to a dictionary."""
|
|
||||||
dict = {}
|
|
||||||
size = winreg.QueryInfoKey(key)[1]
|
|
||||||
for i in range(size):
|
|
||||||
data = winreg.EnumValue(key, i)
|
|
||||||
dict[data[0]] = data[1]
|
|
||||||
return dict
|
|
|
@ -25,12 +25,8 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
|
||||||
try:
|
try:
|
||||||
check_call(["zic", "-d", zonedir] + filepaths)
|
check_call(["zic", "-d", zonedir] + filepaths)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == 2:
|
_print_on_nosuchfile(e)
|
||||||
logging.error(
|
raise
|
||||||
"Could not find zic. Perhaps you need to install "
|
|
||||||
"libc-bin or some other package that provides it, "
|
|
||||||
"or it's not in your PATH?")
|
|
||||||
raise
|
|
||||||
# write metadata file
|
# write metadata file
|
||||||
with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
|
with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
|
||||||
json.dump(metadata, f, indent=4, sort_keys=True)
|
json.dump(metadata, f, indent=4, sort_keys=True)
|
||||||
|
@ -41,3 +37,15 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
|
||||||
tf.add(entrypath, entry)
|
tf.add(entrypath, entry)
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
def _print_on_nosuchfile(e):
|
||||||
|
"""Print helpful troubleshooting message
|
||||||
|
|
||||||
|
e is an exception raised by subprocess.check_call()
|
||||||
|
|
||||||
|
"""
|
||||||
|
if e.errno == 2:
|
||||||
|
logging.error(
|
||||||
|
"Could not find zic. Perhaps you need to install "
|
||||||
|
"libc-bin or some other package that provides it, "
|
||||||
|
"or it's not in your PATH?")
|
||||||
|
|
Loading…
Reference in a new issue