mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-06 05:01:14 -07:00
Update tzlocal==5.0.1
This commit is contained in:
parent
80e6131a0d
commit
85bc9c39ae
6 changed files with 807 additions and 772 deletions
|
@ -1,20 +1,21 @@
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
from datetime import timezone
|
||||
import pytz_deprecation_shim as pds
|
||||
|
||||
from tzlocal import utils
|
||||
|
||||
if sys.version_info >= (3, 9):
|
||||
from zoneinfo import ZoneInfo # pragma: no cover
|
||||
import zoneinfo # pragma: no cover
|
||||
else:
|
||||
from backports.zoneinfo import ZoneInfo # pragma: no cover
|
||||
from backports import zoneinfo # pragma: no cover
|
||||
|
||||
_cache_tz = None
|
||||
_cache_tz_name = None
|
||||
|
||||
log = logging.getLogger("tzlocal")
|
||||
|
||||
def _get_localzone_name(_root="/"):
|
||||
"""Tries to find the local timezone configuration.
|
||||
|
@ -32,14 +33,21 @@ def _get_localzone_name(_root="/"):
|
|||
|
||||
# Are we under Termux on Android?
|
||||
if os.path.exists(os.path.join(_root, "system/bin/getprop")):
|
||||
log.debug("This looks like Termux")
|
||||
|
||||
import subprocess
|
||||
|
||||
androidtz = (
|
||||
subprocess.check_output(["getprop", "persist.sys.timezone"])
|
||||
.strip()
|
||||
.decode()
|
||||
)
|
||||
return androidtz
|
||||
try:
|
||||
androidtz = (
|
||||
subprocess.check_output(["getprop", "persist.sys.timezone"])
|
||||
.strip()
|
||||
.decode()
|
||||
)
|
||||
return androidtz
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
# proot environment or failed to getprop
|
||||
log.debug("It's not termux?")
|
||||
pass
|
||||
|
||||
# Now look for distribution specific configuration files
|
||||
# that contain the timezone name.
|
||||
|
@ -50,10 +58,11 @@ def _get_localzone_name(_root="/"):
|
|||
for configfile in ("etc/timezone", "var/db/zoneinfo"):
|
||||
tzpath = os.path.join(_root, configfile)
|
||||
try:
|
||||
with open(tzpath, "rt") as tzfile:
|
||||
with open(tzpath) as tzfile:
|
||||
data = tzfile.read()
|
||||
log.debug(f"{tzpath} found, contents:\n {data}")
|
||||
|
||||
etctz = data.strip('/ \t\r\n')
|
||||
etctz = data.strip("/ \t\r\n")
|
||||
if not etctz:
|
||||
# Empty file, skip
|
||||
continue
|
||||
|
@ -68,7 +77,7 @@ def _get_localzone_name(_root="/"):
|
|||
|
||||
found_configs[tzpath] = etctz.replace(" ", "_")
|
||||
|
||||
except (IOError, UnicodeDecodeError):
|
||||
except (OSError, UnicodeDecodeError):
|
||||
# File doesn't exist or is a directory, or it's a binary file.
|
||||
continue
|
||||
|
||||
|
@ -86,6 +95,7 @@ def _get_localzone_name(_root="/"):
|
|||
try:
|
||||
with open(tzpath, "rt") as tzfile:
|
||||
data = tzfile.readlines()
|
||||
log.debug(f"{tzpath} found, contents:\n {data}")
|
||||
|
||||
for line in data:
|
||||
# Look for the ZONE= setting.
|
||||
|
@ -95,13 +105,13 @@ def _get_localzone_name(_root="/"):
|
|||
match = timezone_re.match(line)
|
||||
if match is not None:
|
||||
# Some setting existed
|
||||
line = line[match.end():]
|
||||
line = line[match.end() :]
|
||||
etctz = line[: end_re.search(line).start()]
|
||||
|
||||
# We found a timezone
|
||||
found_configs[tzpath] = etctz.replace(" ", "_")
|
||||
|
||||
except (IOError, UnicodeDecodeError):
|
||||
except (OSError, UnicodeDecodeError):
|
||||
# UnicodeDecode handles when clock is symlink to /etc/localtime
|
||||
continue
|
||||
|
||||
|
@ -109,30 +119,34 @@ def _get_localzone_name(_root="/"):
|
|||
# see manpage of localtime(5) and timedatectl(1)
|
||||
tzpath = os.path.join(_root, "etc/localtime")
|
||||
if os.path.exists(tzpath) and os.path.islink(tzpath):
|
||||
etctz = realtzpath = os.path.realpath(tzpath)
|
||||
log.debug(f"{tzpath} found")
|
||||
etctz = os.path.realpath(tzpath)
|
||||
start = etctz.find("/") + 1
|
||||
while start != 0:
|
||||
etctz = etctz[start:]
|
||||
try:
|
||||
pds.timezone(etctz)
|
||||
zoneinfo.ZoneInfo(etctz)
|
||||
tzinfo = f"{tzpath} is a symlink to"
|
||||
found_configs[tzinfo] = etctz.replace(" ", "_")
|
||||
except pds.UnknownTimeZoneError:
|
||||
# Only need first valid relative path in simlink.
|
||||
break
|
||||
except zoneinfo.ZoneInfoNotFoundError:
|
||||
pass
|
||||
start = etctz.find("/") + 1
|
||||
|
||||
if len(found_configs) > 0:
|
||||
log.debug(f"{len(found_configs)} found:\n {found_configs}")
|
||||
# We found some explicit config of some sort!
|
||||
if len(found_configs) > 1:
|
||||
# Uh-oh, multiple configs. See if they match:
|
||||
unique_tzs = set()
|
||||
zoneinfo = os.path.join(_root, "usr", "share", "zoneinfo")
|
||||
directory_depth = len(zoneinfo.split(os.path.sep))
|
||||
zoneinfopath = os.path.join(_root, "usr", "share", "zoneinfo")
|
||||
directory_depth = len(zoneinfopath.split(os.path.sep))
|
||||
|
||||
for tzname in found_configs.values():
|
||||
# Look them up in /usr/share/zoneinfo, and find what they
|
||||
# really point to:
|
||||
path = os.path.realpath(os.path.join(zoneinfo, *tzname.split("/")))
|
||||
path = os.path.realpath(os.path.join(zoneinfopath, *tzname.split("/")))
|
||||
real_zone_name = "/".join(path.split(os.path.sep)[directory_depth:])
|
||||
unique_tzs.add(real_zone_name)
|
||||
|
||||
|
@ -141,7 +155,7 @@ def _get_localzone_name(_root="/"):
|
|||
for key, value in found_configs.items():
|
||||
message += f"{key}: {value}\n"
|
||||
message += "Fix the configuration, or set the time zone in a TZ environment variable.\n"
|
||||
raise utils.ZoneInfoNotFoundError(message)
|
||||
raise zoneinfo.ZoneInfoNotFoundError(message)
|
||||
|
||||
# We found exactly one config! Use it.
|
||||
return list(found_configs.values())[0]
|
||||
|
@ -165,24 +179,25 @@ def _get_localzone(_root="/"):
|
|||
tzname = _get_localzone_name(_root)
|
||||
if tzname is None:
|
||||
# No explicit setting existed. Use localtime
|
||||
log.debug("No explicit setting existed. Use localtime")
|
||||
for filename in ("etc/localtime", "usr/local/etc/localtime"):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
|
||||
if not os.path.exists(tzpath):
|
||||
continue
|
||||
with open(tzpath, "rb") as tzfile:
|
||||
tz = pds.wrap_zone(ZoneInfo.from_file(tzfile, key="local"))
|
||||
tz = zoneinfo.ZoneInfo.from_file(tzfile, key="local")
|
||||
break
|
||||
else:
|
||||
warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
|
||||
tz = timezone.utc
|
||||
else:
|
||||
tz = pds.timezone(tzname)
|
||||
tz = zoneinfo.ZoneInfo(tzname)
|
||||
|
||||
if _root == "/":
|
||||
# We are using a file in etc to name the timezone.
|
||||
# Verify that the timezone specified there is actually used:
|
||||
utils.assert_tz_offset(tz)
|
||||
utils.assert_tz_offset(tz, error=False)
|
||||
return tz
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue