mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Many more improvements
This commit is contained in:
parent
a564e33efc
commit
6666331a15
16 changed files with 96 additions and 54 deletions
|
@ -2,6 +2,7 @@ import telegram
|
|||
import asyncio
|
||||
import typing
|
||||
import logging as _logging
|
||||
import sys
|
||||
from ..commands import NullCommand
|
||||
from ..utils import asyncify, Call, Command
|
||||
from ..network import RoyalnetLink, Message
|
||||
|
@ -120,9 +121,17 @@ class TelegramBot:
|
|||
command = self.missing_command
|
||||
# Call the command
|
||||
try:
|
||||
return await self.Call(message.chat, command, *parameters, update=update).run()
|
||||
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, previous_command=command).run()
|
||||
try:
|
||||
return await self.Call(message.chat, self.error_command, parameters,
|
||||
update=update,
|
||||
exception_info=sys.exc_info(),
|
||||
previous_command=command,
|
||||
log=log).run()
|
||||
except Exception as exc2:
|
||||
log.error(f"Exception in error handler command: {exc2}")
|
||||
|
||||
async def handle_net_request(self, message: Message):
|
||||
pass
|
||||
|
|
|
@ -8,8 +8,8 @@ class CiaoruoziCommand(Command):
|
|||
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"]
|
||||
async def telegram(self, call: Call):
|
||||
update: Update = call.kwargs["update"]
|
||||
user: User = update.effective_user
|
||||
if user.id == 112437036:
|
||||
await call.reply("👋 Ciao me!")
|
||||
|
|
|
@ -7,7 +7,7 @@ class ColorCommand(Command):
|
|||
command_title = "Invia un colore in chat...?"
|
||||
command_syntax = ""
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
await call.reply("""
|
||||
[i]I am sorry, unknown error occured during working with your request, Admin were notified[/i]
|
||||
""")
|
||||
|
|
|
@ -10,7 +10,7 @@ class DebugAuthorCommand(Command):
|
|||
|
||||
require_alchemy_tables = {Royal, Telegram}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
author = await call.get_author()
|
||||
if author is None:
|
||||
await call.reply(f"☁️ L'autore di questa chiamata è sconosciuto.")
|
||||
|
|
|
@ -10,10 +10,10 @@ class DebugCreateCommand(Command):
|
|||
|
||||
require_alchemy_tables = {Royal, Alias}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
royal = call.alchemy.Royal(username=args[0], role="Member")
|
||||
async def common(self, call: Call):
|
||||
royal = call.alchemy.Royal(username=call.args[0], role="Member")
|
||||
call.session.add(royal)
|
||||
alias = call.alchemy.Alias(royal=royal, alias=royal.username)
|
||||
call.session.add(alias)
|
||||
await asyncify(call.session.commit)
|
||||
await call.reply(f"✅ Utente <code>{royal}</code> creato!")
|
||||
await call.reply(f"✅ Utente [c]{royal}[/c] creato!")
|
||||
|
|
|
@ -13,18 +13,28 @@ class DiarioCommand(Command):
|
|||
|
||||
require_alchemy_tables = {Royal, Diario, Alias}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
# Find the creator of the quotes
|
||||
creator = await call.get_author()
|
||||
if creator is None:
|
||||
await call.reply("⚠️ Devi essere registrato a Royalnet per usare questo comando!")
|
||||
return
|
||||
# Recreate the full sentence
|
||||
text = " ".join(args.args)
|
||||
raw_text = " ".join(call.args)
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([\w ]+))?(?:, *([^ ].*))?', text)
|
||||
match = re.match(r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([\w ]+))?(?:, *([^ ].*))?', raw_text)
|
||||
# Find the corresponding matches
|
||||
if match is None:
|
||||
raise InvalidInputError("No match found.")
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
if match is not None:
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
# Otherwise, consider everything part of the text
|
||||
else:
|
||||
spoiler = False
|
||||
text = raw_text
|
||||
quoted = None
|
||||
context = None
|
||||
timestamp = datetime.datetime.now()
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
if quoted is not None:
|
||||
|
@ -32,8 +42,6 @@ class DiarioCommand(Command):
|
|||
else:
|
||||
quoted_alias = None
|
||||
quoted_account = quoted_alias.royal if quoted_alias is not None else None
|
||||
# Find the creator of the quotes
|
||||
creator = await call.get_author()
|
||||
# Create the diario quote
|
||||
diario = call.alchemy.Diario(creator=creator,
|
||||
quoted_account=quoted_account,
|
||||
|
@ -45,4 +53,4 @@ class DiarioCommand(Command):
|
|||
spoiler=spoiler)
|
||||
call.session.add(diario)
|
||||
await asyncify(call.session.commit)
|
||||
await call.reply(f"✅ Aggiunto al diario!")
|
||||
await call.reply(f"✅ {str(diario)}")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from ..utils import Command, CommandArgs, Call, InvalidInputError
|
||||
|
||||
import traceback
|
||||
from logging import Logger
|
||||
from ..utils import Command, CommandArgs, Call, InvalidInputError, UnsupportedError
|
||||
|
||||
class ErrorHandlerCommand(Command):
|
||||
|
||||
|
@ -7,14 +8,20 @@ class ErrorHandlerCommand(Command):
|
|||
command_title = "Gestisce gli errori causati dagli altri comandi."
|
||||
command_syntax = ""
|
||||
|
||||
async def telegram(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
raise UnsupportedError()
|
||||
|
||||
async def telegram(self, call: Call):
|
||||
try:
|
||||
exc = args.kwargs["exception"]
|
||||
e_type, e_value, e_tb = call.kwargs["exception_info"]
|
||||
except InvalidInputError:
|
||||
await call.reply("⚠️ Questo comando non può essere chiamato da solo.")
|
||||
return
|
||||
if isinstance(exc, InvalidInputError):
|
||||
command = args.kwargs["previous_command"]
|
||||
if e_type == InvalidInputError:
|
||||
command = call.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.")
|
||||
await call.reply(f"❌ Eccezione non gestita durante l'esecuzione del comando:\n[b]{e_type.__name__}[/b]\n{e_value}")
|
||||
log: Logger = call.kwargs["log"]
|
||||
formatted_tb: str = '\n'.join(traceback.format_tb(e_tb))
|
||||
log.error(f"Unhandled exception - {e_type.__name__}: {e_value}\n{formatted_tb}")
|
||||
|
|
|
@ -7,5 +7,5 @@ class NullCommand(Command):
|
|||
command_title = "Non fa nulla."
|
||||
command_syntax = ""
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
pass
|
||||
|
|
|
@ -7,5 +7,5 @@ class PingCommand(Command):
|
|||
command_title = "Ping pong!"
|
||||
command_syntax = ""
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
await call.reply("🏓 Pong!")
|
||||
|
|
|
@ -11,11 +11,11 @@ class ShipCommand(Command):
|
|||
command_title = "Crea una ship tra due cose."
|
||||
command_syntax = "(uno) (due)"
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
name_one = args[0]
|
||||
name_two = args[1]
|
||||
async def common(self, call: Call):
|
||||
name_one = call.args[0]
|
||||
name_two = call.args[1]
|
||||
if name_two == "+":
|
||||
name_two = args[2]
|
||||
name_two = call.args[2]
|
||||
name_one = name_one.lower()
|
||||
name_two = name_two.lower()
|
||||
# Get all letters until the first vowel, included
|
||||
|
|
|
@ -57,6 +57,6 @@ class SmecdsCommand(Command):
|
|||
command_title = "Secondo me, è colpa dello stagista..."
|
||||
command_syntax = ""
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
ds = random.sample(DS_LIST, 1)[0]
|
||||
return await call.reply(safeformat(SMECDS, ds=ds))
|
||||
|
|
|
@ -12,17 +12,17 @@ class SyncCommand(Command):
|
|||
|
||||
require_alchemy_tables = {Royal, Telegram}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
async def common(self, call: Call):
|
||||
raise UnsupportedError()
|
||||
|
||||
async def telegram(self, call: Call, args: CommandArgs):
|
||||
update: Update = args.kwargs["update"]
|
||||
async def telegram(self, call: Call):
|
||||
update: Update = call.kwargs["update"]
|
||||
# Find the user
|
||||
user: typing.Optional[User] = update.effective_user
|
||||
if user is None:
|
||||
raise ValueError("Trying to sync a None user.")
|
||||
# Find the Royal
|
||||
royal = await asyncify(call.session.query(call.alchemy.Royal).filter_by(username=args[0]).one_or_none)
|
||||
royal = await asyncify(call.session.query(call.alchemy.Royal).filter_by(username=call.args[0]).one_or_none)
|
||||
if royal is None:
|
||||
await call.reply("⚠️ Non esiste alcun account Royalnet con quel nome.")
|
||||
return
|
||||
|
@ -46,4 +46,4 @@ class SyncCommand(Command):
|
|||
telegram.tg_username = user.username
|
||||
await call.reply(f"✅ Dati di [c]{str(telegram)}[/c] aggiornati.")
|
||||
# Commit the session
|
||||
await asyncify(call.session.commit())
|
||||
await asyncify(call.session.commit)
|
||||
|
|
|
@ -15,7 +15,7 @@ def relationshiplinkchain(starting_class, ending_class) -> typing.Optional[tuple
|
|||
if _relationship.mapper in inspected:
|
||||
continue
|
||||
result = search(_relationship.mapper, chain + (_relationship,))
|
||||
if len(result) == 0:
|
||||
if len(result) != 0:
|
||||
return result
|
||||
return ()
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import re
|
||||
from sqlalchemy import Column, \
|
||||
Integer, \
|
||||
Text, \
|
||||
|
@ -13,7 +14,7 @@ class Diario:
|
|||
__tablename__ = "diario"
|
||||
|
||||
diario_id = Column(Integer, primary_key=True)
|
||||
creator_id = Column(Integer, ForeignKey("royals.uid"))
|
||||
creator_id = Column(Integer, ForeignKey("royals.uid"), nullable=False)
|
||||
quoted_account_id = Column(Integer, ForeignKey("royals.uid"))
|
||||
quoted = Column(String)
|
||||
text = Column(Text, nullable=False)
|
||||
|
@ -27,3 +28,23 @@ class Diario:
|
|||
|
||||
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}>"
|
||||
|
||||
def __str__(self):
|
||||
# TODO: support media_url
|
||||
text = f"Riga #{self.diario_id}"
|
||||
text += f" (salvata da {self.creator.username}"
|
||||
text += f" alle {self.timestamp.strftime('%Y-%m-%d %H:%M')}):\n"
|
||||
if self.spoiler:
|
||||
hidden = re.sub("\w", "█", self.text)
|
||||
text += f"\"{hidden}\"\n"
|
||||
else:
|
||||
text += f"[b]\"{self.text}\"[/b]\n"
|
||||
if self.quoted_account is not None:
|
||||
text += f" —{self.quoted_account.username}"
|
||||
elif self.quoted is not None:
|
||||
text += f" —{self.quoted}"
|
||||
else:
|
||||
text += f" —Anonimo"
|
||||
if self.context:
|
||||
text += f", [i]{self.context}[/i]"
|
||||
return text
|
||||
|
|
|
@ -32,10 +32,10 @@ class Call:
|
|||
raise NotImplementedError()
|
||||
|
||||
# These parameters / methods should be left alone
|
||||
def __init__(self, channel, command: Command, *args, **kwargs):
|
||||
def __init__(self, channel, command: typing.Type[Command], command_args: list, **kwargs):
|
||||
self.channel = channel
|
||||
self.command = command
|
||||
self.args = args
|
||||
self.args = CommandArgs(command_args)
|
||||
self.kwargs = kwargs
|
||||
self.session = None
|
||||
|
||||
|
@ -56,7 +56,7 @@ class Call:
|
|||
except AttributeError:
|
||||
coroutine = getattr(self.command, "common")
|
||||
try:
|
||||
result = await coroutine(self.command, self, CommandArgs(*self.args, **self.kwargs))
|
||||
result = await coroutine(self.command, self)
|
||||
finally:
|
||||
await self.session_end()
|
||||
return result
|
||||
|
|
|
@ -13,23 +13,20 @@ class InvalidInputError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class CommandArgs:
|
||||
class CommandArgs(list):
|
||||
"""The arguments of a command. Raises InvalidInputError if the requested argument does not exist."""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
def __getitem__(self, item):
|
||||
if isinstance(item, int):
|
||||
try:
|
||||
return self.args[item]
|
||||
return super().__getitem__(item)
|
||||
except IndexError:
|
||||
raise InvalidInputError(f'Tried to get missing [{item}] arg from CommandArgs')
|
||||
elif isinstance(item, str):
|
||||
if isinstance(item, slice):
|
||||
try:
|
||||
return self.kwargs[item]
|
||||
return super().__getitem__(item)
|
||||
except IndexError:
|
||||
raise InvalidInputError(f'Tried to get missing ["{item}"] kwarg from CommandArgs')
|
||||
raise InvalidInputError(f'Tried to get invalid [{item}] slice from CommandArgs')
|
||||
raise ValueError(f"Invalid type passed to CommandArgs.__getattr__: {type(item)}")
|
||||
|
||||
|
||||
|
@ -42,5 +39,5 @@ class Command:
|
|||
|
||||
require_alchemy_tables: typing.Set = set()
|
||||
|
||||
async def common(self, call: "Call", args: CommandArgs):
|
||||
async def common(self, call: "Call"):
|
||||
raise NotImplementedError()
|
||||
|
|
Loading…
Reference in a new issue