Source code for telegram_bot_discussion.button.params.params

from typing import Self, Tuple, TypeVar, Union


from telegram import CallbackQuery


from ..coder_interface import CoderInterface


T = TypeVar("T", bound="Params")


[docs] class Params: """ `Telegram-button` callback query stores some data. When the User clicks the button, this data is returned to the bot. So, `Params` formalizes storing more than one value in the callback query and fetching it after the button click. """ action: str """ str: All params must be associated with some actions, which are used for handlers reaction route..""" def __new__(cls, action, **kwargs): if getattr(cls, "keys", None) is None: raise Exception(f"classmethod `keys()` not defined in class {cls}") if getattr(cls, "create", None) is None: raise Exception(f"classmethod `create()` not defined in class {cls}") if getattr(cls, "fetch", None) is None: raise Exception(f"classmethod `fetch()` not defined in class {cls}") if cls.keys()[0] != "action": raise Exception(f"first `{cls.__name__}.keys()` item must be `action`") self = super().__new__(cls) self.action = action return self
[docs] @classmethod def fetch( cls, callback_query: Union[CallbackQuery, None], coder: CoderInterface, ) -> Self: """ Fetch data from `Telegram-button` callback query into a special structure named `Params`. :param callback_query: `Telegram-button` callback query data :param coder: algorithm of serializing and deserializing stored in a `Telegram-button` data :raises CallbackQueryIsNone: when `Telegram-button` has no callback query :raises CallbackQueryDataIsNone: when `Telegram-button` has empty callback query """ if not callback_query: raise CallbackQueryIsNone() if not callback_query.data: raise CallbackQueryDataIsNone() params_values = coder.fetch_deserialized_data(callback_query.data) return cls.create(params_values)
[docs] @classmethod def create(cls, fields_values): kwargs = dict() for i in range(0, len(cls.keys())): kwargs[cls.keys()[i]] = fields_values[i] return cls(**kwargs)
[docs] @classmethod def keys(cls) -> Tuple[str, ...]: list_of_attrs = set(cls.__annotations__.keys()) for i in cls.__mro__[1:]: list_of_super_me = ( getattr(i, "keys")() if getattr(i, "keys", None) and callable(getattr(i, "keys")) else [] ) list_of_attrs = list_of_attrs.union(list_of_super_me) list_of_attrs = list(list_of_attrs) if "action" in list_of_attrs: list_of_attrs.remove("action") list_of_attrs.sort() list_of_attrs.insert(0, "action") return tuple(list_of_attrs)
[docs] def set_action(self, action: str) -> "Params": self.action = action return self
[docs] def get_action(self) -> str: return self.action
[docs] def values(self) -> tuple: return tuple(getattr(self, x) for x in self.keys())
def __str__(self) -> str: return str(self.values()) def __eq__(self, other: object) -> bool: if not isinstance(other, self.__class__): return False self_values = self.values() other_values = other.values() return self_values == other_values
[docs] class CallbackQueryDataIsNone(Exception): def __str__(self) -> str: return "CallbackQuery-data is None"
[docs] class CallbackQueryIsNone(Exception): def __str__(self) -> str: return "CallbackQuery is None"