From a564e33efc04c6b7f6de802a2d79eaeabbc6fda1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 4 Apr 2019 17:39:38 +0200 Subject: [PATCH] Handle errors in commands --- royalgames.py | 3 ++- royalnet/bots/telegram.py | 18 ++++++++++++++---- royalnet/commands/ciaoruozi.py | 5 +++-- royalnet/commands/color.py | 3 ++- royalnet/commands/debug_author.py | 3 ++- royalnet/commands/debug_create.py | 3 ++- royalnet/commands/diario.py | 4 ++-- royalnet/commands/error_handler.py | 20 ++++++++++++++++++++ royalnet/commands/null.py | 3 ++- royalnet/commands/ping.py | 3 ++- royalnet/commands/ship.py | 5 +++-- royalnet/commands/smecds.py | 1 + royalnet/commands/sync.py | 7 ++++--- royalnet/database/tables/diario.py | 2 +- royalnet/utils/command.py | 1 + 15 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 royalnet/commands/error_handler.py diff --git a/royalgames.py b/royalgames.py index b9d72c27..5736ad59 100644 --- a/royalgames.py +++ b/royalgames.py @@ -4,6 +4,7 @@ from royalnet.bots import TelegramBot from royalnet.commands import PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, SyncCommand, DiarioCommand from royalnet.commands.debug_create import DebugCreateCommand from royalnet.commands.debug_author import DebugAuthorCommand +from royalnet.commands.error_handler import ErrorHandlerCommand from royalnet.network import RoyalnetServer from royalnet.database.tables import Royal, Telegram @@ -13,7 +14,7 @@ commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziComm DebugAuthorCommand, DiarioCommand] master = RoyalnetServer("localhost", 1234, "sas") -tg_bot = TelegramBot(os.environ["TG_AK"], "localhost:1234", "sas", commands, os.environ["DB_PATH"], Royal, Telegram, "tg_id") +tg_bot = TelegramBot(os.environ["TG_AK"], "localhost:1234", "sas", commands, os.environ["DB_PATH"], Royal, Telegram, "tg_id", error_command=ErrorHandlerCommand) loop.create_task(master.run()) loop.create_task(tg_bot.run()) print("Starting loop...") diff --git a/royalnet/bots/telegram.py b/royalnet/bots/telegram.py index dc69d438..efe82784 100644 --- a/royalnet/bots/telegram.py +++ b/royalnet/bots/telegram.py @@ -26,8 +26,8 @@ class TelegramBot: master_table, identity_table, identity_column_name: str, - missing_command: Command = NullCommand, - error_command: Command = NullCommand): + missing_command: typing.Type[Command] = NullCommand, + error_command: typing.Type[Command] = NullCommand): self.bot: telegram.Bot = telegram.Bot(api_key) self.should_run: bool = False self.offset: int = -100 @@ -54,7 +54,17 @@ class TelegramBot: alchemy = self.alchemy async def reply(call, text: str): - await asyncify(call.channel.send_message, text, parse_mode="HTML") + escaped_text = text.replace("<", "<") \ + .replace(">", ">") \ + .replace("[b]", "") \ + .replace("[/b]", "") \ + .replace("[i]", "") \ + .replace("[/i]", "") \ + .replace("[u]", "") \ + .replace("[/u]", "") \ + .replace("[c]", "
") \
+                                   .replace("[/c]", "
") + await asyncify(call.channel.send_message, escaped_text, parse_mode="HTML") async def net_request(call, message: Message, destination: str): response = await self.network.request(message, destination) @@ -112,7 +122,7 @@ class TelegramBot: try: return await self.Call(message.chat, command, *parameters, update=update).run() except Exception as exc: - return await self.Call(message.chat, self.error_command, *parameters, update=update, exception=exc).run() + return await self.Call(message.chat, self.error_command, *parameters, update=update, exception=exc, previous_command=command).run() async def handle_net_request(self, message: Message): pass diff --git a/royalnet/commands/ciaoruozi.py b/royalnet/commands/ciaoruozi.py index 4c6d0f13..c33ca88c 100644 --- a/royalnet/commands/ciaoruozi.py +++ b/royalnet/commands/ciaoruozi.py @@ -6,11 +6,12 @@ class CiaoruoziCommand(Command): command_name = "ciaoruozi" command_title = "Saluta Ruozi, anche se non Γ¨ piΓΉ in RYG." + command_syntax = "" async def telegram(self, call: Call, args: CommandArgs): update: Update = args.kwargs["update"] user: User = update.effective_user if user.id == 112437036: - await call.reply("Ciao me!") + await call.reply("πŸ‘‹ Ciao me!") else: - await call.reply("Ciao Ruozi!") + await call.reply("πŸ‘‹ Ciao Ruozi!") diff --git a/royalnet/commands/color.py b/royalnet/commands/color.py index 76dbe2c2..e76ed11c 100644 --- a/royalnet/commands/color.py +++ b/royalnet/commands/color.py @@ -5,8 +5,9 @@ class ColorCommand(Command): command_name = "color" command_title = "Invia un colore in chat...?" + command_syntax = "" async def common(self, call: Call, args: CommandArgs): await call.reply(""" - I am sorry, unknown error occured during working with your request, Admin were notified + [i]I am sorry, unknown error occured during working with your request, Admin were notified[/i] """) diff --git a/royalnet/commands/debug_author.py b/royalnet/commands/debug_author.py index 0e9799ff..011c10a6 100644 --- a/royalnet/commands/debug_author.py +++ b/royalnet/commands/debug_author.py @@ -6,6 +6,7 @@ class DebugAuthorCommand(Command): command_name = "debug_author" command_title = "Ottieni informazioni sull'autore di questa chiamata." + command_syntax = "" require_alchemy_tables = {Royal, Telegram} @@ -13,4 +14,4 @@ class DebugAuthorCommand(Command): author = await call.get_author() if author is None: await call.reply(f"☁️ L'autore di questa chiamata Γ¨ sconosciuto.") - await call.reply(f"🌞 {str(author)} Γ¨ l'autore di questa chiamata.") + await call.reply(f"🌞 [c]{str(author)}[/c] Γ¨ l'autore di questa chiamata.") diff --git a/royalnet/commands/debug_create.py b/royalnet/commands/debug_create.py index 6327ca2b..d69c5d18 100644 --- a/royalnet/commands/debug_create.py +++ b/royalnet/commands/debug_create.py @@ -5,7 +5,8 @@ from ..database.tables import Royal, Alias class DebugCreateCommand(Command): command_name = "debug_create" - command_title = "Create a new Royalnet user account" + command_title = "Crea un nuovo account Royalnet" + command_syntax = "(newusername)" require_alchemy_tables = {Royal, Alias} diff --git a/royalnet/commands/diario.py b/royalnet/commands/diario.py index b25ede61..b4339828 100644 --- a/royalnet/commands/diario.py +++ b/royalnet/commands/diario.py @@ -9,6 +9,7 @@ class DiarioCommand(Command): command_name = "diario" command_title = "Aggiungi una citazione al Diario." + command_syntax = "\"(testo)\" --[autore], [contesto]" require_alchemy_tables = {Royal, Diario, Alias} @@ -19,7 +20,6 @@ class DiarioCommand(Command): match = re.match(r'(!)? *["Β«β€˜β€œβ€›β€Ÿβ›βγ€οΌ‚`]([^"]+)["Β»β€™β€βœβžγ€žοΌ‚`] *(?:(?:-{1,2}|β€”) *([\w ]+))?(?:, *([^ ].*))?', text) # Find the corresponding matches if match is None: - await call.reply(f"βœ… Comando skippato per frase non valida") raise InvalidInputError("No match found.") spoiler = bool(match.group(1)) text = match.group(2) @@ -45,4 +45,4 @@ class DiarioCommand(Command): spoiler=spoiler) call.session.add(diario) await asyncify(call.session.commit) - await call.reply(f"βœ… Aggiunto al diario: {repr(diario)}") + await call.reply(f"βœ… Aggiunto al diario!") diff --git a/royalnet/commands/error_handler.py b/royalnet/commands/error_handler.py new file mode 100644 index 00000000..68b7c0ae --- /dev/null +++ b/royalnet/commands/error_handler.py @@ -0,0 +1,20 @@ +from ..utils import Command, CommandArgs, Call, InvalidInputError + + +class ErrorHandlerCommand(Command): + + command_name = "error_handler" + command_title = "Gestisce gli errori causati dagli altri comandi." + command_syntax = "" + + async def telegram(self, call: Call, args: CommandArgs): + try: + exc = args.kwargs["exception"] + except InvalidInputError: + await call.reply("⚠️ Questo comando non puΓ² essere chiamato da solo.") + return + if isinstance(exc, InvalidInputError): + command = args.kwargs["previous_command"] + await call.reply(f"⚠️ Sintassi non valida.\nSintassi corretta:[c]/{command.command_name} {command.command_syntax}[/c]") + return + await call.reply("❌ Eccezione non gestita durante l'esecuzione del comando.") diff --git a/royalnet/commands/null.py b/royalnet/commands/null.py index 236f2617..6d281c1d 100644 --- a/royalnet/commands/null.py +++ b/royalnet/commands/null.py @@ -4,7 +4,8 @@ from ..utils import Command, CommandArgs, Call class NullCommand(Command): command_name = "null" - command_title = "Do nothing" + command_title = "Non fa nulla." + command_syntax = "" async def common(self, call: Call, args: CommandArgs): pass diff --git a/royalnet/commands/ping.py b/royalnet/commands/ping.py index 462b33e5..da7a99b6 100644 --- a/royalnet/commands/ping.py +++ b/royalnet/commands/ping.py @@ -5,6 +5,7 @@ class PingCommand(Command): command_name = "ping" command_title = "Ping pong!" + command_syntax = "" async def common(self, call: Call, args: CommandArgs): - await call.reply("Pong!") + await call.reply("πŸ“ Pong!") diff --git a/royalnet/commands/ship.py b/royalnet/commands/ship.py index 74592c5e..635357aa 100644 --- a/royalnet/commands/ship.py +++ b/royalnet/commands/ship.py @@ -2,13 +2,14 @@ import re from ..utils import Command, CommandArgs, Call, safeformat -SHIP_RESULT = "πŸ’• {one} + {two} = {result}" +SHIP_RESULT = "πŸ’• {one} + {two} = [b]{result}[/b]" class ShipCommand(Command): command_name = "ship" - command_title = "Create a ship between two items" + command_title = "Crea una ship tra due cose." + command_syntax = "(uno) (due)" async def common(self, call: Call, args: CommandArgs): name_one = args[0] diff --git a/royalnet/commands/smecds.py b/royalnet/commands/smecds.py index e6f74fe2..0f200573 100644 --- a/royalnet/commands/smecds.py +++ b/royalnet/commands/smecds.py @@ -55,6 +55,7 @@ class SmecdsCommand(Command): command_name = "smecds" command_title = "Secondo me, Γ¨ colpa dello stagista..." + command_syntax = "" async def common(self, call: Call, args: CommandArgs): ds = random.sample(DS_LIST, 1)[0] diff --git a/royalnet/commands/sync.py b/royalnet/commands/sync.py index 89dcf63a..3c67cdd2 100644 --- a/royalnet/commands/sync.py +++ b/royalnet/commands/sync.py @@ -7,7 +7,8 @@ from ..database.tables import Royal, Telegram class SyncCommand(Command): command_name = "sync" - command_title = "Connect your current account to Royalnet" + command_title = "Connetti il tuo account attuale a Royalnet!" + command_syntax = "(royalnetusername)" require_alchemy_tables = {Royal, Telegram} @@ -36,13 +37,13 @@ class SyncCommand(Command): tg_last_name=user.last_name, tg_username=user.username) call.session.add(telegram) - await call.reply(f"βœ… Connessione completata: {str(royal)} ⬌ {str(telegram)}") + await call.reply(f"βœ… Connessione completata: [c]{str(royal)}[/c] ⬌ [c]{str(telegram)}[/c]") else: # Update the Telegram data # Avatar is WIP telegram.tg_first_name = user.first_name telegram.tg_last_name = user.last_name telegram.tg_username = user.username - await call.reply(f"βœ… Dati di {str(telegram)} aggiornati.") + await call.reply(f"βœ… Dati di [c]{str(telegram)}[/c] aggiornati.") # Commit the session await asyncify(call.session.commit()) diff --git a/royalnet/database/tables/diario.py b/royalnet/database/tables/diario.py index 5f91dd5c..149b2e5f 100644 --- a/royalnet/database/tables/diario.py +++ b/royalnet/database/tables/diario.py @@ -26,4 +26,4 @@ class Diario: quoted_account = relationship("Royal", foreign_keys=quoted_account_id, backref="diario_quoted") def __repr__(self): - return f"<Diario diario_id={self.diario_id} creator_id={self.creator_id} quoted_account_id={self.quoted_account_id} quoted={self.quoted} text={self.text} context={self.context} timestamp={self.timestamp} media_url={self.media_url} spoiler={self.spoiler}>" + return f"" diff --git a/royalnet/utils/command.py b/royalnet/utils/command.py index 885e3472..ec08c119 100644 --- a/royalnet/utils/command.py +++ b/royalnet/utils/command.py @@ -38,6 +38,7 @@ class Command: command_name: str = NotImplemented command_title: str = NotImplemented + command_syntax: str = NotImplemented require_alchemy_tables: typing.Set = set()