104 lines
3.0 KiB
Python
104 lines
3.0 KiB
Python
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Any, Union
|
|
|
|
|
|
class FilesPathWrapper(ABC):
|
|
@abstractmethod
|
|
def to_local(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def to_server(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
pass
|
|
|
|
|
|
class BareFilesPathWrapper(FilesPathWrapper):
|
|
def to_local(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
return path
|
|
|
|
def to_server(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
return path
|
|
|
|
|
|
class SimpleFilesPathWrapper(FilesPathWrapper):
|
|
def __init__(self, server_path: Path, local_path: Path) -> None:
|
|
self.server_path = server_path
|
|
self.local_path = local_path
|
|
|
|
@classmethod
|
|
def _resolve(
|
|
cls, base1: Union[Path, str], base2: Union[Path, str], value: Union[Path, str]
|
|
) -> Path:
|
|
relative = Path(value).relative_to(base1)
|
|
return base2 / relative
|
|
|
|
def to_local(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
return self._resolve(base1=self.server_path, base2=self.local_path, value=path)
|
|
|
|
def to_server(self, path: Union[Path, str]) -> Union[Path, str]:
|
|
return self._resolve(base1=self.local_path, base2=self.server_path, value=path)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TelegramAPIServer:
|
|
"""
|
|
Base config for API Endpoints
|
|
"""
|
|
|
|
base: str
|
|
"""Base URL"""
|
|
file: str
|
|
"""Files URL"""
|
|
is_local: bool = False
|
|
"""Mark this server is
|
|
in `local mode <https://core.telegram.org/bots/api#using-a-local-bot-api-server>`_."""
|
|
wrap_local_file: FilesPathWrapper = BareFilesPathWrapper()
|
|
"""Callback to wrap files path in local mode"""
|
|
|
|
def api_url(self, token: str, method: str) -> str:
|
|
"""
|
|
Generate URL for API methods
|
|
|
|
:param token: Bot token
|
|
:param method: API method name (case insensitive)
|
|
:return: URL
|
|
"""
|
|
return self.base.format(token=token, method=method)
|
|
|
|
def file_url(self, token: str, path: Union[str, Path]) -> str:
|
|
"""
|
|
Generate URL for downloading files
|
|
|
|
:param token: Bot token
|
|
:param path: file path
|
|
:return: URL
|
|
"""
|
|
return self.file.format(token=token, path=path)
|
|
|
|
@classmethod
|
|
def from_base(cls, base: str, **kwargs: Any) -> "TelegramAPIServer":
|
|
"""
|
|
Use this method to auto-generate TelegramAPIServer instance from base URL
|
|
|
|
:param base: Base URL
|
|
:return: instance of :class:`TelegramAPIServer`
|
|
"""
|
|
base = base.rstrip("/")
|
|
return cls(
|
|
base=f"{base}/bot{{token}}/{{method}}",
|
|
file=f"{base}/file/bot{{token}}/{{path}}",
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
PRODUCTION = TelegramAPIServer(
|
|
base="https://api.telegram.org/bot{token}/{method}",
|
|
file="https://api.telegram.org/file/bot{token}/{path}",
|
|
)
|
|
TEST = TelegramAPIServer(
|
|
base="https://api.telegram.org/bot{token}/test/{method}",
|
|
file="https://api.telegram.org/file/bot{token}/test/{path}",
|
|
)
|