mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Update tzlocal-3.0
This commit is contained in:
parent
9d78e6ae4c
commit
c67f18d65c
4 changed files with 34 additions and 231 deletions
|
@ -1,189 +0,0 @@
|
||||||
Changes
|
|
||||||
=======
|
|
||||||
|
|
||||||
2.1b1 (2020-02-08)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- The is_dst flag is wrong for Europe/Dublin on some Unix releases.
|
|
||||||
I changed to another way of determining if DST is in effect or not.
|
|
||||||
|
|
||||||
- Added support for Python 3.7 and 3.8. Dropped 3.5 although it still works.
|
|
||||||
|
|
||||||
|
|
||||||
2.0.0 (2019-07-23)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- No differences since 2.0.0b3
|
|
||||||
|
|
||||||
Major differences since 1.5.1
|
|
||||||
.............................
|
|
||||||
|
|
||||||
- When no time zone configuration can be find, tzlocal now return UTC.
|
|
||||||
This is a major difference from 1.x, where an exception would be raised.
|
|
||||||
This change is because Docker images often have no configuration at all,
|
|
||||||
and the unix utilities will then default to UTC, so we follow that.
|
|
||||||
|
|
||||||
- If tzlocal on Unix finds a timezone name in a /etc config file, then
|
|
||||||
tzlocal now verifies that the timezone it fouds has the same offset as
|
|
||||||
the local computer is configured with. If it doesn't, something is
|
|
||||||
configured incorrectly. (Victor Torres, regebro)
|
|
||||||
|
|
||||||
- Get timezone via Termux `getprop` wrapper on Android. It's not officially
|
|
||||||
supported because we can't test it, but at least we make an effort.
|
|
||||||
(Jean Jordaan)
|
|
||||||
|
|
||||||
Minor differences and bug fixes
|
|
||||||
...............................
|
|
||||||
|
|
||||||
- Skip comment lines when parsing /etc/timezone. (Edward Betts)
|
|
||||||
|
|
||||||
- Don't load timezone from current directory. (Gabriel Corona)
|
|
||||||
|
|
||||||
- Now verifies that the config files actually contain something before
|
|
||||||
reading them. (Zackary Welch, regebro)
|
|
||||||
|
|
||||||
- Got rid of a BytesWarning (Mickaël Schoentgen)
|
|
||||||
|
|
||||||
- Now handles if config file paths exists, but are directories.
|
|
||||||
|
|
||||||
- Moved tests out from distributions
|
|
||||||
|
|
||||||
- Support wheels
|
|
||||||
|
|
||||||
|
|
||||||
1.5.1 (2017-12-01)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- 1.5 had a bug that slipped through testing, fixed that,
|
|
||||||
increased test coverage.
|
|
||||||
|
|
||||||
|
|
||||||
1.5 (2017-11-30)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- No longer treats macOS as special, but as a unix.
|
|
||||||
|
|
||||||
- get_windows_info.py is renamed to update_windows_mappings.py
|
|
||||||
|
|
||||||
- Windows mappings now also contain mappings from deprecated zoneinfo names.
|
|
||||||
(Preston-Landers, regebro)
|
|
||||||
|
|
||||||
|
|
||||||
1.4 (2017-04-18)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- I use MIT on my other projects, so relicensing.
|
|
||||||
|
|
||||||
|
|
||||||
1.4b1 (2017-04-14)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- Dropping support for Python versions nobody uses (2.5, 3.1, 3.2), adding 3.6
|
|
||||||
Python 3.1 and 3.2 still works, 2.5 has been broken for some time.
|
|
||||||
|
|
||||||
- Ayalash's OS X fix didn't work on Python 2.7, fixed that.
|
|
||||||
|
|
||||||
|
|
||||||
1.3.2 (2017-04-12)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- Ensure closing of subprocess on OS X (ayalash)
|
|
||||||
|
|
||||||
- Removed unused imports (jwilk)
|
|
||||||
|
|
||||||
- Closes stdout and stderr to get rid of ResourceWarnings (johnwquarles)
|
|
||||||
|
|
||||||
- Updated Windows timezones (axil)
|
|
||||||
|
|
||||||
|
|
||||||
1.3 (2016-10-15)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- #34: Added support for /var/db/zoneinfo
|
|
||||||
|
|
||||||
|
|
||||||
1.2.2 (2016-03-02)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- #30: Fixed a bug on OS X.
|
|
||||||
|
|
||||||
|
|
||||||
1.2.1 (2016-02-28)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- Tests failed if TZ was set in the environment. (EdwardBetts)
|
|
||||||
|
|
||||||
- Replaces os.popen() with subprocess.Popen() for OS X to
|
|
||||||
handle when systemsetup doesn't exist. (mckabi, cewing)
|
|
||||||
|
|
||||||
|
|
||||||
1.2 (2015-06-14)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Systemd stores no time zone name, forcing us to look at the name of the file
|
|
||||||
that localtime symlinks to. (cameris)
|
|
||||||
|
|
||||||
|
|
||||||
1.1.2 (2014-10-18)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- Timezones that has 3 items did not work on Mac OS X.
|
|
||||||
(Marc Van Olmen)
|
|
||||||
|
|
||||||
- Now doesn't fail if the TZ environment variable isn't an Olsen time zone.
|
|
||||||
|
|
||||||
- Some timezones on Windows can apparently be empty (perhaps the are deleted).
|
|
||||||
Now these are ignored.
|
|
||||||
(Xiaokun Zhu)
|
|
||||||
|
|
||||||
|
|
||||||
1.1.1 (2014-01-29)
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- I forgot to add Etc/UTC as an alias for Etc/GMT.
|
|
||||||
|
|
||||||
|
|
||||||
1.1 (2014-01-28)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Adding better support for OS X.
|
|
||||||
|
|
||||||
- Added support to map from tzdata/Olsen names to Windows names.
|
|
||||||
(Thanks to Benjamen Meyer).
|
|
||||||
|
|
||||||
|
|
||||||
1.0 (2013-05-29)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Fixed some more cases where spaces needs replacing with underscores.
|
|
||||||
|
|
||||||
- Better handling of misconfigured /etc/timezone.
|
|
||||||
|
|
||||||
- Better error message on Windows if we can't find a timezone at all.
|
|
||||||
|
|
||||||
|
|
||||||
0.3 (2012-09-13)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Windows 7 support.
|
|
||||||
|
|
||||||
- Python 2.5 supported; because it only needed a __future__ import.
|
|
||||||
|
|
||||||
- Python 3.3 tested, it worked.
|
|
||||||
|
|
||||||
- Got rid of relative imports, because I don't actually like them,
|
|
||||||
so I don't know why I used them in the first place.
|
|
||||||
|
|
||||||
- For each Windows zone, use the default zoneinfo zone, not the last one.
|
|
||||||
|
|
||||||
|
|
||||||
0.2 (2012-09-12)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Python 3 support.
|
|
||||||
|
|
||||||
|
|
||||||
0.1 (2012-09-11)
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- Initial release.
|
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright 2011-2017 Lennart Regebro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,10 +1,16 @@
|
||||||
import os
|
import os
|
||||||
import pytz
|
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
from datetime import timezone
|
||||||
|
|
||||||
from tzlocal import utils
|
from tzlocal import utils
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 9):
|
||||||
|
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||||
|
else:
|
||||||
|
from backports.zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||||
|
|
||||||
_cache_tz = None
|
_cache_tz = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,17 +21,17 @@ def _tz_from_env(tzenv):
|
||||||
# TZ specifies a file
|
# TZ specifies a file
|
||||||
if os.path.isabs(tzenv) and os.path.exists(tzenv):
|
if os.path.isabs(tzenv) and os.path.exists(tzenv):
|
||||||
with open(tzenv, 'rb') as tzfile:
|
with open(tzenv, 'rb') as tzfile:
|
||||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
return ZoneInfo.from_file(tzfile, key='local')
|
||||||
|
|
||||||
# TZ specifies a zoneinfo zone.
|
# TZ specifies a zoneinfo zone.
|
||||||
try:
|
try:
|
||||||
tz = pytz.timezone(tzenv)
|
tz = ZoneInfo(tzenv)
|
||||||
# That worked, so we return this:
|
# That worked, so we return this:
|
||||||
return tz
|
return tz
|
||||||
except pytz.UnknownTimeZoneError:
|
except ZoneInfoNotFoundError:
|
||||||
raise pytz.UnknownTimeZoneError(
|
raise ZoneInfoNotFoundError(
|
||||||
"tzlocal() does not support non-zoneinfo timezones like %s. \n"
|
"tzlocal() does not support non-zoneinfo timezones like %s. \n"
|
||||||
"Please use a timezone in the form of Continent/City")
|
"Please use a timezone in the form of Continent/City") from None
|
||||||
|
|
||||||
|
|
||||||
def _try_tz_from_env():
|
def _try_tz_from_env():
|
||||||
|
@ -33,7 +39,7 @@ def _try_tz_from_env():
|
||||||
if tzenv:
|
if tzenv:
|
||||||
try:
|
try:
|
||||||
return _tz_from_env(tzenv)
|
return _tz_from_env(tzenv)
|
||||||
except pytz.UnknownTimeZoneError:
|
except ZoneInfoNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +62,7 @@ def _get_localzone(_root='/'):
|
||||||
if os.path.exists('/system/bin/getprop'):
|
if os.path.exists('/system/bin/getprop'):
|
||||||
import subprocess
|
import subprocess
|
||||||
androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode()
|
androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode()
|
||||||
return pytz.timezone(androidtz)
|
return ZoneInfo(androidtz)
|
||||||
|
|
||||||
# Now look for distribution specific configuration files
|
# Now look for distribution specific configuration files
|
||||||
# that contain the timezone name.
|
# that contain the timezone name.
|
||||||
|
@ -83,15 +89,15 @@ def _get_localzone(_root='/'):
|
||||||
etctz, dummy = etctz.split('#', 1)
|
etctz, dummy = etctz.split('#', 1)
|
||||||
if not etctz:
|
if not etctz:
|
||||||
continue
|
continue
|
||||||
tz = pytz.timezone(etctz.replace(' ', '_'))
|
tz = ZoneInfo(etctz.replace(' ', '_'))
|
||||||
if _root == '/':
|
if _root == '/':
|
||||||
# We are using a file in etc to name the timezone.
|
# We are using a file in etc to name the timezone.
|
||||||
# Verify that the timezone specified there is actually used:
|
# Verify that the timezone specified there is actually used:
|
||||||
utils.assert_tz_offset(tz)
|
utils.assert_tz_offset(tz)
|
||||||
return tz
|
return tz
|
||||||
|
|
||||||
except IOError:
|
except (IOError, UnicodeDecodeError):
|
||||||
# File doesn't exist or is a directory
|
# File doesn't exist or is a directory, or it's a binary file.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# CentOS has a ZONE setting in /etc/sysconfig/clock,
|
# CentOS has a ZONE setting in /etc/sysconfig/clock,
|
||||||
|
@ -121,15 +127,15 @@ def _get_localzone(_root='/'):
|
||||||
etctz = line[:end_re.search(line).start()]
|
etctz = line[:end_re.search(line).start()]
|
||||||
|
|
||||||
# We found a timezone
|
# We found a timezone
|
||||||
tz = pytz.timezone(etctz.replace(' ', '_'))
|
tz = ZoneInfo(etctz.replace(' ', '_'))
|
||||||
if _root == '/':
|
if _root == '/':
|
||||||
# We are using a file in etc to name the timezone.
|
# We are using a file in etc to name the timezone.
|
||||||
# Verify that the timezone specified there is actually used:
|
# Verify that the timezone specified there is actually used:
|
||||||
utils.assert_tz_offset(tz)
|
utils.assert_tz_offset(tz)
|
||||||
return tz
|
return tz
|
||||||
|
|
||||||
except IOError:
|
except (IOError, UnicodeDecodeError) as e:
|
||||||
# File doesn't exist or is a directory
|
# UnicodeDecode handles when clock is symlink to /etc/localtime
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# systemd distributions use symlinks that include the zone name,
|
# systemd distributions use symlinks that include the zone name,
|
||||||
|
@ -141,8 +147,8 @@ def _get_localzone(_root='/'):
|
||||||
while start != 0:
|
while start != 0:
|
||||||
tzpath = tzpath[start:]
|
tzpath = tzpath[start:]
|
||||||
try:
|
try:
|
||||||
return pytz.timezone(tzpath)
|
return ZoneInfo(tzpath)
|
||||||
except pytz.UnknownTimeZoneError:
|
except ZoneInfoNotFoundError:
|
||||||
pass
|
pass
|
||||||
start = tzpath.find("/")+1
|
start = tzpath.find("/")+1
|
||||||
|
|
||||||
|
@ -153,10 +159,10 @@ def _get_localzone(_root='/'):
|
||||||
if not os.path.exists(tzpath):
|
if not os.path.exists(tzpath):
|
||||||
continue
|
continue
|
||||||
with open(tzpath, 'rb') as tzfile:
|
with open(tzpath, 'rb') as tzfile:
|
||||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
return ZoneInfo.from_file(tzfile, key='local')
|
||||||
|
|
||||||
warnings.warn('Can not find any timezone configuration, defaulting to UTC.')
|
warnings.warn('Can not find any timezone configuration, defaulting to UTC.')
|
||||||
return pytz.utc
|
return timezone.utc
|
||||||
|
|
||||||
def get_localzone():
|
def get_localzone():
|
||||||
"""Get the computers configured local timezone, if any."""
|
"""Get the computers configured local timezone, if any."""
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import _winreg as winreg
|
import _winreg as winreg
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import winreg
|
import winreg
|
||||||
|
|
||||||
import pytz
|
|
||||||
|
|
||||||
from tzlocal.windows_tz import win_tz
|
from tzlocal.windows_tz import win_tz
|
||||||
from tzlocal import utils
|
from tzlocal import utils
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 9):
|
||||||
|
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||||
|
else:
|
||||||
|
from backports.zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||||
|
|
||||||
_cache_tz = None
|
_cache_tz = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +86,7 @@ def get_localzone_name():
|
||||||
|
|
||||||
# Return what we have.
|
# Return what we have.
|
||||||
if timezone is None:
|
if timezone is None:
|
||||||
raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname)
|
raise ZoneInfoNotFoundError(tzkeyname)
|
||||||
|
|
||||||
return timezone
|
return timezone
|
||||||
|
|
||||||
|
@ -90,7 +95,7 @@ def get_localzone():
|
||||||
"""Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
|
"""Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
|
||||||
global _cache_tz
|
global _cache_tz
|
||||||
if _cache_tz is None:
|
if _cache_tz is None:
|
||||||
_cache_tz = pytz.timezone(get_localzone_name())
|
_cache_tz = ZoneInfo(get_localzone_name())
|
||||||
|
|
||||||
utils.assert_tz_offset(_cache_tz)
|
utils.assert_tz_offset(_cache_tz)
|
||||||
return _cache_tz
|
return _cache_tz
|
||||||
|
@ -99,6 +104,6 @@ def get_localzone():
|
||||||
def reload_localzone():
|
def reload_localzone():
|
||||||
"""Reload the cached localzone. You need to call this if the timezone has changed."""
|
"""Reload the cached localzone. You need to call this if the timezone has changed."""
|
||||||
global _cache_tz
|
global _cache_tz
|
||||||
_cache_tz = pytz.timezone(get_localzone_name())
|
_cache_tz = ZoneInfo(get_localzone_name())
|
||||||
utils.assert_tz_offset(_cache_tz)
|
utils.assert_tz_offset(_cache_tz)
|
||||||
return _cache_tz
|
return _cache_tz
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue