1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Merge branch 'master' into beeg-refactor

# Conflicts:
#	royalnet/bots/generic.py
#	royalnet/commands/royalmusic/pause.py
#	royalnet/commands/royalmusic/play.py
This commit is contained in:
Steffo 2019-10-09 01:17:18 +02:00
commit a69cb05bd1
36 changed files with 79 additions and 35 deletions

View file

@ -24,19 +24,30 @@ class GenericBot:
def _init_commands(self) -> None: def _init_commands(self) -> None:
"""Generate the ``commands`` dictionary required to handle incoming messages, and the ``network_handlers`` """Generate the ``commands`` dictionary required to handle incoming messages, and the ``network_handlers``
dictionary required to handle incoming requests. """ dictionary required to handle incoming requests. """
log.debug(f"Now binding commands") log.info(f"Registering commands...")
self._Interface = self._interface_factory() self._Interface = self._interface_factory()
self._Data = self._data_factory() self._Data = self._data_factory()
self.commands = {} self.commands = {}
self.network_handlers: typing.Dict[str, typing.Type[NetworkHandler]] = {} self.network_handlers: typing.Dict[str, typing.Type[NetworkHandler]] = {}
for SelectedCommand in self.uninitialized_commands: for SelectedCommand in self.uninitialized_commands:
log.debug(f"Binding {SelectedCommand.name}...")
interface = self._Interface() interface = self._Interface()
try: try:
self.commands[f"{interface.prefix}{SelectedCommand.name}"] = SelectedCommand(interface) command = SelectedCommand(interface)
except Exception as e: except Exception as e:
log.error(f"{e.__class__.__name__} during the initialization of {SelectedCommand.name}, skipping...") log.error(f"{e.__class__.__qualname__} during the registration of {SelectedCommand.__qualname__}")
log.debug(f"Successfully bound commands") # Override the main command name, but warn if it's overriding something
if f"{interface.prefix}{SelectedCommand.name}" in self.commands:
log.warning(f"Overriding (already defined): {SelectedCommand.__qualname__} -> {interface.prefix}{SelectedCommand.name}")
else:
log.debug(f"Registering: {SelectedCommand.__qualname__} -> {interface.prefix}{SelectedCommand.name}")
self.commands[f"{interface.prefix}{SelectedCommand.name}"] = command
# Register aliases, but don't override anything
for alias in SelectedCommand.aliases:
if f"{interface.prefix}{alias}" not in self.commands:
log.debug(f"Aliasing: {SelectedCommand.__qualname__} -> {interface.prefix}{alias}")
self.commands[f"{interface.prefix}{alias}"] = self.commands[f"{interface.prefix}{SelectedCommand.name}"]
else:
log.info(f"Ignoring (already defined): {SelectedCommand.__qualname__} -> {interface.prefix}{alias}")
def _interface_factory(self) -> typing.Type[CommandInterface]: def _interface_factory(self) -> typing.Type[CommandInterface]:
# noinspection PyAbstractClass,PyMethodParameters # noinspection PyAbstractClass,PyMethodParameters
@ -118,20 +129,23 @@ class GenericBot:
"""Create an :py:class:`royalnet.database.Alchemy` with the tables required by the commands. Then, """Create an :py:class:`royalnet.database.Alchemy` with the tables required by the commands. Then,
find the chain that links the ``master_table`` to the ``identity_table``. """ find the chain that links the ``master_table`` to the ``identity_table``. """
if self.uninitialized_database_config: if self.uninitialized_database_config:
log.debug(f"Initializing database") log.info(f"Database: enabled")
required_tables = {self.uninitialized_database_config.master_table, self.uninitialized_database_config.identity_table} required_tables = {self.uninitialized_database_config.master_table, self.uninitialized_database_config.identity_table}
for command in self.uninitialized_commands: for command in self.uninitialized_commands:
required_tables = required_tables.union(command.require_alchemy_tables) required_tables = required_tables.union(command.require_alchemy_tables)
log.debug(f"Found {len(required_tables)} required tables") log.debug(f"Required tables: {', '.join([item.__qualname__ for item in required_tables])}")
self.alchemy = Alchemy(self.uninitialized_database_config.database_uri, required_tables) self.alchemy = Alchemy(self.uninitialized_database_config.database_uri, required_tables)
self.master_table = self.alchemy.__getattribute__(self.uninitialized_database_config.master_table.__qualname__) self.master_table = self.alchemy.__getattribute__(self.uninitialized_database_config.master_table.__name__)
self.identity_table = self.alchemy.__getattribute__(self.uninitialized_database_config.identity_table.__qualname__) log.debug(f"Master table: {self.master_table.__qualname__}")
self.identity_table = self.alchemy.__getattribute__(self.uninitialized_database_config.identity_table.__name__)
log.debug(f"Identity table: {self.identity_table.__qualname__}")
self.identity_column = self.identity_table.__getattribute__(self.identity_table, self.identity_column = self.identity_table.__getattribute__(self.identity_table,
self.uninitialized_database_config.identity_column_name) self.uninitialized_database_config.identity_column_name)
log.debug(f"Identity column: {self.identity_column.__class__.__qualname__}")
self.identity_chain = relationshiplinkchain(self.master_table, self.identity_table) self.identity_chain = relationshiplinkchain(self.master_table, self.identity_table)
log.debug(f"Identity chain is {self.identity_chain}") log.debug(f"Identity chain: {' -> '.join([str(item) for item in self.identity_chain])}")
else: else:
log.debug(f"Database is not enabled, setting everything to None") log.debug(f"Database: disabled")
self.alchemy = None self.alchemy = None
self.master_table = None self.master_table = None
self.identity_table = None self.identity_table = None
@ -139,13 +153,13 @@ class GenericBot:
def _init_sentry(self): def _init_sentry(self):
if self.uninitialized_sentry_dsn: if self.uninitialized_sentry_dsn:
log.debug("Sentry integration enabled") log.info("Sentry: enabled")
self.sentry = sentry_sdk.init(self.uninitialized_sentry_dsn, self.sentry = sentry_sdk.init(self.uninitialized_sentry_dsn,
integrations=[AioHttpIntegration(), integrations=[AioHttpIntegration(),
SqlalchemyIntegration(), SqlalchemyIntegration(),
LoggingIntegration(event_level=None)]) LoggingIntegration(event_level=None)])
else: else:
log.debug("Sentry integration disabled") log.info("Sentry: disabled")
def _init_loop(self): def _init_loop(self):
if self.uninitialized_loop is None: if self.uninitialized_loop is None:

