Added Bot() property callback_data_separator
and method to set it
It will be used to parse callback data unless a more specific separator is passed to @Bot().button decorator. If both are None, data will be a string without prefix.
This commit is contained in:
parent
f689d9b95a
commit
e412548edf
@ -42,7 +42,7 @@ from aiohttp import web
|
|||||||
from davtelepot.api import TelegramBot, TelegramError
|
from davtelepot.api import TelegramBot, TelegramError
|
||||||
from davtelepot.database import ObjectWithDatabase
|
from davtelepot.database import ObjectWithDatabase
|
||||||
from davtelepot.utilities import (
|
from davtelepot.utilities import (
|
||||||
escape_html_chars, get_secure_key, make_inline_query_answer,
|
escape_html_chars, extract, get_secure_key, make_inline_query_answer,
|
||||||
make_lines_of_buttons, remove_html_tags
|
make_lines_of_buttons, remove_html_tags
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -168,6 +168,7 @@ class Bot(TelegramBot, ObjectWithDatabase):
|
|||||||
self.text_message_parsers = OrderedDict()
|
self.text_message_parsers = OrderedDict()
|
||||||
# Callback query-related properties
|
# Callback query-related properties
|
||||||
self.callback_handlers = OrderedDict()
|
self.callback_handlers = OrderedDict()
|
||||||
|
self._callback_data_separator = None
|
||||||
# Inline query-related properties
|
# Inline query-related properties
|
||||||
self.inline_query_handlers = OrderedDict()
|
self.inline_query_handlers = OrderedDict()
|
||||||
self._default_inline_query_answer = None
|
self._default_inline_query_answer = None
|
||||||
@ -348,6 +349,25 @@ class Bot(TelegramBot, ObjectWithDatabase):
|
|||||||
return self._unknown_command_message
|
return self._unknown_command_message
|
||||||
return self.__class__._unknown_command_message
|
return self.__class__._unknown_command_message
|
||||||
|
|
||||||
|
@property
|
||||||
|
def callback_data_separator(self):
|
||||||
|
"""Separator between callback data elements.
|
||||||
|
|
||||||
|
Example of callback_data: 'my_button_prefix:///1|4|test'
|
||||||
|
Prefix: `my_button_prefix:///`
|
||||||
|
Separator: `|` <--- this is returned
|
||||||
|
Data: `['1', '4', 'test']`
|
||||||
|
"""
|
||||||
|
return self._callback_data_separator
|
||||||
|
|
||||||
|
def set_callback_data_separator(self, separator):
|
||||||
|
"""Set a callback_data separator.
|
||||||
|
|
||||||
|
See property `callback_data_separator` for details.
|
||||||
|
"""
|
||||||
|
assert type(separator) is str, "Separator must be a string!"
|
||||||
|
self._callback_data_separator = separator
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default_inline_query_answer(self):
|
def default_inline_query_answer(self):
|
||||||
"""Answer to be returned if inline query returned None.
|
"""Answer to be returned if inline query returned None.
|
||||||
@ -1387,24 +1407,28 @@ class Bot(TelegramBot, ObjectWithDatabase):
|
|||||||
authorization_level=authorization_level
|
authorization_level=authorization_level
|
||||||
)(handler)
|
)(handler)
|
||||||
|
|
||||||
def button(self, data, description='', authorization_level='admin'):
|
def button(self, prefix, separator=None, description='',
|
||||||
"""Associate a bot button prefix (`data`) with a handler.
|
authorization_level='admin'):
|
||||||
|
"""Associate a bot button `prefix` with a handler.
|
||||||
|
|
||||||
When a callback data text starts with <data>, the associated handler is
|
When a callback data text starts with `prefix`, the associated handler
|
||||||
called upon the update.
|
is called upon the update.
|
||||||
Decorate button handlers like this:
|
Decorate button handlers like this:
|
||||||
```
|
```
|
||||||
@bot.button('a_prefix:///', "A button", 'user')
|
@bot.button('a_prefix:///', description="A button",
|
||||||
async def button_handler(bot, update, user_record):
|
authorization_level='user')
|
||||||
|
async def button_handler(bot, update, user_record, data):
|
||||||
return "Result"
|
return "Result"
|
||||||
```
|
```
|
||||||
|
`separator` will be used to parse callback data received when a button
|
||||||
|
starting with `prefix` will be pressed.
|
||||||
`description` contains information about the button.
|
`description` contains information about the button.
|
||||||
`authorization_level` is the lowest authorization level needed to
|
`authorization_level` is the lowest authorization level needed to
|
||||||
be allowed to push the button.
|
be allowed to push the button.
|
||||||
"""
|
"""
|
||||||
if not isinstance(data, str):
|
if not isinstance(prefix, str):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f'Inline button callback_data {data} is not a string'
|
f'Inline button callback_data {prefix} is not a string'
|
||||||
)
|
)
|
||||||
|
|
||||||
def button_decorator(handler):
|
def button_decorator(handler):
|
||||||
@ -1419,8 +1443,20 @@ class Bot(TelegramBot, ObjectWithDatabase):
|
|||||||
authorization_level=authorization_level
|
authorization_level=authorization_level
|
||||||
):
|
):
|
||||||
return await handler(bot, update, user_record)
|
return await handler(bot, update, user_record)
|
||||||
|
# Remove `prefix` from `ðata`
|
||||||
|
data = extract(update['data'], prefix)
|
||||||
|
# If a specific separator or default separator is set,
|
||||||
|
# use it to split `data` string in a list.
|
||||||
|
# Cast numeric `data` elements to `int`.
|
||||||
|
_separator = separator or self.callback_data_separator
|
||||||
|
if _separator:
|
||||||
|
data = [
|
||||||
|
int(element) if element.isnumeric()
|
||||||
|
else element
|
||||||
|
for element in data.split(_separator)
|
||||||
|
]
|
||||||
return bot.unauthorized_message
|
return bot.unauthorized_message
|
||||||
self.callback_handlers[data] = dict(
|
self.callback_handlers[prefix] = dict(
|
||||||
handler=decorated_button_handler,
|
handler=decorated_button_handler,
|
||||||
description=description,
|
description=description,
|
||||||
authorization_level=authorization_level
|
authorization_level=authorization_level
|
||||||
|
Loading…
x
Reference in New Issue
Block a user