From 0c8e94d2c6fd1e759daddab11436185be9490826 Mon Sep 17 00:00:00 2001 From: abdullaev388 Date: Thu, 10 Feb 2022 13:43:19 +0500 Subject: [PATCH] advanced usage of callbackdata was added --- .../advanced_calendar_example/filters.py | 25 +++++ .../advanced_calendar_example/keyboards.py | 92 +++++++++++++++++++ .../advanced_calendar_example/main.py | 56 +++++++++++ 3 files changed, 173 insertions(+) create mode 100644 examples/callback_data_examples/advanced_calendar_example/filters.py create mode 100644 examples/callback_data_examples/advanced_calendar_example/keyboards.py create mode 100644 examples/callback_data_examples/advanced_calendar_example/main.py diff --git a/examples/callback_data_examples/advanced_calendar_example/filters.py b/examples/callback_data_examples/advanced_calendar_example/filters.py new file mode 100644 index 0000000..e48f406 --- /dev/null +++ b/examples/callback_data_examples/advanced_calendar_example/filters.py @@ -0,0 +1,25 @@ +import telebot +from telebot import types, AdvancedCustomFilter +from telebot.callback_data import CallbackData, CallbackDataFilter + +calendar_factory = CallbackData("year", "month", prefix="calendar") +calendar_zoom = CallbackData("year", prefix="calendar_zoom") + + +class CalendarCallbackFilter(AdvancedCustomFilter): + key = 'calendar_config' + + def check(self, call: types.CallbackQuery, config: CallbackDataFilter): + return config.check(query=call) + + +class CalendarZoomCallbackFilter(AdvancedCustomFilter): + key = 'calendar_zoom_config' + + def check(self, call: types.CallbackQuery, config: CallbackDataFilter): + return config.check(query=call) + + +def bind_filters(bot: telebot.TeleBot): + bot.add_custom_filter(CalendarCallbackFilter()) + bot.add_custom_filter(CalendarZoomCallbackFilter()) diff --git a/examples/callback_data_examples/advanced_calendar_example/keyboards.py b/examples/callback_data_examples/advanced_calendar_example/keyboards.py new file mode 100644 index 0000000..46ffde1 --- /dev/null +++ b/examples/callback_data_examples/advanced_calendar_example/keyboards.py @@ -0,0 +1,92 @@ +import calendar +from datetime import date, timedelta + +from examples.callback_data_examples.advanced_calendar_example.filters import calendar_factory, calendar_zoom +from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton + +EMTPY_FIELD = '1' +WEEK_DAYS = [calendar.day_abbr[i] for i in range(7)] +MONTHS = [(i, calendar.month_name[i]) for i in range(1, 13)] + + +def generate_calendar_days(year: int, month: int): + keyboard = InlineKeyboardMarkup(row_width=7) + today = date.today() + + keyboard.add( + InlineKeyboardButton( + text=date(year=year, month=month, day=1).strftime('%b %Y'), + callback_data=EMTPY_FIELD + ) + ) + keyboard.add(*[ + InlineKeyboardButton( + text=day, + callback_data=EMTPY_FIELD + ) + for day in WEEK_DAYS + ]) + + for week in calendar.Calendar().monthdayscalendar(year=year, month=month): + week_buttons = [] + for day in week: + day_name = ' ' + if day == today.day and today.year == year and today.month == month: + day_name = '🔘' + elif day != 0: + day_name = str(day) + week_buttons.append( + InlineKeyboardButton( + text=day_name, + callback_data=EMTPY_FIELD + ) + ) + keyboard.add(*week_buttons) + + previous_date = date(year=year, month=month, day=1) - timedelta(days=1) + next_date = date(year=year, month=month, day=1) + timedelta(days=31) + + keyboard.add( + InlineKeyboardButton( + text='Previous month', + callback_data=calendar_factory.new(year=previous_date.year, month=previous_date.month) + ), + InlineKeyboardButton( + text='Zoom out', + callback_data=calendar_zoom.new(year=year) + ), + InlineKeyboardButton( + text='Next month', + callback_data=calendar_factory.new(year=next_date.year, month=next_date.month) + ), + ) + + return keyboard + + +def generate_calendar_months(year: int): + keyboard = InlineKeyboardMarkup(row_width=3) + keyboard.add( + InlineKeyboardButton( + text=date(year=year, month=1, day=1).strftime('Year %Y'), + callback_data=EMTPY_FIELD + ) + ) + keyboard.add(*[ + InlineKeyboardButton( + text=month, + callback_data=calendar_factory.new(year=year, month=month_number) + ) + for month_number, month in MONTHS + ]) + keyboard.add( + InlineKeyboardButton( + text='Previous year', + callback_data=calendar_zoom.new(year=year - 1) + ), + InlineKeyboardButton( + text='Next year', + callback_data=calendar_zoom.new(year=year + 1) + ) + ) + return keyboard diff --git a/examples/callback_data_examples/advanced_calendar_example/main.py b/examples/callback_data_examples/advanced_calendar_example/main.py new file mode 100644 index 0000000..8ccf469 --- /dev/null +++ b/examples/callback_data_examples/advanced_calendar_example/main.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +""" +This Example will show you an advanced usage of CallbackData. +In this example calendar was implemented +""" + +from datetime import date + +from examples.callback_data_examples.advanced_calendar_example.keyboards import generate_calendar_days, \ + generate_calendar_months, EMTPY_FIELD +from filters import calendar_factory, calendar_zoom, bind_filters +from telebot import types, TeleBot + +API_TOKEN = '' +bot = TeleBot(API_TOKEN) + + +@bot.message_handler(commands='start') +def start_command_handler(message: types.Message): + bot.send_message(message.chat.id, + f"Hello {message.from_user.first_name}. This bot is an example of calendar keyboard." + "\nPress /calendar to see it.") + + +@bot.message_handler(commands='calendar') +def calendar_command_handler(message: types.Message): + now = date.today() + bot.send_message(message.chat.id, 'Calendar', reply_markup=generate_calendar_days(year=now.year, month=now.month)) + + +@bot.callback_query_handler(func=None, calendar_config=calendar_factory.filter()) +def calendar_action_handler(call: types.CallbackQuery): + callback_data: dict = calendar_factory.parse(callback_data=call.data) + year, month = int(callback_data['year']), int(callback_data['month']) + + bot.edit_message_reply_markup(call.message.chat.id, call.message.id, + reply_markup=generate_calendar_days(year=year, month=month)) + + +@bot.callback_query_handler(func=None, calendar_zoom_config=calendar_zoom.filter()) +def calendar_zoom_out_handler(call: types.CallbackQuery): + callback_data: dict = calendar_zoom.parse(callback_data=call.data) + year = int(callback_data.get('year')) + + bot.edit_message_reply_markup(call.message.chat.id, call.message.id, + reply_markup=generate_calendar_months(year=year)) + + +@bot.callback_query_handler(func=lambda call: call.data == EMTPY_FIELD) +def callback_empty_field_handler(call: types.CallbackQuery): + bot.answer_callback_query(call.id) + + +if __name__ == '__main__': + bind_filters(bot) + bot.infinity_polling()