View file

@ -9,7 +9,7 @@ class Command:
"""The main name of the command. """The main name of the command.
To have ``/example`` on Telegram, the name should be ``example``.""" To have ``/example`` on Telegram, the name should be ``example``."""
aliases: typing.List[str] = NotImplemented aliases: typing.List[str] = []
"""A list of possible aliases for a command. """A list of possible aliases for a command.
To have ``/e`` as alias for ``/example``, one should set aliases to ``["e"]``.""" To have ``/e`` as alias for ``/example``, one should set aliases to ``["e"]``."""

View file

@ -11,6 +11,8 @@ from ...utils import parse_5etools_entry
class DnditemCommand(Command): class DnditemCommand(Command):
name: str = "dnditem" name: str = "dnditem"
aliases = ["item"]
description: str = "Ottieni informazioni su un oggetto di D&D5e." description: str = "Ottieni informazioni su un oggetto di D&D5e."
syntax = "(nomeoggetto)" syntax = "(nomeoggetto)"

View file

@ -11,6 +11,8 @@ from ...utils import parse_5etools_entry, ordinalformat, andformat
class DndspellCommand(Command): class DndspellCommand(Command):
name: str = "dndspell" name: str = "dndspell"
aliases = ["spell"]
description: str = "Ottieni informazioni su una magia di D&D5e." description: str = "Ottieni informazioni su una magia di D&D5e."
syntax = "(nomemagia)" syntax = "(nomemagia)"

