Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 76 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@

Provide easy way for create number pagination with inline keyboard for telegram bot on python.

**InlineKeyboardPaginator**

[Example](https://github.com/ksinn/python-telegram-bot-pagination/blob/master/examples/example.py) with [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI)

[Example](https://github.com/ksinn/python-telegram-bot-pagination/blob/master/examples/example2.py) with [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot)

![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/ex1.png) ![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/f1.jpg)

**InlineKeyboardSimplePaginator**

This paginator can be used similarly to InlineKeyboardPaginator.

It is suitable when page numbers are not as important to us as the ability to quickly view them and scroll around page
(e.g. when you click the next page button on the last one, the first page will open).

[Example](https://github.com/ksinn/python-telegram-bot-pagination/blob/master/examples/example3.py) with [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot)

![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/simple_2.png) ![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/simple_1.png)

---
* [Installation.](#installation)
* [Usage.](#usage)
* [Button render controlling.](#button-render-controlling)
Expand All @@ -21,20 +35,30 @@ Provide easy way for create number pagination with inline keyboard for telegram
pip install python-telegram-bot-pagination

#### Usage
from telegram_bot_pagination import InlineKeyboardPaginator

paginator = InlineKeyboardPaginator(
page_count,
current_page=page,
data_pattern='page#{page}'
)

bot.send_message(
chat_id,
text,
reply_markup=paginator.markup,
)

```python3
from telegram_bot_pagination import InlineKeyboardPaginator, InlineKeyboardSimplePaginator

paginator = InlineKeyboardPaginator(
page_count,
current_page=page,
data_pattern='page#{page}'
)

# you can use two types of Pagianators in a similar way
simple_paginator = InlineKeyboardSimplePaginator(
page_count,
current_page=page,
data_pattern='page#{page}'
)
```
```python3
bot.send_message(
chat_id,
text,
reply_markup=paginator.markup,
)
```

Init arguments:
* page_count - integer, total 1-based pages count.
Expand All @@ -48,28 +72,45 @@ Properties:
#### Button render controlling
For edit button render, use paginator object properties:

* first_page_label
* previous_page_label
* current_page_label
* next_page_label
* last_page_label
| InlineKeyboardPaginator | InlineKeyboardSimplePaginator |
|-------------------------|-------------------------------|
| previous_page_label | previous_page_label |
| current_page_label | current_page_label |
| next_page_label | next_page_label |
| first_page_label | - |
| last_page_label | - |


All of them can by python style formatting string with one arg, or simple string.

For example:
```python3
class MyPaginator(InlineKeyboardPaginator):
first_page_label = '<<'
previous_page_label = '<'
current_page_label = '-{}-'
next_page_label = '>'
last_page_label = '>>'

paginator = MyPaginator(page_count)
```
```python3
class MyPaginator(InlineKeyboardSimplePaginator):
previous_page_label = '<'
current_page_label = '{}-{}'
next_page_label = '>'

paginator = MyPaginator(page_count)
```
Results:

InlineKeyboardPaginator

class MyPaginator(InlineKeyboardPaginator):
first_page_label = '<<'
previous_page_label = '<'
current_page_label = '-{}-'
next_page_label = '>'
last_page_label = '>>'
![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/m2.jpg)

paginator = MyPaginator(page_count)
InlineKeyboardSimplePaginator

Result:

![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/m2.jpg)
![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/simple_3.png)

#### Adding extra button
For adding button line before and after pagination use methods:
Expand All @@ -80,16 +121,16 @@ For adding button line before and after pagination use methods:
Each argument mast provide property 'text' and 'callback_data'

For example:
```python3
paginator.add_before(
InlineKeyboardButton('Like', callback_data='like#{}'.format(page)),
InlineKeyboardButton('Dislike', callback_data='dislike#{}'.format(page))
)
paginator.add_after(InlineKeyboardButton('Go back', callback_data='back'))

paginator.add_before(
InlineKeyboardButton('Like', callback_data='like#{}'.format(page)),
InlineKeyboardButton('Dislike', callback_data='dislike#{}'.format(page))
)
paginator.add_after(InlineKeyboardButton('Go back', callback_data='back'))
```

Result:

![](https://github.com/ksinn/python-telegram-bot-pagination/raw/master/examples/media/ex1.png)



65 changes: 65 additions & 0 deletions examples/example3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import logging

from telegram import InlineKeyboardButton
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
from telegram_bot_pagination import InlineKeyboardSimplePaginator

from data import character_pages

logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO
)


def start(update, context):

paginator = InlineKeyboardSimplePaginator(
len(character_pages),
data_pattern='character#{page}'
)

update.message.reply_text(
text=character_pages[0],
reply_markup=paginator.markup,
parse_mode='Markdown'
)


def characters_page_callback(update, context):
query = update.callback_query

query.answer()

page = int(query.data.split('#')[1])

paginator = InlineKeyboardSimplePaginator(
len(character_pages),
current_page=page,
data_pattern='character#{page}'
)

paginator.add_before(
InlineKeyboardButton('Like', callback_data='like#{}'.format(page)),
InlineKeyboardButton('Dislike', callback_data='dislike#{}'.format(page))
)
paginator.add_after(InlineKeyboardButton('Go back', callback_data='back'))

query.edit_message_text(
text=character_pages[page - 1],
reply_markup=paginator.markup,
parse_mode='Markdown'
)


updater = Updater(os.getenv('BOT_TOKEN'), use_context=True)

updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(characters_page_callback, pattern='^character#'))

updater.start_polling()
updater.idle()

Binary file added examples/media/simple_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/media/simple_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/media/simple_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 58 additions & 10 deletions telegram_bot_pagination/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ def __init__(self, page_count, current_page=1, data_pattern='{page}'):
self._keyboard_before = list()
self._keyboard_after = list()

if current_page is None or current_page < 1:
current_page = 1
if current_page > page_count:
current_page = page_count
self.current_page = current_page

self.page_count = page_count

self.data_pattern = data_pattern

if current_page is None or current_page < 1:
self.current_page = 1
if current_page > page_count:
self.current_page = page_count

def _build(self):
keyboard_dict = dict()

Expand Down Expand Up @@ -139,10 +138,8 @@ def __str__(self):
def add_before(self, *inline_buttons):
"""
Add buttons as line above pagination buttons.

Args:
inline_buttons (:object:`iterable`): List of object with attributes `text` and `callback_data`.

Returns:
None
"""
Expand All @@ -151,16 +148,67 @@ def add_before(self, *inline_buttons):
def add_after(self, *inline_buttons):
"""
Add buttons as line under pagination buttons.

Args:
inline_buttons (:object:`iterable`): List of object with attributes 'text' and 'callback_data'.

Returns:
None
"""
self._keyboard_after.append(_buttons_to_dict(inline_buttons))


class InlineKeyboardSimplePaginator(InlineKeyboardPaginator):
previous_page_label = '‹‹'
next_page_label = '››'
current_page_label = '{}/{}'

def __init__(self, page_count, current_page=1, data_pattern='{page}'):
super().__init__(page_count, current_page, data_pattern)

if current_page is None or current_page < 1:
self.current_page = page_count

if current_page > page_count:
self.current_page = 1

def _build(self):
if self.page_count == 1:
self._keyboard = list()
else:
keyboard_dict = self._build_keyboard()
self._keyboard = self._to_button_array(keyboard_dict)

def _build_keyboard(self):
keyboard_dict = dict()

if self.current_page - 1 < 1:
keyboard_dict[self.page_count] = self.previous_page_label
else:
keyboard_dict[self.current_page-1] = self.previous_page_label

keyboard_dict[self.current_page] = self.current_page_label.format(self.current_page, self.page_count)

if self.current_page + 1 > self.page_count:
keyboard_dict[1] = self.next_page_label
else:
keyboard_dict[self.current_page+1] = self.next_page_label

return keyboard_dict

def _to_button_array(self, keyboard_dict):
keyboard = list()

keys = list(keyboard_dict.keys())

for key in keys:
keyboard.append(
InlineKeyboardButton(
text=str(keyboard_dict[key]),
callback_data=self.data_pattern.format(page=key)
)
)
return _buttons_to_dict(keyboard)


def _buttons_to_dict(buttons):
return [
{
Expand Down