Исходный код raito.core.routers.loader
from __future__ import annotations
from asyncio import sleep
from pathlib import Path
from typing import TYPE_CHECKING
from .base_router import BaseRouter
from .parser import RouterParser
from .router import Router as RaitoRouter
if TYPE_CHECKING:
from aiogram import Dispatcher, Router
from raito.utils.types import StrOrPath
__all__ = ("RouterLoader",)
[документация]
class RouterLoader(BaseRouter, RouterParser):
"""A class for loading, unloading and reloading routers dynamically."""
def __init__(
self,
name: str,
path: StrOrPath,
dispatcher: Dispatcher,
router: Router | None = None,
) -> None:
"""Initialize RouterLoader.
:param name: Unique name of the router
:type name: str
:param path: Path to the router file
:type path: StrOrPath
:param dispatcher: Aiogram dispatcher
:type dispatcher: Dispatcher
:param router: Router (aiogram or Raito) instance, defaults to None
:type router: aiogram.Router | raito.Router | None, optional
"""
super().__init__(router)
self.name = name
self.path = Path(path)
self._dispatcher = dispatcher
self._router: Router | None = router
self._parent_router: Router | None = router.parent_router if router else None
self._is_restarting: bool = False
self._is_loaded: bool = False
self._saved_index: int | None = None
@property
def priority(self) -> int:
"""Get router loading priority
:return: Integer from -inf to +inf
:rtype: int
"""
if isinstance(self._router, RaitoRouter):
return self._router.priority
return 0
@property
def autoload(self) -> bool:
"""Should router autoload
:return: True if autload is turned on, otherwise False
:rtype: bool
"""
if isinstance(self._router, RaitoRouter):
return self._router.autoload
return True
@property
def is_loaded(self) -> bool:
"""Check whether the router is currently loaded.
:return: True if the router has been loaded and registered into the dispatcher
:rtype: bool
"""
return self._is_loaded
@property
def is_restarting(self) -> bool:
"""Check whether the router is currently being reloaded.
:return: True if a reload operation is in progress
:rtype: bool
"""
return self._is_restarting
@property
def router(self) -> Router:
"""Get or load the router instance.
:return: The router instance
:rtype: aiogram.Router | raito.Router
"""
if self._router is None:
self._router = self.extract_router(self.path)
self._router.name = self.name
return self._router
[документация]
def load(self) -> None:
"""Load and register the router."""
if router := self.router:
if self._parent_router:
self._link_to_parent(self._parent_router)
self._dispatcher.include_router(router)
if self._saved_index is not None:
self._dispatcher.sub_routers.remove(router)
self._dispatcher.sub_routers.insert(self._saved_index, router)
self._saved_index = None
self._is_loaded = True
[документация]
def unload(self) -> None:
"""Unload and unregister the router."""
if self._router is not None:
if self._router in self._dispatcher.sub_routers:
self._saved_index = self._dispatcher.sub_routers.index(self._router)
self._dispatcher.sub_routers.remove(self._router)
else:
self._saved_index = None
self._unlink_from_parent()
self._router = None
self._is_loaded = False
[документация]
async def reload(self, timeout: float | None = None) -> None:
"""Reload the router with optional delay.
:param timeout: Delay in seconds before reloading, defaults to None
:type timeout: float | None, optional
"""
if not self._is_restarting:
self._is_restarting = True
try:
self.unload()
if timeout:
await sleep(timeout)
self.load()
finally:
self._is_restarting = False