Недавно встала передо мной задача сделать пагинацию списка элементов в телеграм боте. И с удивлением обнаружила, что для такой, казалось бы типовой задачи в PyPi нет ни одной библиотеки. Поэтому решено было исправить это досадное упущение и опубликовать свою реализацию.
Установить пакет можно из PyPi, выполнив в консоли:
pip install python-telegram-bot-pagination
Класс InlineKeyboardPaginator из пакета telegram_bot_pagination позволяет легко получить набор inline-кнопок для перемещения по страницам списка. В конструктор необходимо передать количество страниц, на которое разбит список элементов, а так же текущую страницу и паттерн для формирования данных, возвращаемых по нажатию на кнопку боту. После чего пагинатор сам сформирует необходимую клавиатуру, которая будет доступна через свойство markup.
from telegram_bot_pagination import InlineKeyboardPaginator
paginator = InlineKeyboardPaginator(
10,
current_page=1,
data_pattern='elements#{page}'
)
Теперь paginator.markup вернет json объект для поля reply_markup метода sendMessage Telegram Bot API. В данном случае будет сформированы пять кнопок. Если количество страниц пять или меньше, то кнопок будет соответственно. Если страница только одна, то markup будет пустым. В случае же если страниц больше пяти, то клавиатура будет содержать 5 кнопок для:
- первой страницы;
- предыдущей страницы;
- текущей страницы;
- следующей страницы;
- последней страницы.
Например, если есть массив character_pages, содержащей описания персонажей Гарри Поттера для создания бота, который показывает листаемый список персонажей, нам понадобиться функция отправляющая текущею страницу списка:
def send_character_page(message, page=1):
paginator = InlineKeyboardPaginator(
len(character_pages),
current_page=page,
data_pattern='character#{page}'
)
bot.send_message(
message.chat.id,
character_pages[page-1],
reply_markup=paginator.markup,
parse_mode='Markdown'
)
И обработчик нажатия кнопок в боте:
@bot.callback_query_handler(func=lambda call: call.data.split('#')[0]=='character')
def characters_page_callback(call):
page = int(call.data.split('#')[1])
bot.delete_message(
call.message.chat.id,
call.message.message_id
)
send_character_page(call.message, page)
*В примере используется pyTelegramBotAPI для работы с ботом.
Полный код примера можно посмотреть здесь.
Результат в зависимости от количества записей в списке будет выглядеть следующим образом:
Спасибо за внимание. Буду руда любой конструктивной критике.
pure_intelligence