View file

@ -21,6 +21,8 @@ class MmCommand(Command):
Requires the MM_CHANNEL_ID envvar to be set.""" Requires the MM_CHANNEL_ID envvar to be set."""
name: str = "mm" name: str = "mm"
aliases = ["matchmaking", "matchmake"]
description: str = "Trova giocatori per una partita a qualcosa." description: str = "Trova giocatori per una partita a qualcosa."
syntax: str = "[ (data) ] (nomegioco)\n[descrizione]" syntax: str = "[ (data) ] (nomegioco)\n[descrizione]"

View file

@ -6,7 +6,9 @@ from ..commanddata import CommandData
class RageCommand(Command): class RageCommand(Command):
name: str = "ship" name: str = "rage"
aliases = ["balurage", "madden"]
description: str = "Arrabbiati per qualcosa, come una software house californiana." description: str = "Arrabbiati per qualcosa, come una software house californiana."

View file

@ -16,6 +16,8 @@ from ..commanderrors import InvalidInputError, UnsupportedError
class ReminderCommand(Command): class ReminderCommand(Command):
name: str = "reminder" name: str = "reminder"
aliases = ["calendar"]
description: str = "Ti ricorda di fare qualcosa dopo un po' di tempo." description: str = "Ti ricorda di fare qualcosa dopo un po' di tempo."
syntax: str = "[ (data) ] (messaggio)" syntax: str = "[ (data) ] (messaggio)"

View file

@ -9,6 +9,8 @@ from ...utils import safeformat
class ShipCommand(Command): class ShipCommand(Command):
name: str = "ship" name: str = "ship"
aliases = ["⛵️"]
description: str = "Crea una ship tra due nomi." description: str = "Crea una ship tra due nomi."
syntax = "(nomeuno) (nomedue)" syntax = "(nomeuno) (nomedue)"

View file

@ -9,6 +9,8 @@ from ...utils import safeformat
class SmecdsCommand(Command): class SmecdsCommand(Command):
name: str = "smecds" name: str = "smecds"
aliases = ["secondomeecolpadellostagista"]
description: str = "Secondo me, è colpa dello stagista..." description: str = "Secondo me, è colpa dello stagista..."
syntax = "" syntax = ""

View file

@ -16,6 +16,8 @@ from ...database.tables import TriviaScore
class TriviaCommand(Command): class TriviaCommand(Command):
name: str = "trivia" name: str = "trivia"
aliases = ["t"]
description: str = "Manda una domanda dell'OpenTDB in chat." description: str = "Manda una domanda dell'OpenTDB in chat."
require_alchemy_tables = {TriviaScore} require_alchemy_tables = {TriviaScore}

View file

@ -9,6 +9,8 @@ from ..commanderrors import CommandError, UnsupportedError
class VideochannelCommand(Command): class VideochannelCommand(Command):
name: str = "videochannel" name: str = "videochannel"
aliases = ["golive", "live", "video"]
description: str = "Converti il canale vocale in un canale video." description: str = "Converti il canale vocale in un canale video."
syntax = "[channelname]" syntax = "[channelname]"

View file

@ -11,6 +11,8 @@ from ...audio import YtdlMp3
class Mp3Command(Command): class Mp3Command(Command):
name: str = "mp3" name: str = "mp3"
aliases = ["dlmusic"]
description: str = "Scarica un video con youtube-dl e invialo in chat." description: str = "Scarica un video con youtube-dl e invialo in chat."
syntax = "(ytdlstring)" syntax = "(ytdlstring)"

View file

