Source code for domovoy.plugins.utils
import asyncio
import datetime
from collections.abc import Awaitable, Callable
from typing import ParamSpec, TypeVar
from warnings import deprecated
import pytz
from dateutil.parser import parse
from domovoy.applications.types import Interval
from domovoy.core.app_infra import AppWrapper
from domovoy.core.configuration import get_main_config
from domovoy.core.utils import as_float, as_int, get_callback_name
from domovoy.plugins.plugins import AppPlugin
TFloat = TypeVar("TFloat", bound=float | None)
TInt = TypeVar("TInt", bound=float | None)
P = ParamSpec("P")
T = TypeVar("T")
[docs]
class UtilsPlugin(AppPlugin):
def __init__(self, name: str, wrapper: AppWrapper) -> None:
super().__init__(name, wrapper)
[docs]
def parse_float(self, val: object, default: TFloat = None) -> float | TFloat:
return as_float(val, default) # type: ignore
[docs]
def parse_int(self, val: object, default: TInt = None) -> int | TInt:
return as_int(val, default) # type: ignore
[docs]
def parse_int_or_float(self, val: object) -> int | float | None:
as_int = self.parse_int(val)
if as_int is not None:
return as_int
as_float = self.parse_float(val)
if as_float is not None:
return as_float
return None
[docs]
def run_async(
self,
callback: Callable[P, Awaitable[T]],
*args: P.args,
**kwargs: P.kwargs,
) -> asyncio.Task[T]:
async def callback_wrapper() -> T:
return await callback(*args, **kwargs)
return asyncio.get_event_loop().create_task(
callback_wrapper(),
name=get_callback_name(callback),
)
[docs]
def run_in_executor(
self,
callback: Callable[P, T],
*args: P.args,
**kwargs: P.kwargs,
) -> asyncio.Future[T]:
def callback_wrapper() -> T:
return callback(*args, **kwargs)
return asyncio.get_event_loop().run_in_executor(None, callback_wrapper)
[docs]
@deprecated("use time plugin")
async def sleep_for(self, interval: Interval) -> None:
await asyncio.sleep(interval.total_seconds())
[docs]
@deprecated("use time plugin")
def parse_date(self, string: str) -> datetime.datetime:
return parse(string)
[docs]
@deprecated("use time plugin")
def timedelta_from_now(
self,
date: datetime.datetime | str,
target_tz: pytz.BaseTzInfo | None = None,
) -> datetime.timedelta:
if target_tz is None:
target_tz = get_main_config().get_timezone()
date = date if isinstance(date, datetime.datetime) else parse(date)
has_tz_info = date.tzinfo is not None and date.tzinfo.utcoffset(date) is not None
if not has_tz_info:
if target_tz is None:
raise ValueError(
"Date provided does not have timezone and a target timezone was not provided",
)
date = target_tz.localize(date)
now = datetime.datetime.now(target_tz)
return now - date