Files
quickbot/bot/handlers/editors/date.py
2025-01-10 13:45:02 +01:00

172 lines
9.2 KiB
Python

from datetime import datetime, timedelta
from aiogram import Router, F
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from logging import getLogger
from typing import TYPE_CHECKING
from ....model.descriptors import EntityFieldDescriptor, EntityDescriptor
from ..context import ContextData, CallbackCommand
from ..common import get_send_message, get_field_descriptor, get_entity_descriptor
from .common import wrap_editor
if TYPE_CHECKING:
from ....main import QBotApp
logger = getLogger(__name__)
router = Router()
async def date_picker(message: Message | CallbackQuery,
field_descriptor: EntityFieldDescriptor,
callback_data: ContextData,
current_value: datetime,
state: FSMContext,
edit_prompt: str | None = None,
**kwargs):
if not current_value:
start_date = datetime.now()
else:
start_date = current_value
start_date = start_date.replace(day = 1)
previous_month = start_date - timedelta(days = 1)
next_month = start_date.replace(day = 28) + timedelta(days = 4)
keyboard_builder = InlineKeyboardBuilder()
keyboard_builder.row(InlineKeyboardButton(text = "◀️",
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_MONTH,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = previous_month.strftime("%Y-%m-%d"),
save_state = True).pack()),
InlineKeyboardButton(text = start_date.strftime("%b %Y"),
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_YEAR,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = start_date.strftime("%Y-%m-%d"),
save_state = True).pack()),
InlineKeyboardButton(text = "▶️",
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_MONTH,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = next_month.strftime("%Y-%m-%d"),
save_state = True).pack()))
first_day = start_date - timedelta(days = start_date.weekday())
weeks = (((start_date.replace(day = 28) + timedelta(days = 4)).replace(day = 1) - first_day).days - 1) // 7 + 1
for week in range(weeks):
buttons = []
for day in range(7):
current_day = first_day + timedelta(days = week * 7 + day)
buttons.append(InlineKeyboardButton(text = current_day.strftime("%d"),
callback_data = ContextData(
command = CallbackCommand.FIELD_EDITOR_CALLBACK,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = current_day.strftime("%Y-%m-%d"),
save_state = True).pack()))
keyboard_builder.row(*buttons)
state_data = kwargs["state_data"]
await wrap_editor(keyboard_builder = keyboard_builder,
field_descriptor = field_descriptor,
callback_data = callback_data,
state_data = state_data)
await state.set_data(state_data)
if edit_prompt:
send_message = get_send_message(message)
await send_message(text = edit_prompt, reply_markup = keyboard_builder.as_markup())
else:
await message.edit_reply_markup(reply_markup = keyboard_builder.as_markup())
@router.callback_query(ContextData.filter(F.command == CallbackCommand.DATE_PICKER_YEAR))
async def date_picker_year(query: CallbackQuery,
callback_data: ContextData,
app: "QBotApp",
state: FSMContext,
**kwargs):
start_date = datetime.strptime(callback_data.data, "%Y-%m-%d")
state_data = await state.get_data()
kwargs["state_data"] = state_data
keyboard_builder = InlineKeyboardBuilder()
keyboard_builder.row(InlineKeyboardButton(text = "🔼",
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_YEAR,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = start_date.replace(year = start_date.year - 20).strftime("%Y-%m-%d")).pack()))
for r in range(4):
buttons = []
for c in range(5):
current_date = start_date.replace(year = start_date.year + r * 5 + c - 10)
buttons.append(InlineKeyboardButton(text = current_date.strftime("%Y"),
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_MONTH,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = current_date.strftime("%Y-%m-%d"),
save_state = True).pack()))
keyboard_builder.row(*buttons)
keyboard_builder.row(InlineKeyboardButton(text = "🔽",
callback_data = ContextData(
command = CallbackCommand.DATE_PICKER_YEAR,
context = callback_data.context,
entity_name = callback_data.entity_name,
entity_id = callback_data.entity_id,
field_name = callback_data.field_name,
data = start_date.replace(year = start_date.year + 20).strftime("%Y-%m-%d")).pack()))
field_descriptor = get_field_descriptor(app, callback_data)
await wrap_editor(keyboard_builder = keyboard_builder,
field_descriptor = field_descriptor,
callback_data = callback_data,
state_data = state_data)
await query.message.edit_reply_markup(reply_markup = keyboard_builder.as_markup())
@router.callback_query(ContextData.filter(F.command == CallbackCommand.DATE_PICKER_MONTH))
async def date_picker_month(query: CallbackQuery, callback_data: ContextData, app: "QBotApp", **kwargs):
field_descriptor = get_field_descriptor(app, callback_data)
state: FSMContext = kwargs["state"]
state_data = await state.get_data()
kwargs["state_data"] = state_data
await date_picker(query.message,
field_descriptor = field_descriptor,
callback_data = callback_data,
current_value = datetime.strptime(callback_data.data, "%Y-%m-%d"),
**kwargs)