@ -47,6 +47,8 @@ class PlaymodeNH(NetworkHandler):
class PlaymodeCommand(Command): class PlaymodeCommand(Command):
name: str = "playmode" name: str = "playmode"
aliases = ["pm", "mode"]
description: str = "Cambia modalità di riproduzione per la chat vocale." description: str = "Cambia modalità di riproduzione per la chat vocale."
syntax = "[ [guild] ] (mode)" syntax = "[ [guild] ] (mode)"

View file

@ -52,6 +52,8 @@ class QueueNH(NetworkHandler):
class QueueCommand(Command): class QueueCommand(Command):
name: str = "queue" name: str = "queue"
aliases = ["q"]
description: str = "Visualizza la coda di riproduzione attuale." description: str = "Visualizza la coda di riproduzione attuale."
syntax = "[ [guild] ]" syntax = "[ [guild] ]"

View file

@ -40,6 +40,8 @@ class SkipNH(NetworkHandler):
class SkipCommand(Command): class SkipCommand(Command):
name: str = "skip" name: str = "skip"
aliases = ["s", "next", "n"]
description: str = "Salta la canzone attualmente in riproduzione in chat vocale." description: str = "Salta la canzone attualmente in riproduzione in chat vocale."
syntax: str = "[ [guild] ]" syntax: str = "[ [guild] ]"

View file

@ -29,6 +29,8 @@ class SummonNH(NetworkHandler):
class SummonCommand(Command): class SummonCommand(Command):
name: str = "summon" name: str = "summon"
aliases = ["cv"]
description: str = "Evoca il bot in un canale vocale." description: str = "Evoca il bot in un canale vocale."
syntax: str = "[nomecanale]" syntax: str = "[nomecanale]"

View file

@ -77,6 +77,8 @@ class ZawarudoNH(NetworkHandler):
class ZawarudoCommand(Command): class ZawarudoCommand(Command):
name: str = "zawarudo" name: str = "zawarudo"
aliases = ["theworld", "world"]
description: str = "Ferma il tempo!" description: str = "Ferma il tempo!"
syntax = "[ [guild] ] [1-9]" syntax = "[ [guild] ] [1-9]"

View file

@ -1,4 +1,4 @@
from .royals import User from .users import User
from .telegram import Telegram from .telegram import Telegram
from .diario import Diario from .diario import Diario
from .aliases import Alias from .aliases import Alias

View file

@ -5,7 +5,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .keygroups import Keygroup from .keygroups import Keygroup

View file

@ -5,7 +5,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class Alias: class Alias:

View file

@ -4,7 +4,7 @@ from sqlalchemy import Column, \
ForeignKey ForeignKey
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from .royals import User from .users import User
class Bio: class Bio:

View file

@ -9,7 +9,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class Diario: class Diario:

View file

@ -6,7 +6,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class Discord: class Discord:

View file

@ -4,7 +4,7 @@ from sqlalchemy import Column, \
ForeignKey ForeignKey
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .royals import User from .users import User
from .medals import Medal from .medals import Medal

View file

@ -4,7 +4,7 @@ from sqlalchemy import Column, \
ForeignKey ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from .royals import User from .users import User
from .mmevents import MMEvent from .mmevents import MMEvent

View file

@ -9,7 +9,7 @@ from sqlalchemy import Column, \
BigInteger BigInteger
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from .royals import User from .users import User
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from .mmdecisions import MMDecision from .mmdecisions import MMDecision
from .mmresponse import MMResponse from .mmresponse import MMResponse

View file

@ -4,7 +4,7 @@ from sqlalchemy import Column, \
ForeignKey ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from .royals import User from .users import User
from .mmevents import MMEvent from .mmevents import MMEvent

View file

@ -7,7 +7,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class Reminder: class Reminder:

View file

@ -6,7 +6,7 @@ from sqlalchemy import Column, \
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class Telegram: class Telegram:

View file

@ -3,7 +3,7 @@ from sqlalchemy import Column, \
ForeignKey ForeignKey
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import declared_attr
from .royals import User from .users import User
class TriviaScore: class TriviaScore:

View file

