Files

182 lines
5.1 KiB
Python

from string import Template
from typing import TYPE_CHECKING
from aiogram.enums import ParseMode, PollType
from aiogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboardMarkup
from ..utils import get_plural_form, key_from_poll, key_from_user_chat
from .base import BaseTask, VerificationCallback, mute_while_task
from .utils import user_mention
if TYPE_CHECKING:
from aiogram import Bot
class SimpleBaseTask(BaseTask):
pass
class SimpleVariantsBaseTaskConfig:
def __init__(self, task_type, config: dict):
self.config = config
self.task_type = task_type
@property
def timeout(self):
timeout = self.config.get(f"welcome::tasks::{self.task_type}::timeout")
if timeout is None:
return self.config.get("welcome::timeout")
return timeout
@property
def task_message_text(self):
return self.config.get(f"welcome::tasks::{self.task_type}::message_text")
@property
def task_retry_message_text(self):
return self.config.get(f"welcome::tasks::{self.task_type}::retry_message_text")
class SimpleVariantsBaseTask(SimpleBaseTask):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.config = None
self.variants = []
self.task = ""
self.correct = None
self.task_message_id = None
def set_config(self, cfg: SimpleVariantsBaseTaskConfig):
self.config = cfg
def get_timeout(self):
return self.config.timeout
@mute_while_task
class SimpleInlineButtonsTask(SimpleVariantsBaseTask):
async def init(self):
raise NotImplementedError()
def build_keyboard(self):
return InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=str(option),
callback_data=VerificationCallback(
user_id=self.from_user_id,
chat_id=self.from_chat_id,
answer=str(option),
).pack(),
)
for option in self.variants
]
]
)
async def run(self):
await self.init()
message_template = Template(
self.config.task_message_text
if self.attempt_number == 1
else self.config.task_retry_message_text
)
chat_id = self.from_chat_id
message = await self.bot.send_message(
chat_id,
text=message_template.substitute(
mention=user_mention(self.from_user),
task=self.task,
attempts=get_plural_form(
self.attemps_left, "попытка", "попытки", "попыток"
),
),
reply_markup=self.build_keyboard(),
parse_mode=ParseMode.HTML,
)
self.task_message_id = message.message_id
await self.start_timeout_func()
return [key_from_user_chat(self.from_user_id, self.from_chat_id)]
async def verify(self, data):
return self.correct == data
async def end(self, success=True):
await self.bot.delete_message(self.from_chat_id, self.task_message_id)
if self.timeout_func_task:
self.timeout_func_task.cancel()
@mute_while_task
class SimplePollTask(SimpleVariantsBaseTask):
def __init__(
self,
event: ChatMemberUpdated,
bot: "Bot",
timeout_func=None,
attempt_number=1,
max_attempts=1,
):
super().__init__(event, bot, timeout_func, attempt_number, max_attempts)
self.correct_index = None
async def init(self):
raise NotImplementedError()
async def run(self):
await self.init()
self.correct_index = self.variants.index(self.correct)
message_template = Template(
self.config.task_message_text
if self.attempt_number == 1
else self.config.task_retry_message_text
)
chat_id = self.from_chat_id
message = await self.bot.send_poll(
chat_id,
question=message_template.substitute(
mention=self.from_user.first_name,
task=self.task,
attempts=get_plural_form(
self.attemps_left, "попытка", "попытки", "попыток"
),
),
options=self.variants,
type=PollType.QUIZ,
correct_option_id=self.correct_index,
allows_multiple_answers=False,
is_anonymous=False,
# parse_mode=ParseMode.HTML
)
self.task_message_id = message.message_id
await self.start_timeout_func()
return [
key_from_poll(message.poll.id),
key_from_user_chat(self.from_user_id, self.from_chat_id),
]
async def verify(self, data):
return self.correct_index == data
async def end(self, success=True):
await self.bot.delete_message(self.from_chat_id, self.task_message_id)
if self.timeout_func_task:
self.timeout_func_task.cancel()