New Addon
Google BK
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
from injector import inject, singleton
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from dateutil.parser import parse
|
||||
from .logger import getLogger
|
||||
import pytz
|
||||
import os
|
||||
from pytz import timezone, utc
|
||||
from tzlocal import get_localzone_name, get_localzone
|
||||
from dateutil.tz import tzlocal
|
||||
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
def get_local_tz():
|
||||
methods = [
|
||||
_infer_timezone_from_env,
|
||||
_infer_timezone_from_system,
|
||||
_infer_timezone_from_name,
|
||||
_infer_timezone_from_offset
|
||||
]
|
||||
for method in methods:
|
||||
try:
|
||||
tz = method()
|
||||
if tz is not None:
|
||||
return tz
|
||||
except Exception:
|
||||
pass
|
||||
return utc
|
||||
|
||||
|
||||
def _infer_timezone_from_offset():
|
||||
now = datetime.now()
|
||||
desired_offset = tzlocal().utcoffset(now)
|
||||
for tz_name in pytz.all_timezones:
|
||||
tz = pytz.timezone(tz_name)
|
||||
if desired_offset == tz.utcoffset(now):
|
||||
return tz
|
||||
return None
|
||||
|
||||
|
||||
def _infer_timezone_from_name():
|
||||
name = get_localzone_name()
|
||||
if name is not None:
|
||||
return timezone(name)
|
||||
return None
|
||||
|
||||
|
||||
def _infer_timezone_from_system():
|
||||
tz = get_localzone()
|
||||
if tz is not None:
|
||||
return tz
|
||||
return None
|
||||
|
||||
|
||||
def _infer_timezone_from_env():
|
||||
if "TZ" in os.environ:
|
||||
tz = timezone(os.environ["TZ"])
|
||||
if tz is not None:
|
||||
return tz
|
||||
return None
|
||||
|
||||
@singleton
|
||||
class Time(object):
|
||||
@inject
|
||||
def __init__(self, local_tz=get_local_tz()):
|
||||
self.local_tz = local_tz
|
||||
self._offset = timedelta(seconds=0)
|
||||
|
||||
def now(self) -> datetime:
|
||||
return datetime.now(pytz.utc) + self._offset
|
||||
|
||||
def nowLocal(self) -> datetime:
|
||||
return datetime.now(self.local_tz) + self._offset
|
||||
|
||||
@property
|
||||
def offset(self):
|
||||
return self._offset
|
||||
|
||||
@offset.setter
|
||||
def offset(self, delta: timedelta):
|
||||
self._offset = delta
|
||||
|
||||
@classmethod
|
||||
def parse(cls, text: str) -> datetime:
|
||||
ret = parse(text)
|
||||
if ret.tzinfo is None:
|
||||
ret = ret.replace(tzinfo=utc)
|
||||
return ret
|
||||
|
||||
def toLocal(self, dt: datetime) -> datetime:
|
||||
return dt.astimezone(self.local_tz)
|
||||
|
||||
def localize(self, dt: datetime) -> datetime:
|
||||
return self.local_tz.localize(dt)
|
||||
|
||||
def toUtc(self, dt: datetime) -> datetime:
|
||||
return dt.astimezone(utc)
|
||||
|
||||
async def sleepAsync(self, seconds: float, early_exit: asyncio.Event = None) -> None:
|
||||
if early_exit is None:
|
||||
await asyncio.sleep(seconds)
|
||||
else:
|
||||
try:
|
||||
await asyncio.wait_for(early_exit.wait(), seconds)
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
def local(self, year, month, day, hour=0, minute=0, second=0, ms=0):
|
||||
return self.local_tz.localize(datetime(year, month, day, hour, minute, second, ms))
|
||||
|
||||
def formatDelta(self, time: datetime, now=None) -> str:
|
||||
if not now:
|
||||
now = self.now()
|
||||
|
||||
delta: relativedelta = None
|
||||
flavor = ""
|
||||
if time < now:
|
||||
delta = relativedelta(now, time)
|
||||
flavor = " ago"
|
||||
else:
|
||||
delta = relativedelta(time, now)
|
||||
flavor = ""
|
||||
if delta.years > 0:
|
||||
plural = "s" if delta.years > 1 else ""
|
||||
return "{0} year{2}{1}".format(delta.years, flavor, plural)
|
||||
if (delta.months != 0):
|
||||
plural = "s" if delta.months > 1 else ""
|
||||
if delta.days > 15:
|
||||
return "{0} month{2}{1}".format(delta.months + 1, flavor, plural)
|
||||
return "{0} month{2}{1}".format(delta.months, flavor, plural)
|
||||
if (delta.days != 0):
|
||||
plural = "s" if delta.days > 1 else ""
|
||||
if delta.hours >= 12:
|
||||
return "{0} day{2}{1}".format(delta.days + 1, flavor, plural)
|
||||
return "{0} day{2}{1}".format(delta.days, flavor, plural)
|
||||
if (delta.hours != 0):
|
||||
plural = "s" if delta.hours > 1 else ""
|
||||
if delta.minutes >= 30:
|
||||
return "{0} hour{2}{1}".format(delta.hours + 1, flavor, plural)
|
||||
return "{0} hour{2}{1}".format(delta.hours, flavor, plural)
|
||||
if (delta.minutes != 0):
|
||||
plural = "s" if delta.minutes > 1 else ""
|
||||
if delta.minutes >= 30:
|
||||
return "{0} minute{2}{1}".format(delta.minutes + 1, flavor, plural)
|
||||
return "{0} minute{2}{1}".format(delta.minutes, flavor, plural)
|
||||
if (delta.seconds != 0):
|
||||
plural = "s" if delta.seconds > 1 else ""
|
||||
return "{0} second{2}{1}".format(delta.seconds, flavor, plural)
|
||||
return "right now"
|
||||
|
||||
def asRfc3339String(self, time: datetime) -> str:
|
||||
if time is None:
|
||||
time = self.now()
|
||||
return time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
class AcceleratedTime(Time):
|
||||
def __init__(self, dialation=1.0):
|
||||
super().__init__()
|
||||
self.start = datetime.now(utc)
|
||||
self.dialation = dialation
|
||||
|
||||
def now(self):
|
||||
return self.start + timedelta(seconds=(datetime.now(utc) - self.start).total_seconds() * self.dialation)
|
||||
|
||||
def nowLocal(self) -> datetime:
|
||||
return self.localize(self.now())
|
||||
|
||||
async def sleepAsync(self, seconds: float) -> None:
|
||||
await asyncio.sleep(seconds / self.dialation)
|
||||
Reference in New Issue
Block a user