@ -9,7 +9,7 @@ from sqlalchemy.ext.declarative import declared_attr
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .wikipages import WikiPage from .wikipages import WikiPage
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from .royals import User from .users import User
class WikiRevision: class WikiRevision:

View file

@ -1 +1 @@
semantic = "5.0a62" semantic = "5.0a63"

View file

@ -25,7 +25,7 @@ def login_done():
fd = f.request.form fd = f.request.form
if "username" not in fd: if "username" not in fd:
return error(400, "Nessun username inserito.") return error(400, "Nessun username inserito.")
royal_user = alchemy_session.query(alchemy.Royal).filter_by(username=fd["username"]).one_or_none() royal_user = alchemy_session.query(alchemy.User).filter_by(username=fd["username"]).one_or_none()
if royal_user is None: if royal_user is None:
return error(404, "L'username inserito non corrisponde a nessun account registrato.") return error(404, "L'username inserito non corrisponde a nessun account registrato.")
if "password" not in fd: if "password" not in fd:

View file

@ -23,7 +23,7 @@ def login_index():
return error(400, "Non è stato inserito nessun username.") return error(400, "Non è stato inserito nessun username.")
if "password" not in fd: if "password" not in fd:
return error(400, "Non è stata inserita nessuna password.") return error(400, "Non è stata inserita nessuna password.")
royal = alchemy_session.query(alchemy.Royal).filter_by(username=fd["username"]).one_or_none() royal = alchemy_session.query(alchemy.User).filter_by(username=fd["username"]).one_or_none()
if royal is not None: if royal is not None:
return error(403, "Esiste già un utente con quell'username.") return error(403, "Esiste già un utente con quell'username.")
alias = alchemy_session.query(alchemy.Alias).filter_by(alias=fd["username"]).one_or_none() alias = alchemy_session.query(alchemy.Alias).filter_by(alias=fd["username"]).one_or_none()

View file

@ -18,14 +18,14 @@ rp = Royalprint("profile", __name__, url_prefix="/profile", template_folder=tmpl
@rp.route("/") @rp.route("/")
def profile_index(): def profile_index():
alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"] alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
royals = alchemy_session.query(alchemy.Royal).order_by(alchemy.Royal.username).all() royals = alchemy_session.query(alchemy.User).order_by(alchemy.User.username).all()
return f.render_template("profile_index.html", royals=royals) return f.render_template("profile_index.html", royals=royals)
@rp.route("/<username>") @rp.route("/<username>")
def profile_page(username): def profile_page(username):
alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"] alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
royal = alchemy_session.query(alchemy.Royal).filter_by(username=username).one_or_none() royal = alchemy_session.query(alchemy.User).filter_by(username=username).one_or_none()
if royal is None: if royal is None:
return error(404, "Non esiste nessun utente con l'username richiesto.") return error(404, "Non esiste nessun utente con l'username richiesto.")
if royal.bio is not None and royal.bio.contents != "": if royal.bio is not None and royal.bio.contents != "":
@ -43,7 +43,7 @@ def profile_editbio(username):
if "royal" not in f.session: if "royal" not in f.session:
return error(403, "Devi aver effettuato il login per modificare una bio.") return error(403, "Devi aver effettuato il login per modificare una bio.")
alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"] alchemy, alchemy_session = f.current_app.config["ALCHEMY"], f.current_app.config["ALCHEMY_SESSION"]
royal = alchemy_session.query(alchemy.Royal).filter_by(username=username).one_or_none() royal = alchemy_session.query(alchemy.User).filter_by(username=username).one_or_none()
if not (f.session["royal"]["uid"] == royal.uid or f.session["royal"]["role"] == "Admin"): if not (f.session["royal"]["uid"] == royal.uid or f.session["royal"]["role"] == "Admin"):
return error(403, "Non sei autorizzato a modificare questa pagina bio.") return error(403, "Non sei autorizzato a modificare questa pagina bio.")