From e6fdacd2f4246dee1e317de78d85b4307a1ebf4c Mon Sep 17 00:00:00 2001 From: Davte Date: Thu, 14 May 2020 15:32:06 +0200 Subject: [PATCH] Allow language-labelled commands --- davtelepot/__init__.py | 2 +- davtelepot/bot.py | 39 ++++++++++++++++++++++++++++++++++----- davtelepot/helper.py | 17 ++++++++++------- davtelepot/languages.py | 40 +++++++++++++++++++++------------------- 4 files changed, 66 insertions(+), 32 deletions(-) diff --git a/davtelepot/__init__.py b/davtelepot/__init__.py index f0b5941..a810614 100644 --- a/davtelepot/__init__.py +++ b/davtelepot/__init__.py @@ -11,7 +11,7 @@ __author__ = "Davide Testa" __email__ = "davide@davte.it" __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"] __license__ = "GNU General Public License v3.0" -__version__ = "2.5.11" +__version__ = "2.5.12" __maintainer__ = "Davide Testa" __contact__ = "t.me/davte" diff --git a/davtelepot/bot.py b/davtelepot/bot.py index 3fe3a37..c47c8bd 100644 --- a/davtelepot/bot.py +++ b/davtelepot/bot.py @@ -43,7 +43,7 @@ import re import sys from collections import OrderedDict -from typing import Callable +from typing import Callable, Union, Dict # Third party modules from aiohttp import web @@ -2100,10 +2100,14 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): help_section['authorization_level'] = 'admin' self.messages['help_sections'][help_section['name']] = help_section - def command(self, command, aliases=None, reply_keyboard_button=None, + def command(self, + command: Union[str, Dict[str, str]], + aliases=None, + reply_keyboard_button=None, show_in_keyboard=False, description="", help_section=None, - authorization_level='admin'): + authorization_level='admin', + language_labelled_commands: Dict[str, str] = None): """Associate a bot command with a custom handler function. Decorate command handlers like this: @@ -2114,7 +2118,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): ``` When a message text starts with `/command[@bot_name]`, or with an alias, it gets passed to the decorated function. - `command` is the command name (with or without /). + `command` is the command name (with or without /). Language-labeled + commands are supported in the form of {'en': 'command', ...} `aliases` is a list of aliases; each will call the command handler function; the first alias will appear as button in reply keyboard if `reply_keyboard_button` is not set. @@ -2142,7 +2147,30 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): } `authorization_level` is the lowest authorization level needed to run the command. + + For advanced examples see `davtelepot.helper` or other modules + (suggestions, administration_tools, ...). """ + if language_labelled_commands is None: + language_labelled_commands = dict() + # Handle language-labelled commands: + # choose one main command and add others to `aliases` + if isinstance(command, dict) and len(command) > 0: + language_labelled_commands = command.copy() + if 'main' in language_labelled_commands: + command = language_labelled_commands['main'] + elif self.default_language in language_labelled_commands: + command = language_labelled_commands[self.default_language] + else: + for command in language_labelled_commands.values(): + break + if aliases is None: + aliases = [] + aliases += [ + alias + for alias in language_labelled_commands.values() + if alias != command + ] if not isinstance(command, str): raise TypeError(f'Command `{command}` is not a string') if isinstance(reply_keyboard_button, dict): @@ -2192,7 +2220,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject): self.commands[command] = dict( handler=decorated_command_handler, description=description, - authorization_level=authorization_level + authorization_level=authorization_level, + language_labelled_commands=language_labelled_commands ) if type(description) is dict: self.messages['commands'][command] = dict( diff --git a/davtelepot/helper.py b/davtelepot/helper.py index d31c5ac..ae0e378 100644 --- a/davtelepot/helper.py +++ b/davtelepot/helper.py @@ -1,16 +1,15 @@ """Make a self-consistent bot help section.""" -# Third party modules -from davtelepot.utilities import ( +# Project modules +from .bot import Bot +from .messages import default_help_messages +from .utilities import ( get_cleaned_text, make_inline_keyboard, make_lines_of_buttons, make_button ) -# Project modules -from .messages import default_help_messages - -def get_commands_description(bot, update, user_record): +def get_commands_description(bot: Bot, update, user_record): """Get a string description of `bot` commands. Show only commands available for `update` sender. @@ -31,7 +30,11 @@ def get_commands_description(bot, update, user_record): commands[command_role.code] = [] commands[command_role.code].append( "/{command}{authorization_level}: {description}".format( - command=command, + command=bot.get_message( + messages=details['language_labelled_commands'], + default_message=command, + user_record=user_record, update=update + ), authorization_level=( f" [{command_role.plural}]" if command_role.code != bot.Role.default_role_code diff --git a/davtelepot/languages.py b/davtelepot/languages.py index 7b874ac..1ba554f 100644 --- a/davtelepot/languages.py +++ b/davtelepot/languages.py @@ -140,26 +140,9 @@ class MultiLanguageObject(object): result = messages or self.messages for field in fields: if field not in result: - logging.debug( - "Please define self.message{f}".format( - f=''.join( - '[\'{field}\']'.format( - field=field - ) - for field in fields - ) - ) - ) - return default_message or self.missing_message - result = result[field] - if language not in result: - # For specific languages, try generic ones - language = language.partition('-')[0] - if language not in result: - language = 'en' - if language not in result: + if not default_message: logging.debug( - "Please define self.message{f}['en']".format( + "Please define self.message{f}".format( f=''.join( '[\'{field}\']'.format( field=field @@ -168,6 +151,25 @@ class MultiLanguageObject(object): ) ) ) + return default_message or self.missing_message + result = result[field] + if language not in result: + # For specific languages, try generic ones + language = language.partition('-')[0] + if language not in result: + language = 'en' + if language not in result: + if not default_message: + logging.debug( + "Please define self.message{f}['en']".format( + f=''.join( + '[\'{field}\']'.format( + field=field + ) + for field in fields + ) + ) + ) return default_message or self.missing_message if type(result) is str: return result