Source code for telegram_bot_discussion.button.button
from abc import ABC, abstractmethod
from datetime import timedelta
from typing import Type, Union
from telegram import InlineKeyboardButton, Update
from telegram.ext import CallbackContext
from .button_meta import ButtonMeta, ACTION, LIFE_TIME, TITLE
from .coder_interface import CoderInterface
from .params import Params
[docs]
class Button(ABC):
"""`Button` is base class for creating `Telegram-button`."""
_title: str
chat_id: int
recipient_id: int
params: Params
""" Params: its values need to be stored in button."""
def __init__(
self,
chat_id: int,
recipient_id: int = None,
**kwargs,
):
self.chat_id = chat_id
if recipient_id is None:
recipient_id = chat_id
self.recipient_id = recipient_id
[docs]
@classmethod
@abstractmethod
async def on_click(
cls,
update: Update,
context: CallbackContext,
):
"""Reaction to a user’s button click"""
...
[docs]
@classmethod
def life_time(cls) -> Union[timedelta, None]:
return getattr(cls.Meta, LIFE_TIME, None)
[docs]
def get_title(self) -> str:
if getattr(self, "_title", None):
return getattr(self, "_title")
if getattr(self.__class__.Meta, TITLE, None):
return getattr(self.__class__.Meta, TITLE)
return self.__class__.__name__
[docs]
def set_title(self, title: str) -> "Button":
"""Method for force set `Telegram-button` title"""
self._title = title
return self
[docs]
def equals(
self,
other: Union[Type["Button"], InlineKeyboardButton],
callback_data_coder: CoderInterface,
) -> bool:
"""Method for comparing a `Button` object with another `Button` object or a native `Telegram-button` (e.g. `InlineKeyboardButton`)."""
if not isinstance(other, (self.__class__, InlineKeyboardButton)):
return False
if isinstance(other, self.__class__):
return self.params == other.params
if isinstance(other, InlineKeyboardButton):
if isinstance(other.callback_data, str):
deserialized_values_of_other = (
callback_data_coder.fetch_deserialized_data(other.callback_data)
)
try:
return self.params == self.params.__class__.create(
deserialized_values_of_other
)
except IndexError as _:
return False
return False
[docs]
def as_button(
self,
callback_data_coder: CoderInterface,
) -> InlineKeyboardButton:
"""Method for create `Telegram-button`"""
serialized_data = callback_data_coder.serialize(
*self.params.values(),
)
signature = callback_data_coder.get_signature(
self.chat_id,
serialized_data,
self.recipient_id,
)
callback_data = callback_data_coder.sign(
signature,
serialized_data,
)
return InlineKeyboardButton(
self.get_title(),
callback_data=callback_data,
)