diff --git a/davtelepot/__init__.py b/davtelepot/__init__.py index a1b27bf..78b2544 100644 --- a/davtelepot/__init__.py +++ b/davtelepot/__init__.py @@ -14,7 +14,7 @@ __author__ = "Davide Testa" __email__ = "davide@davte.it" __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"] __license__ = "GNU General Public License v3.0" -__version__ = "2.4.5" +__version__ = "2.4.6" __maintainer__ = "Davide Testa" __contact__ = "t.me/davte" diff --git a/davtelepot/administration_tools.py b/davtelepot/administration_tools.py index ff5f18d..44d266f 100644 --- a/davtelepot/administration_tools.py +++ b/davtelepot/administration_tools.py @@ -14,6 +14,7 @@ import datetime import json # Third party modules +from davtelepot import messages from davtelepot.utilities import ( async_wrapper, Confirmator, extract, get_cleaned_text, get_user, escape_html_chars, line_drawing_unordered_list, make_button, @@ -23,110 +24,6 @@ from davtelepot.utilities import ( from sqlalchemy.exc import ResourceClosedError -default_talk_messages = dict( - admin_session_ended=dict( - en=( - 'Session with user {u} ended.' - ), - it=( - 'Sessione terminata con l\'utente {u}.' - ), - ), - admin_warning=dict( - en=( - 'You are now talking to {u}.\n' - 'Until you end this session, your messages will be ' - 'forwarded to each other.' - ), - it=( - 'Sei ora connesso con {u}.\n' - 'Finché non chiuderai la connessione, i messaggi che scriverai ' - 'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.' - ), - ), - end_session=dict( - en=( - 'End session?' - ), - it=( - 'Chiudere la sessione?' - ), - ), - help_text=dict( - en='Press the button to search for user.', - it='Premi il pulsante per scegliere un utente.' - ), - search_button=dict( - en="🔍 Search for user", - it="🔍 Cerca utente", - ), - select_user=dict( - en='Which user would you like to talk to?', - it='Con quale utente vorresti parlare?' - ), - user_not_found=dict( - en=( - "Sory, but no user matches your query for\n" - "{q}" - ), - it=( - "Spiacente, ma nessun utente corrisponde alla ricerca per\n" - "{q}" - ), - ), - instructions=dict( - en=( - 'Write a part of name, surname or username of the user you want ' - 'to talk to.' - ), - it=( - 'Scrivi una parte del nome, cognome o username dell\'utente con ' - 'cui vuoi parlare.' - ), - ), - stop=dict( - en=( - 'End session' - ), - it=( - 'Termina la sessione' - ), - ), - user_session_ended=dict( - en=( - 'Session with admin {u} ended.' - ), - it=( - 'Sessione terminata con l\'amministratore {u}.' - ), - ), - user_warning=dict( - en=( - '{u}, admin of this bot, wants to talk to you.\n' - 'Until this session is ended by {u}, your messages will be ' - 'forwarded to each other.' - ), - it=( - '{u}, amministratore di questo bot, vuole parlare con te.\n' - 'Finché non chiuderà la connessione, i messaggi che scriverai ' - 'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.' - ), - ), - # key=dict( - # en='', - # it='', - # ), - # key=dict( - # en=( - # '' - # ), - # it=( - # '' - # ), - # ), -) - - async def _forward_to(update, bot, sender, addressee, is_admin=False): if update['text'].lower() in ['stop'] and is_admin: with bot.db as db: @@ -411,7 +308,7 @@ async def end_session(bot, other_user_record, admin_record): u=get_user(other_user_record) ), ) - for record in (admin_record, other_user_record, ): + for record in (admin_record, other_user_record,): bot.remove_individual_text_message_handler(record['telegram_id']) return @@ -434,8 +331,8 @@ async def _talk_button(bot, update, user_record, data): reply_markup = None elif command == 'select': if ( - len(arguments) < 1 - or type(arguments[0]) is not int + len(arguments) < 1 + or type(arguments[0]) is not int ): result = "Errore!" else: @@ -453,8 +350,8 @@ async def _talk_button(bot, update, user_record, data): ) elif command == 'stop': if ( - len(arguments) < 1 - or type(arguments[0]) is not int + len(arguments) < 1 + or type(arguments[0]) is not int ): result = "Errore!" elif not Confirmator.get('stop_bots').confirm(telegram_id): @@ -490,245 +387,6 @@ async def _talk_button(bot, update, user_record, data): return result -default_admin_messages = { - 'talk_command': { - 'description': { - 'en': "Choose a user and forward messages to each other", - 'it': "Scegli un utente e il bot farà da tramite inoltrando a " - "ognuno i messaggi dell'altro finché non terminerai la " - "sessione" - } - }, - 'restart_command': { - 'description': { - 'en': "Restart bots", - 'it': "Riavvia i bot" - }, - 'restart_scheduled_message': { - 'en': "Bots are being restarted, after pulling from repository.", - 'it': "I bot verranno riavviati in pochi secondi, caricando " - "prima le eventuali modifiche al codice." - }, - 'restart_completed_message': { - 'en': "Restart was successful.", - 'it': "Restart avvenuto con successo." - } - }, - 'stop_command': { - 'description': { - 'en': "Stop bots", - 'it': "Ferma i bot" - }, - 'text': { - 'en': "Are you sure you want to stop all bots?\n" - "To make them start again you will have to ssh-log " - "in server.\n\n" - "To restart the bots remotely use the /restart command " - "instead (before starting over, a git pull " - "is performed).", - 'it': "Sei sicuro di voler fermare i bot?\n" - "Per farli ripartire dovrai accedere al server.\n\n" - "Per far ripartire i bot da remoto usa invece il comando " - "/restart (prima di ripartire farò un " - "git pull)." - } - }, - 'stop_button': { - 'stop_text': { - 'en': "Stop bots", - 'it': "Ferma i bot" - }, - 'cancel': { - 'en': "Cancel", - 'it': "Annulla" - }, - 'confirm': { - 'en': "Do you really want to stop all bots?", - 'it': "Vuoi davvero fermare tutti i bot?" - }, - 'stopping': { - 'en': "Stopping bots...", - 'it': "Arresto in corso..." - }, - 'cancelled': { - 'en': "Operation was cancelled", - 'it': "Operazione annullata" - } - }, - 'db_command': { - 'description': { - 'en': "Ask for bot database via Telegram", - 'it': "Ricevi il database del bot via Telegram" - }, - 'not_sqlite': { - 'en': "Only SQLite databases may be sent via Telegram, since they " - "are single-file databases.\n" - "This bot has a `{db_type}` database.", - 'it': "Via Telegram possono essere inviati solo database SQLite, " - "in quanto composti di un solo file.\n" - "Questo bot ha invece un database `{db_type}`." - }, - 'file_caption': { - 'en': "Here is bot database.", - 'it': "Ecco il database!" - }, - 'db_sent': { - 'en': "Database sent.", - 'it': "Database inviato." - } - }, - 'query_command': { - 'description': { - 'en': "Receive the result of a SQL query performed on bot " - "database", - 'it': "Ricevi il risultato di una query SQL sul database del bot" - }, - 'help': { - 'en': "Write a SQL query to be run on bot database.\n\n" - "Example\n" - "/query SELECT * FROM users WHERE 0", - 'it': "Invia una query SQL da eseguire sul database del bot.\n\n" - "Esempio\n" - "/query SELECT * FROM users WHERE 0" - }, - 'no_iterable': { - 'en': "No result to show was returned", - 'it': "La query non ha restituito risultati da mostrare" - }, - 'exception': { - 'en': "The query threw this error:", - 'it': "La query ha dato questo errore:" - }, - 'result': { - 'en': "Query result", - 'it': "Risultato della query" - } - }, - 'select_command': { - 'description': { - 'en': "Receive the result of a SELECT query performed on bot " - "database", - 'it': "Ricevi il risultato di una query SQL di tipo SELECT " - "sul database del bot" - } - }, - 'query_button': { - 'error': { - 'en': "Error!", - 'it': "Errore!" - }, - 'file_name': { - 'en': "Query result.csv", - 'it': "Risultato della query.csv" - }, - 'empty_file': { - 'en': "No result to show.", - 'it': "Nessun risultato da mostrare." - } - }, - 'log_command': { - 'description': { - 'en': "Receive bot log file, if set", - 'it': "Ricevi il file di log del bot, se impostato" - }, - 'no_log': { - 'en': "Sorry but no log file is set.\n" - "To set it, use `bot.set_log_file_name` instance method or " - "`Bot.set_class_log_file_name` class method.", - 'it': "Spiacente ma il file di log non è stato impostato.\n" - "Per impostarlo, usa il metodo d'istanza " - "`bot.set_log_file_name` o il metodo di classe" - "`Bot.set_class_log_file_name`." - }, - 'sending_failure': { - 'en': "Sending log file failed!\n\n" - "Error:\n" - "{e}", - 'it': "Inviio del messaggio di log fallito!\n\n" - "Errore:\n" - "{e}" - }, - 'here_is_log_file': { - 'en': "Here is the complete log file.", - 'it': "Ecco il file di log completo." - }, - 'log_file_first_lines': { - 'en': "Here are the first {lines} lines of the log file.", - 'it': "Ecco le prime {lines} righe del file di log." - }, - 'log_file_last_lines': { - 'en': "Here are the last {lines} lines of the log file.\n" - "Newer lines are at the top of the file.", - 'it': "Ecco le ultime {lines} righe del file di log.\n" - "L'ordine è cronologico, con i messaggi nuovi in alto." - } - }, - 'errors_command': { - 'description': { - 'en': "Receive bot error log file, if set", - 'it': "Ricevi il file di log degli errori del bot, se impostato" - }, - 'no_log': { - 'en': "Sorry but no errors log file is set.\n" - "To set it, use `bot.set_errors_file_name` instance method" - "or `Bot.set_class_errors_file_name` class method.", - 'it': "Spiacente ma il file di log degli errori non è stato " - "impostato.\n" - "Per impostarlo, usa il metodo d'istanza " - "`bot.set_errors_file_name` o il metodo di classe" - "`Bot.set_class_errors_file_name`." - }, - 'empty_log': { - 'en': "Congratulations! Errors log is empty!", - 'it': "Congratulazioni! Il log degli errori è vuoto!" - }, - 'sending_failure': { - 'en': "Sending errors log file failed!\n\n" - "Error:\n" - "{e}", - 'it': "Inviio del messaggio di log degli errori fallito!\n\n" - "Errore:\n" - "{e}" - }, - 'here_is_log_file': { - 'en': "Here is the complete errors log file.", - 'it': "Ecco il file di log degli errori completo." - }, - 'log_file_first_lines': { - 'en': "Here are the first {lines} lines of the errors log file.", - 'it': "Ecco le prime {lines} righe del file di log degli errori." - }, - 'log_file_last_lines': { - 'en': "Here are the last {lines} lines of the errors log file.\n" - "Newer lines are at the top of the file.", - 'it': "Ecco le ultime {lines} righe del file di log degli " - "errori.\n" - "L'ordine è cronologico, con i messaggi nuovi in alto." - } - }, - 'maintenance_command': { - 'description': { - 'en': "Put the bot under maintenance", - 'it': "Metti il bot in manutenzione" - }, - 'maintenance_started': { - 'en': "Bot has just been put under maintenance!\n\n" - "Until further notice, it will reply to users " - "with the following message:\n\n" - "{message}", - 'it': "Il bot è stato messo in manutenzione!\n\n" - "Fino a nuovo ordine, risponderà a tutti i comandi con il " - "seguente messaggio\n\n" - "{message}" - }, - 'maintenance_ended': { - 'en': "Maintenance ended!", - 'it': "Manutenzione terminata!" - } - } -} - - async def _restart_command(bot, update, user_record): with bot.db as db: db['restart_messages'].insert( @@ -801,22 +459,22 @@ async def _stop_button(bot, update, user_record, data): if command == 'stop': if not Confirmator.get('stop_bots').confirm(telegram_id): return bot.get_message( - 'admin', 'stop_button', 'confirm', - update=update, user_record=user_record - ) - text = bot.get_message( - 'admin', 'stop_button', 'stopping', + 'admin', 'stop_button', 'confirm', update=update, user_record=user_record ) + text = bot.get_message( + 'admin', 'stop_button', 'stopping', + update=update, user_record=user_record + ) result = text # Do not stop bots immediately, otherwise callback query # will never be answered asyncio.ensure_future(stop_bots(bot)) elif command == 'cancel': text = bot.get_message( - 'admin', 'stop_button', 'cancelled', - update=update, user_record=user_record - ) + 'admin', 'stop_button', 'cancelled', + update=update, user_record=user_record + ) result = text if text: return dict( @@ -833,10 +491,10 @@ async def _stop_button(bot, update, user_record, data): async def _send_bot_database(bot, update, user_record): if not all( - [ - bot.db_url.endswith('.db'), - bot.db_url.startswith('sqlite:///') - ] + [ + bot.db_url.endswith('.db'), + bot.db_url.startswith('sqlite:///') + ] ): return bot.get_message( 'admin', 'db_command', 'not_sqlite', @@ -905,14 +563,14 @@ async def _query_command(bot, update, user_record): e=e ) result = ( - "{first_line}\n".format( - first_line=bot.get_message( - 'admin', 'query_command', 'result', - update=update, user_record=user_record + "{first_line}\n".format( + first_line=bot.get_message( + 'admin', 'query_command', 'result', + update=update, user_record=user_record + ) ) - ) - + f"{query}\n\n" - f"{result}" + + f"{query}\n\n" + f"{result}" ) if query_id: reply_markup = make_inline_keyboard( @@ -1037,7 +695,7 @@ async def _errors_command(bot, update, user_record): try: # Check that error log is not empty with open(bot.errors_file_path, 'r') as errors_file: - for line in errors_file: + for _ in errors_file: break else: return bot.get_message( @@ -1094,14 +752,15 @@ def get_maintenance_exception_criterion(bot, allowed_command): `bot` : davtelepot.bot.Bot() instance `allowed_command` : str (command to be allowed during maintenance) """ + def criterion(update): if 'message' not in update: return False update = update['message'] text = get_cleaned_text(update, bot, []) if ( - 'from' not in update - or 'id' not in update['from'] + 'from' not in update + or 'id' not in update['from'] ): return False with bot.db as db: @@ -1109,164 +768,162 @@ def get_maintenance_exception_criterion(bot, allowed_command): telegram_id=update['from']['id'] ) if not bot.authorization_function( - update=update, - user_record=user_record, - authorization_level=2 + update=update, + user_record=user_record, + authorization_level=2 ): return False return text == allowed_command.strip('/') + return criterion -def init(bot, talk_messages=None, admin_messages=None): +def init(telegram_bot, talk_messages=None, admin_messages=None): """Assign parsers, commands, buttons and queries to given `bot`.""" if talk_messages is None: - talk_messages = default_talk_messages - bot.messages['talk'] = talk_messages + talk_messages = messages.default_talk_messages + telegram_bot.messages['talk'] = talk_messages if admin_messages is None: - admin_messages = default_admin_messages - bot.messages['admin'] = admin_messages - with bot.db as db: - if 'talking_sessions' not in db.tables: - db['talking_sessions'].insert( - dict( - user=0, - admin=0, - cancelled=1 - ) + admin_messages = messages.default_admin_messages + telegram_bot.messages['admin'] = admin_messages + db = telegram_bot.db + if 'talking_sessions' not in db.tables: + db['talking_sessions'].insert( + dict( + user=0, + admin=0, + cancelled=1 ) + ) allowed_during_maintenance = [ - get_maintenance_exception_criterion(bot, command) + get_maintenance_exception_criterion(telegram_bot, command) for command in ['stop', 'restart', 'maintenance'] ] - @bot.additional_task(when='BEFORE') + @telegram_bot.additional_task(when='BEFORE') async def load_talking_sessions(): sessions = [] - with bot.db as db: - for session in db.query( + for session in db.query( """SELECT * - FROM talking_sessions - WHERE NOT cancelled - """ - ): - sessions.append( - dict( - other_user_record=db['users'].find_one( - id=session['user'] - ), - admin_record=db['users'].find_one( - id=session['admin'] - ), - ) - ) - for session in sessions: - await start_session( - bot=bot, - other_user_record=session['other_user_record'], - admin_record=session['admin_record'] + FROM talking_sessions + WHERE NOT cancelled + """ + ): + sessions.append( + dict( + other_user_record=db['users'].find_one( + id=session['user'] + ), + admin_record=db['users'].find_one( + id=session['admin'] + ), ) + ) + for session in sessions: + await start_session( + bot=telegram_bot, + other_user_record=session['other_user_record'], + admin_record=session['admin_record'] + ) - @bot.command(command='/talk', aliases=[], show_in_keyboard=False, - description=admin_messages['talk_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/talk', aliases=[], show_in_keyboard=False, + description=admin_messages['talk_command']['description'], + authorization_level='admin') async def talk_command(bot, update, user_record): return await _talk_command(bot, update, user_record) - @bot.button(prefix='talk:///', separator='|', authorization_level='admin') + @telegram_bot.button(prefix='talk:///', separator='|', authorization_level='admin') async def talk_button(bot, update, user_record, data): return await _talk_button(bot, update, user_record, data) - @bot.command(command='/restart', aliases=[], show_in_keyboard=False, - description=admin_messages['restart_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/restart', aliases=[], show_in_keyboard=False, + description=admin_messages['restart_command']['description'], + authorization_level='admin') async def restart_command(bot, update, user_record): return await _restart_command(bot, update, user_record) - @bot.additional_task('BEFORE') + @telegram_bot.additional_task('BEFORE') async def send_restart_messages(): """Send restart messages at restart.""" - with bot.db as db: - for restart_message in db['restart_messages'].find(sent=None): - asyncio.ensure_future( - bot.send_message( - **{ - key: val - for key, val in restart_message.items() - if key in ( - 'chat_id', - 'text', - 'parse_mode', - 'reply_to_message_id' - ) - } - ) - ) - db['restart_messages'].update( - dict( - sent=datetime.datetime.now(), - id=restart_message['id'] - ), - ['id'], - ensure=True + for restart_message in db['restart_messages'].find(sent=None): + asyncio.ensure_future( + telegram_bot.send_message( + **{ + key: val + for key, val in restart_message.items() + if key in ( + 'chat_id', + 'text', + 'parse_mode', + 'reply_to_message_id' + ) + } ) + ) + db['restart_messages'].update( + dict( + sent=datetime.datetime.now(), + id=restart_message['id'] + ), + ['id'], + ensure=True + ) return - @bot.command(command='/stop', aliases=[], show_in_keyboard=False, - description=admin_messages['stop_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/stop', aliases=[], show_in_keyboard=False, + description=admin_messages['stop_command']['description'], + authorization_level='admin') async def stop_command(bot, update, user_record): return await _stop_command(bot, update, user_record) - @bot.button(prefix='stop:///', separator='|', - description=admin_messages['stop_command']['description'], - authorization_level='admin') + @telegram_bot.button(prefix='stop:///', separator='|', + description=admin_messages['stop_command']['description'], + authorization_level='admin') async def stop_button(bot, update, user_record, data): return await _stop_button(bot, update, user_record, data) - @bot.command(command='/db', aliases=[], show_in_keyboard=False, - description=admin_messages['db_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/db', aliases=[], show_in_keyboard=False, + description=admin_messages['db_command']['description'], + authorization_level='admin') async def send_bot_database(bot, update, user_record): return await _send_bot_database(bot, update, user_record) - @bot.command(command='/query', aliases=[], show_in_keyboard=False, - description=admin_messages['query_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/query', aliases=[], show_in_keyboard=False, + description=admin_messages['query_command']['description'], + authorization_level='admin') async def query_command(bot, update, user_record): return await _query_command(bot, update, user_record) - @bot.command(command='/select', aliases=[], show_in_keyboard=False, - description=admin_messages['select_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/select', aliases=[], show_in_keyboard=False, + description=admin_messages['select_command']['description'], + authorization_level='admin') async def select_command(bot, update, user_record): return await _query_command(bot, update, user_record) - @bot.button(prefix='db_query:///', separator='|', - description=admin_messages['query_command']['description'], - authorization_level='admin') + @telegram_bot.button(prefix='db_query:///', separator='|', + description=admin_messages['query_command']['description'], + authorization_level='admin') async def query_button(bot, update, user_record, data): return await _query_button(bot, update, user_record, data) - @bot.command(command='/log', aliases=[], show_in_keyboard=False, - description=admin_messages['log_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/log', aliases=[], show_in_keyboard=False, + description=admin_messages['log_command']['description'], + authorization_level='admin') async def log_command(bot, update, user_record): return await _log_command(bot, update, user_record) - @bot.command(command='/errors', aliases=[], show_in_keyboard=False, - description=admin_messages['errors_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/errors', aliases=[], show_in_keyboard=False, + description=admin_messages['errors_command']['description'], + authorization_level='admin') async def errors_command(bot, update, user_record): return await _errors_command(bot, update, user_record) for exception in allowed_during_maintenance: - bot.allow_during_maintenance(exception) + telegram_bot.allow_during_maintenance(exception) - @bot.command(command='/maintenance', aliases=[], show_in_keyboard=False, - description=admin_messages[ - 'maintenance_command']['description'], - authorization_level='admin') + @telegram_bot.command(command='/maintenance', aliases=[], show_in_keyboard=False, + description=admin_messages['maintenance_command']['description'], + authorization_level='admin') async def maintenance_command(bot, update, user_record): return await _maintenance_command(bot, update, user_record) diff --git a/davtelepot/authorization.py b/davtelepot/authorization.py index 5234df2..0ace3e2 100644 --- a/davtelepot/authorization.py +++ b/davtelepot/authorization.py @@ -60,7 +60,7 @@ DEFAULT_ROLES[100] = { } -class Role(): +class Role: """Authorization level for users of a bot.""" roles = OrderedDict() @@ -202,11 +202,11 @@ class Role(): def __gt__(self, other): """Return True if self can appoint other.""" return ( - ( - self.code < other.code - or other.code == 0 - ) - and self.code in other.can_be_appointed_by + ( + self.code < other.code + or other.code == 0 + ) + and self.code in other.can_be_appointed_by ) def __ge__(self, other): @@ -232,6 +232,7 @@ class Role(): def get_authorization_function(bot): """Take a `bot` and return its authorization_function.""" + def is_authorized(update, user_record=None, authorization_level=2): """Return True if user role is at least at `authorization_level`.""" user_role = bot.Role.get_user_role(user_record=user_record) @@ -241,6 +242,7 @@ def get_authorization_function(bot): if needed_role.code < user_role.code: return False return True + return is_authorized @@ -412,8 +414,8 @@ async def _authorization_button(bot, update, user_record, data): elif command in ['set'] and len(arguments) > 1: other_user_id, new_privileges, *_ = arguments if not Confirmator.get( - key=f'{user_id}_set_{other_user_id}', - confirm_timedelta=5 + key=f'{user_id}_set_{other_user_id}', + confirm_timedelta=5 ).confirm: return bot.get_message( 'authorization', 'auth_button', 'confirm', @@ -497,58 +499,55 @@ async def _ban_command(bot, update, user_record): return -def init(bot: Bot, roles=None, authorization_messages=None): +def init(telegram_bot: Bot, roles=None, authorization_messages=None): """Set bot roles and assign role-related commands. Pass an OrderedDict of `roles` to get them set. """ + class _Role(Role): roles = OrderedDict() - bot.set_role_class(_Role) + telegram_bot.set_role_class(_Role) if roles is None: roles = DEFAULT_ROLES # Cast roles to OrderedDict if isinstance(roles, list): roles = OrderedDict( (i, element) - for i, element in enumerate(list) + for i, element in enumerate(roles) ) if not isinstance(roles, OrderedDict): raise TypeError("`roles` shall be a OrderedDict!") - for id, role in roles.items(): + for code, role in roles.items(): if 'code' not in role: - role['code'] = id - bot.Role(**role) + role['code'] = code + telegram_bot.Role(**role) - bot.set_authorization_function( - get_authorization_function(bot) + telegram_bot.set_authorization_function( + get_authorization_function(telegram_bot) ) if authorization_messages is None: authorization_messages = deafult_authorization_messages - bot.messages['authorization'] = authorization_messages + telegram_bot.messages['authorization'] = authorization_messages - @bot.command(command='/auth', aliases=[], show_in_keyboard=False, - description=( - authorization_messages['auth_command']['description'] - ), - authorization_level='moderator') + @telegram_bot.command(command='/auth', aliases=[], show_in_keyboard=False, + description=( + authorization_messages['auth_command']['description'] + ), + authorization_level='moderator') async def authorization_command(bot, update, user_record): return await _authorization_command(bot, update, user_record) - @bot.button('auth:///', - description=( - authorization_messages['auth_button']['description'] - ), - separator='|', - authorization_level='moderator') + @telegram_bot.button('auth:///', + description=authorization_messages['auth_button']['description'], + separator='|', + authorization_level='moderator') async def authorization_button(bot, update, user_record, data): return await _authorization_button(bot, update, user_record, data) - @bot.command('/ban', aliases=[], show_in_keyboard=False, - description=( - authorization_messages['ban_command']['description'] - ), - authorization_level='admin') + @telegram_bot.command('/ban', aliases=[], show_in_keyboard=False, + description=authorization_messages['ban_command']['description'], + authorization_level='admin') async def ban_command(bot, update, user_record): return await _ban_command(bot, update, user_record) diff --git a/davtelepot/messages.py b/davtelepot/messages.py index 3c702e6..e481643 100644 --- a/davtelepot/messages.py +++ b/davtelepot/messages.py @@ -1,5 +1,248 @@ """Default messages for bot functions.""" +default_admin_messages = { + 'talk_command': { + 'description': { + 'en': "Choose a user and forward messages to each other", + 'it': "Scegli un utente e il bot farà da tramite inoltrando a " + "ognuno i messaggi dell'altro finché non terminerai la " + "sessione" + } + }, + 'restart_command': { + 'description': { + 'en': "Restart bots", + 'it': "Riavvia i bot" + }, + 'restart_scheduled_message': { + 'en': "Bots are being restarted, after pulling from repository.", + 'it': "I bot verranno riavviati in pochi secondi, caricando " + "prima le eventuali modifiche al codice." + }, + 'restart_completed_message': { + 'en': "Restart was successful.", + 'it': "Restart avvenuto con successo." + } + }, + 'stop_command': { + 'description': { + 'en': "Stop bots", + 'it': "Ferma i bot" + }, + 'text': { + 'en': "Are you sure you want to stop all bots?\n" + "To make them start again you will have to ssh-log " + "in server.\n\n" + "To restart the bots remotely use the /restart command " + "instead (before starting over, a git pull " + "is performed).", + 'it': "Sei sicuro di voler fermare i bot?\n" + "Per farli ripartire dovrai accedere al server.\n\n" + "Per far ripartire i bot da remoto usa invece il comando " + "/restart (prima di ripartire farò un " + "git pull)." + } + }, + 'stop_button': { + 'stop_text': { + 'en': "Stop bots", + 'it': "Ferma i bot" + }, + 'cancel': { + 'en': "Cancel", + 'it': "Annulla" + }, + 'confirm': { + 'en': "Do you really want to stop all bots?", + 'it': "Vuoi davvero fermare tutti i bot?" + }, + 'stopping': { + 'en': "Stopping bots...", + 'it': "Arresto in corso..." + }, + 'cancelled': { + 'en': "Operation was cancelled", + 'it': "Operazione annullata" + } + }, + 'db_command': { + 'description': { + 'en': "Ask for bot database via Telegram", + 'it': "Ricevi il database del bot via Telegram" + }, + 'not_sqlite': { + 'en': "Only SQLite databases may be sent via Telegram, since they " + "are single-file databases.\n" + "This bot has a `{db_type}` database.", + 'it': "Via Telegram possono essere inviati solo database SQLite, " + "in quanto composti di un solo file.\n" + "Questo bot ha invece un database `{db_type}`." + }, + 'file_caption': { + 'en': "Here is bot database.", + 'it': "Ecco il database!" + }, + 'db_sent': { + 'en': "Database sent.", + 'it': "Database inviato." + } + }, + 'query_command': { + 'description': { + 'en': "Receive the result of a SQL query performed on bot " + "database", + 'it': "Ricevi il risultato di una query SQL sul database del bot" + }, + 'help': { + 'en': "Write a SQL query to be run on bot database.\n\n" + "Example\n" + "/query SELECT * FROM users WHERE 0", + 'it': "Invia una query SQL da eseguire sul database del bot.\n\n" + "Esempio\n" + "/query SELECT * FROM users WHERE 0" + }, + 'no_iterable': { + 'en': "No result to show was returned", + 'it': "La query non ha restituito risultati da mostrare" + }, + 'exception': { + 'en': "The query threw this error:", + 'it': "La query ha dato questo errore:" + }, + 'result': { + 'en': "Query result", + 'it': "Risultato della query" + } + }, + 'select_command': { + 'description': { + 'en': "Receive the result of a SELECT query performed on bot " + "database", + 'it': "Ricevi il risultato di una query SQL di tipo SELECT " + "sul database del bot" + } + }, + 'query_button': { + 'error': { + 'en': "Error!", + 'it': "Errore!" + }, + 'file_name': { + 'en': "Query result.csv", + 'it': "Risultato della query.csv" + }, + 'empty_file': { + 'en': "No result to show.", + 'it': "Nessun risultato da mostrare." + } + }, + 'log_command': { + 'description': { + 'en': "Receive bot log file, if set", + 'it': "Ricevi il file di log del bot, se impostato" + }, + 'no_log': { + 'en': "Sorry but no log file is set.\n" + "To set it, use `bot.set_log_file_name` instance method or " + "`Bot.set_class_log_file_name` class method.", + 'it': "Spiacente ma il file di log non è stato impostato.\n" + "Per impostarlo, usa il metodo d'istanza " + "`bot.set_log_file_name` o il metodo di classe" + "`Bot.set_class_log_file_name`." + }, + 'sending_failure': { + 'en': "Sending log file failed!\n\n" + "Error:\n" + "{e}", + 'it': "Inviio del messaggio di log fallito!\n\n" + "Errore:\n" + "{e}" + }, + 'here_is_log_file': { + 'en': "Here is the complete log file.", + 'it': "Ecco il file di log completo." + }, + 'log_file_first_lines': { + 'en': "Here are the first {lines} lines of the log file.", + 'it': "Ecco le prime {lines} righe del file di log." + }, + 'log_file_last_lines': { + 'en': "Here are the last {lines} lines of the log file.\n" + "Newer lines are at the top of the file.", + 'it': "Ecco le ultime {lines} righe del file di log.\n" + "L'ordine è cronologico, con i messaggi nuovi in alto." + } + }, + 'errors_command': { + 'description': { + 'en': "Receive bot error log file, if set", + 'it': "Ricevi il file di log degli errori del bot, se impostato" + }, + 'no_log': { + 'en': "Sorry but no errors log file is set.\n" + "To set it, use `bot.set_errors_file_name` instance method" + "or `Bot.set_class_errors_file_name` class method.", + 'it': "Spiacente ma il file di log degli errori non è stato " + "impostato.\n" + "Per impostarlo, usa il metodo d'istanza " + "`bot.set_errors_file_name` o il metodo di classe" + "`Bot.set_class_errors_file_name`." + }, + 'empty_log': { + 'en': "Congratulations! Errors log is empty!", + 'it': "Congratulazioni! Il log degli errori è vuoto!" + }, + 'sending_failure': { + 'en': "Sending errors log file failed!\n\n" + "Error:\n" + "{e}", + 'it': "Inviio del messaggio di log degli errori fallito!\n\n" + "Errore:\n" + "{e}" + }, + 'here_is_log_file': { + 'en': "Here is the complete errors log file.", + 'it': "Ecco il file di log degli errori completo." + }, + 'log_file_first_lines': { + 'en': "Here are the first {lines} lines of the errors log file.", + 'it': "Ecco le prime {lines} righe del file di log degli errori." + }, + 'log_file_last_lines': { + 'en': "Here are the last {lines} lines of the errors log file.\n" + "Newer lines are at the top of the file.", + 'it': "Ecco le ultime {lines} righe del file di log degli " + "errori.\n" + "L'ordine è cronologico, con i messaggi nuovi in alto." + } + }, + 'maintenance_command': { + 'description': { + 'en': "Put the bot under maintenance", + 'it': "Metti il bot in manutenzione" + }, + 'maintenance_started': { + 'en': "Bot has just been put under maintenance!\n\n" + "Until further notice, it will reply to users " + "with the following message:\n\n" + "{message}", + 'it': "Il bot è stato messo in manutenzione!\n\n" + "Fino a nuovo ordine, risponderà a tutti i comandi con il " + "seguente messaggio\n\n" + "{message}" + }, + 'maintenance_ended': { + 'en': "Maintenance ended!", + 'it': "Manutenzione terminata!" + } + } +} + +default_authorization_denied_message = { + 'en': "You are not allowed to use this command, sorry.", + 'it': "Non disponi di autorizzazioni sufficienti per questa richiesta, spiacente.", +} + default_help_messages = { 'help_command': { 'header': { @@ -33,8 +276,8 @@ default_help_messages = { }, }, 'commands_button_label': { - 'en': "Commands 🤖", - 'it': "Comandi 🤖", + 'en': "Commands 🤖", + 'it': "Comandi 🤖", }, } @@ -211,3 +454,83 @@ default_suggestion_messages = { }, } } + +default_talk_messages = { + 'admin_session_ended': { + 'en': 'Session with user {u} ended.', + 'it': 'Sessione terminata con l\'utente {u}.', + }, + 'admin_warning': { + 'en': ( + 'You are now talking to {u}.\n' + 'Until you end this session, your messages will be ' + 'forwarded to each other.' + ), + 'it': ( + 'Sei ora connesso con {u}.\n' + 'Finché non chiuderai la connessione, i messaggi che scriverai ' + 'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.' + ), + }, + 'end_session': { + 'en': 'End session?', + 'it': 'Chiudere la sessione?', + }, + 'help_text': { + 'en': 'Press the button to search for user.', + 'it': 'Premi il pulsante per scegliere un utente.', + }, + 'search_button': { + 'en': "🔍 Search for user", + 'it': "🔍 Cerca utente", + }, + 'select_user': { + 'en': 'Which user would you like to talk to?', + 'it': 'Con quale utente vorresti parlare?', + }, + 'user_not_found': { + 'en': ( + "Sory, but no user matches your query for\n" + "{q}" + ), + 'it': ( + "Spiacente, ma nessun utente corrisponde alla ricerca per\n" + "{q}" + ), + }, + 'instructions': { + 'en': ( + 'Write a part of name, surname or username of the user you want ' + 'to talk to.' + ), + 'it': ( + 'Scrivi una parte del nome, cognome o username dell\'utente con ' + 'cui vuoi parlare.' + ), + }, + 'stop': { + 'en': 'End session', + 'it': 'Termina la sessione', + }, + 'user_session_ended': { + 'en': 'Session with admin {u} ended.', + 'it': 'Sessione terminata con l\'amministratore {u}.', + }, + 'user_warning': { + 'en': ( + '{u}, admin of this bot, wants to talk to you.\n' + 'Until this session is ended by {u}, your messages will be ' + 'forwarded to each other.' + ), + 'it': ( + '{u}, amministratore di questo bot, vuole parlare con te.\n' + 'Finché non chiuderà la connessione, i messaggi che scriverai ' + 'qui saranno inoltrati a {u}, e ti inoltrerò i suoi.' + ), + }, +} + +default_unknown_command_message = { + 'en': "Unknown command! Touch /help to read the guide and available commands.", + 'it': "Comando sconosciuto! Fai /help per leggere la guida e i comandi." +}