mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Change an enormous amount of stuff
This commit is contained in:
parent
1750522321
commit
4a07afe72b
72 changed files with 232 additions and 461 deletions
2
docs/html/_static/jquery-3.4.1.js
vendored
2
docs/html/_static/jquery-3.4.1.js
vendored
|
@ -5170,7 +5170,7 @@ jQuery.event = {
|
|||
}
|
||||
}
|
||||
|
||||
// Remove generic event handler if we removed something and no more handlers exist
|
||||
// Remove common event handler if we removed something and no more handlers exist
|
||||
// (avoids potential for endless recursion during removal of special event handlers)
|
||||
if ( origCount && !handlers.length ) {
|
||||
if ( !special.teardown ||
|
||||
|
|
|
@ -5,66 +5,7 @@ These pages were automatically generated from docstrings in code.
|
|||
|
||||
They might be outdated, or incomplete.
|
||||
|
||||
Audio
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.audio
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Bots
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.bots
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Commands
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.commands
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Database
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.database
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Network
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.network
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Utils
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Web
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.web
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
||||
Error
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: royalnet.error
|
||||
.. automodule:: royalnet
|
||||
:members:
|
||||
:undoc-members:
|
||||
:private-members:
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from . import audio, bots, database, utils, error, web, version
|
||||
from royalnet import commands
|
||||
from . import audio, bots, commands, packs, database, utils, error, web, version
|
||||
|
||||
__all__ = ["audio", "bots", "commands", "database", "utils", "error", "web", "version"]
|
||||
|
|
|
@ -2,6 +2,7 @@ import click
|
|||
import typing
|
||||
import importlib
|
||||
import royalnet as r
|
||||
import royalherald as rh
|
||||
import multiprocessing
|
||||
import keyring
|
||||
|
||||
|
@ -13,8 +14,8 @@ import keyring
|
|||
help="Enable/disable the Discord module.")
|
||||
@click.option("-d", "--database", type=str, default=None,
|
||||
help="The PostgreSQL database path.")
|
||||
@click.option("-c", "--command-packs", type=str, multiple=True, default=[],
|
||||
help="The names of the command pack modules that should be imported.")
|
||||
@click.option("-p", "--packs", type=str, multiple=True, default=[],
|
||||
help="The names of the Packs that should be used.")
|
||||
@click.option("-n", "--network-address", type=str, default=None,
|
||||
help="The Network server URL to connect to.")
|
||||
@click.option("-l", "--local-network-server", is_flag=True, default=False,
|
||||
|
@ -26,7 +27,7 @@ import keyring
|
|||
def run(telegram: typing.Optional[bool],
|
||||
discord: typing.Optional[bool],
|
||||
database: typing.Optional[str],
|
||||
command_packs: typing.List[str],
|
||||
packs: typing.List[str],
|
||||
network_address: typing.Optional[str],
|
||||
local_network_server: bool,
|
||||
secrets_name: str,
|
||||
|
@ -63,41 +64,38 @@ def run(telegram: typing.Optional[bool],
|
|||
# Start the network server
|
||||
if local_network_server:
|
||||
server_process = multiprocessing.Process(name="Network Server",
|
||||
target=r.network.NetworkServer("0.0.0.0",
|
||||
44444,
|
||||
network_password).run_blocking,
|
||||
target=rh.Server("0.0.0.0", 44444, network_password).run_blocking,
|
||||
daemon=True)
|
||||
server_process.start()
|
||||
network_address = "ws://127.0.0.1:44444/"
|
||||
|
||||
# Create a Royalnet configuration
|
||||
network_config: typing.Optional[r.network.NetworkConfig] = None
|
||||
network_config: typing.Optional[rh.Config] = None
|
||||
if network_address is not None:
|
||||
network_config = r.network.NetworkConfig(network_address, network_password)
|
||||
network_config = rh.Config(network_address, network_password)
|
||||
|
||||
# Create a Alchemy configuration
|
||||
telegram_db_config: typing.Optional[r.database.DatabaseConfig] = None
|
||||
discord_db_config: typing.Optional[r.database.DatabaseConfig] = None
|
||||
if database is not None:
|
||||
telegram_db_config = r.database.DatabaseConfig(database,
|
||||
r.database.tables.User,
|
||||
r.database.tables.Telegram,
|
||||
r.packs.common.tables.User,
|
||||
r.packs.common.tables.Telegram,
|
||||
"tg_id")
|
||||
discord_db_config = r.database.DatabaseConfig(database,
|
||||
r.database.tables.User,
|
||||
r.database.tables.Discord,
|
||||
r.packs.common.tables.User,
|
||||
r.packs.common.tables.Discord,
|
||||
"discord_id")
|
||||
|
||||
# Import command packs
|
||||
if not command_packs:
|
||||
raise click.ClickException("No command packs were specified.")
|
||||
packs.append("royalnet.packs.common") # common pack is always imported
|
||||
enabled_commands = []
|
||||
for pack in command_packs:
|
||||
for pack in packs:
|
||||
imported = importlib.import_module(pack)
|
||||
try:
|
||||
imported_commands = imported.commands
|
||||
except AttributeError:
|
||||
raise click.ClickException(f"{pack} isn't a Royalnet command pack.")
|
||||
raise click.ClickException(f"{pack} isn't a Royalnet Pack.")
|
||||
enabled_commands = [*enabled_commands, *imported_commands]
|
||||
|
||||
telegram_process: typing.Optional[multiprocessing.Process] = None
|
||||
|
|
|
@ -52,7 +52,7 @@ class PlayMode:
|
|||
def queue_preview(self) -> typing.List[YtdlDiscord]:
|
||||
"""Display all the videos in the PlayMode as a list, if possible.
|
||||
|
||||
To be used with ``queue`` commands, for example.
|
||||
To be used with ``queue`` packs, for example.
|
||||
|
||||
Raises:
|
||||
NotImplementedError: If a preview can't be generated.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Various bot interfaces, and a generic class to create new ones."""
|
||||
"""Various bot interfaces, and a common class to create new ones."""
|
||||
|
||||
from .generic import GenericBot
|
||||
from .telegram import TelegramBot
|
||||
|
|
|
@ -5,7 +5,7 @@ from .generic import GenericBot
|
|||
from ..utils import *
|
||||
from ..error import *
|
||||
from ..audio import *
|
||||
from ..commands import *
|
||||
from ..packs import *
|
||||
|
||||
log = _logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
|||
from sentry_sdk.integrations.logging import LoggingIntegration
|
||||
from ..utils import *
|
||||
from ..database import *
|
||||
from ..commands import *
|
||||
from ..packs import *
|
||||
from ..error import *
|
||||
|
||||
|
||||
|
@ -17,14 +17,14 @@ log = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class GenericBot:
|
||||
"""A generic bot class, to be used as base for the other more specific classes, such as
|
||||
"""A common bot class, to be used as base for the other more specific classes, such as
|
||||
:py:class:`royalnet.bots.TelegramBot` and :py:class:`royalnet.bots.DiscordBot`. """
|
||||
interface_name = NotImplemented
|
||||
|
||||
def _init_commands(self) -> None:
|
||||
"""Generate the ``commands`` dictionary required to handle incoming messages, and the ``network_handlers``
|
||||
"""Generate the ``packs`` dictionary required to handle incoming messages, and the ``network_handlers``
|
||||
dictionary required to handle incoming requests. """
|
||||
log.info(f"Registering commands...")
|
||||
log.info(f"Registering packs...")
|
||||
self._Interface = self._interface_factory()
|
||||
self._Data = self._data_factory()
|
||||
self.commands = {}
|
||||
|
@ -126,7 +126,7 @@ class GenericBot:
|
|||
}).to_dict()
|
||||
|
||||
def _init_database(self):
|
||||
"""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 packs. Then,
|
||||
find the chain that links the ``master_table`` to the ``identity_table``. """
|
||||
if self.uninitialized_database_config:
|
||||
log.info(f"Database: enabled")
|
||||
|
@ -198,7 +198,7 @@ class GenericBot:
|
|||
self.initialized = True
|
||||
|
||||
def run(self):
|
||||
"""A blocking coroutine that should make the bot start listening to commands and requests."""
|
||||
"""A blocking coroutine that should make the bot start listening to packs and requests."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def run_blocking(self, verbose=False):
|
||||
|
|
|
@ -5,10 +5,11 @@ import urllib3
|
|||
import asyncio
|
||||
import sentry_sdk
|
||||
import logging as _logging
|
||||
import warnings
|
||||
from .generic import GenericBot
|
||||
from ..utils import *
|
||||
from ..error import *
|
||||
from ..commands import *
|
||||
from ..packs import *
|
||||
|
||||
|
||||
log = _logging.getLogger(__name__)
|
||||
|
@ -84,6 +85,7 @@ class TelegramBot(GenericBot):
|
|||
return result
|
||||
|
||||
async def keyboard(data, text: str, keyboard: typing.Dict[str, typing.Callable]) -> None:
|
||||
warnings.warn("keyboard is deprecated, please avoid using it", category=DeprecationWarning)
|
||||
tg_keyboard = []
|
||||
for key in keyboard:
|
||||
press_id = uuid.uuid4()
|
||||
|
|
|
@ -20,7 +20,7 @@ class Command:
|
|||
"""The syntax of the command, to be displayed when a :py:exc:`royalnet.error.InvalidInputError` is raised,
|
||||
in the format ``(required_arg) [optional_arg]``."""
|
||||
|
||||
require_alchemy_tables: typing.Set = set()
|
||||
tables: typing.Set = set()
|
||||
"""A set of :py:class:`royalnet.database` tables that must exist for this command to work."""
|
||||
|
||||
def __init__(self, interface: CommandInterface):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import typing
|
||||
import warnings
|
||||
from .commanderrors import UnsupportedError
|
||||
|
||||
|
||||
|
@ -22,6 +23,7 @@ class CommandData:
|
|||
"""Send a keyboard having the keys of the dict as keys and calling the correspondent values on a press.
|
||||
|
||||
The function should be passed the :py:class:`CommandData` instance as a argument."""
|
||||
warnings.warn("keyboard is deprecated, please avoid using it", category=DeprecationWarning)
|
||||
raise UnsupportedError("'keyboard' is not supported on this platform")
|
||||
|
||||
async def delete_invoking(self, error_if_unavailable=False) -> None:
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
from .debug_error import DebugErrorCommand
|
||||
from .debug_keyboard import DebugKeyboardCommand
|
||||
from .debug_invoking import DebugInvokingCommand
|
||||
|
||||
|
||||
commands = [
|
||||
DebugErrorCommand,
|
||||
DebugKeyboardCommand,
|
||||
DebugInvokingCommand,
|
||||
]
|
||||
|
||||
|
||||
__all__ = [command.__name__ for command in commands]
|
|
@ -1,13 +0,0 @@
|
|||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
|
||||
|
||||
class DebugErrorCommand(Command):
|
||||
name: str = "debug_error"
|
||||
|
||||
description: str = "Causa un'eccezione nel bot."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
raise Exception("debug_error command was called")
|
|
@ -1,14 +0,0 @@
|
|||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
|
||||
|
||||
class DebugInvokingCommand(Command):
|
||||
name: str = "debug_invoking"
|
||||
|
||||
description: str = "Elimina il messaggio di invocazione."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
await data.delete_invoking(error_if_unavailable=True)
|
||||
await data.reply("🗑 Messaggio eliminato.")
|
|
@ -1,18 +0,0 @@
|
|||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
|
||||
|
||||
class DebugKeyboardCommand(Command):
|
||||
name: str = "debug_keyboard"
|
||||
|
||||
description: str = "Invia una tastiera di prova."
|
||||
|
||||
async def _callback(self, data: CommandData):
|
||||
await data.reply("OK.")
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
await data.keyboard("This is a keyboard.", {
|
||||
"✅ OK": self._callback
|
||||
})
|
|
@ -1,13 +0,0 @@
|
|||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
|
||||
|
||||
class PingCommand(Command):
|
||||
name: str = "ping"
|
||||
|
||||
description: str = "Gioca a ping-pong con il bot."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
await data.reply("🏓 Pong!")
|
|
@ -1,30 +0,0 @@
|
|||
"""Commands that can be used in bots.
|
||||
|
||||
These probably won't suit your needs, as they are tailored for the bots of the User Games gaming community, but they
|
||||
may be useful to develop new ones."""
|
||||
|
||||
from .pause import PauseCommand
|
||||
from .play import PlayCommand
|
||||
from .playmode import PlaymodeCommand
|
||||
from .queue import QueueCommand
|
||||
from .skip import SkipCommand
|
||||
from .summon import SummonCommand
|
||||
from .youtube import YoutubeCommand
|
||||
from .soundcloud import SoundcloudCommand
|
||||
from .zawarudo import ZawarudoCommand
|
||||
|
||||
|
||||
commands = [
|
||||
PauseCommand,
|
||||
PlayCommand,
|
||||
PlaymodeCommand,
|
||||
QueueCommand,
|
||||
SkipCommand,
|
||||
SummonCommand,
|
||||
YoutubeCommand,
|
||||
SoundcloudCommand,
|
||||
ZawarudoCommand
|
||||
]
|
||||
|
||||
|
||||
__all__ = [command.__name__ for command in commands]
|
|
@ -3,6 +3,5 @@
|
|||
from .alchemy import Alchemy
|
||||
from .relationshiplinkchain import relationshiplinkchain
|
||||
from .databaseconfig import DatabaseConfig
|
||||
from . import tables
|
||||
|
||||
__all__ = ["Alchemy", "relationshiplinkchain", "DatabaseConfig", "tables"]
|
||||
__all__ = ["Alchemy", "relationshiplinkchain", "DatabaseConfig"]
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
from .users import User
|
||||
from .telegram import Telegram
|
||||
from .diario import Diario
|
||||
from .aliases import Alias
|
||||
from .activekvgroups import ActiveKvGroup
|
||||
from .keyvalues import Keyvalue
|
||||
from .keygroups import Keygroup
|
||||
from .discord import Discord
|
||||
from .wikipages import WikiPage
|
||||
from .wikirevisions import WikiRevision
|
||||
from .medals import Medal
|
||||
from .medalawards import MedalAward
|
||||
from .bios import Bio
|
||||
from .reminders import Reminder
|
||||
from .triviascores import TriviaScore
|
||||
from .mmdecisions import MMDecision
|
||||
from .mmevents import MMEvent
|
||||
from .mmresponse import MMResponse
|
||||
|
||||
__all__ = ["User", "Telegram", "Diario", "Alias", "ActiveKvGroup", "Keyvalue", "Keygroup", "Discord", "WikiPage",
|
||||
"WikiRevision", "Medal", "MedalAward", "Bio", "Reminder", "TriviaScore", "MMDecision", "MMEvent",
|
||||
"MMResponse"]
|
|
@ -1,39 +0,0 @@
|
|||
from sqlalchemy import Column, \
|
||||
Integer, \
|
||||
DateTime, \
|
||||
ForeignKey
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from sqlalchemy.orm import relationship
|
||||
from .users import User
|
||||
from .medals import Medal
|
||||
|
||||
|
||||
class MedalAward:
|
||||
__tablename__ = "MedalAward"
|
||||
|
||||
@declared_attr
|
||||
def award_id(self):
|
||||
return Column(Integer, primary_key=True)
|
||||
|
||||
@declared_attr
|
||||
def date(self):
|
||||
return Column(DateTime)
|
||||
|
||||
@declared_attr
|
||||
def medal_id(self):
|
||||
return Column(Integer, ForeignKey("medals.mid"), nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def royal_id(self):
|
||||
return Column(Integer, ForeignKey("users.uid"), nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def medal(self):
|
||||
return relationship("Medal", backref="awarded_to")
|
||||
|
||||
@declared_attr
|
||||
def royal(self):
|
||||
return relationship("User", backref="medals_received")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<MedalAward of {self.medal} to {self.royal} on {self.date}>"
|
|
@ -1,40 +0,0 @@
|
|||
from sqlalchemy import Column, \
|
||||
Integer, \
|
||||
String
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .keygroups import Keygroup
|
||||
|
||||
|
||||
class Medal:
|
||||
__tablename__ = "medals"
|
||||
|
||||
@declared_attr
|
||||
def mid(self):
|
||||
return Column(Integer, primary_key=True)
|
||||
|
||||
@declared_attr
|
||||
def name(self):
|
||||
return Column(String, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def description(self):
|
||||
return Column(String)
|
||||
|
||||
@declared_attr
|
||||
def icon(self):
|
||||
return Column(String)
|
||||
|
||||
@declared_attr
|
||||
def classes(self):
|
||||
return Column(String, nullable=False, default="")
|
||||
|
||||
@declared_attr
|
||||
def score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Medal {self.mid}: {self.name}>"
|
7
royalnet/packs/__init__.py
Normal file
7
royalnet/packs/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from . import common
|
||||
from . import royal
|
||||
|
||||
__all__ = [
|
||||
"common",
|
||||
"royal",
|
||||
]
|
6
royalnet/packs/common/__init__.py
Normal file
6
royalnet/packs/common/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
# This is a template Pack __init__. You can use this without changing anything in other packages too!
|
||||
|
||||
from .commands import commands
|
||||
from .tables import tables
|
||||
|
||||
__all__ = ["commands", "tables"]
|
10
royalnet/packs/common/commands/__init__.py
Normal file
10
royalnet/packs/common/commands/__init__.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Imports go here!
|
||||
from .ping import PingCommand
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
commands = [
|
||||
PingCommand,
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [command.__class__.__qualname__ for command in commands]
|
10
royalnet/packs/common/commands/ping.py
Normal file
10
royalnet/packs/common/commands/ping.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from royalnet.commands import *
|
||||
|
||||
|
||||
class PingCommand(Command):
|
||||
name: str = "ping"
|
||||
|
||||
description: str = "Get a pong response."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
await data.reply("🏓 Pong!")
|
14
royalnet/packs/common/tables/__init__.py
Normal file
14
royalnet/packs/common/tables/__init__.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Imports go here!
|
||||
from .users import User
|
||||
from .telegram import Telegram
|
||||
from .discord import Discord
|
||||
|
||||
# Enter the tables of your Pack here!
|
||||
tables = [
|
||||
User,
|
||||
Telegram,
|
||||
Discord
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [table.__class__.__qualname__ for table in tables]
|
|
@ -29,7 +29,7 @@ class User:
|
|||
return Column(LargeBinary)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User {self.username}>"
|
||||
return f"<{self.__class__.__qualname__} {self.username}>"
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
7
royalnet/packs/empty/__init__.py
Normal file
7
royalnet/packs/empty/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This is a template Pack __init__. You can use this without changing anything in other packages too!
|
||||
|
||||
from .commands import commands
|
||||
from .tables import tables
|
||||
|
||||
__all__ = ["commands", "tables"]
|
||||
|
10
royalnet/packs/empty/commands/__init__.py
Normal file
10
royalnet/packs/empty/commands/__init__.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Imports go here!
|
||||
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
commands = [
|
||||
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [command.__class__.__qualname__ for command in commands]
|
10
royalnet/packs/empty/tables/__init__.py
Normal file
10
royalnet/packs/empty/tables/__init__.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Imports go here!
|
||||
|
||||
|
||||
# Enter the tables of your Pack here!
|
||||
tables = [
|
||||
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [table.__class__.__qualname__ for table in tables]
|
6
royalnet/packs/royal/__init__.py
Normal file
6
royalnet/packs/royal/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
# This is a template Pack __init__. You can use this without changing anything in other packages too!
|
||||
|
||||
from .commands import commands
|
||||
from .tables import tables
|
||||
|
||||
__all__ = ["commands", "tables"]
|
|
@ -1,13 +1,8 @@
|
|||
"""Commands that can be used in bots.
|
||||
|
||||
These probably won't suit your needs, as they are tailored for the bots of the User Games gaming community, but they
|
||||
may be useful to develop new ones."""
|
||||
|
||||
# Imports go here!
|
||||
from .ciaoruozi import CiaoruoziCommand
|
||||
from .color import ColorCommand
|
||||
from .cv import CvCommand
|
||||
from .diario import DiarioCommand
|
||||
from .ping import PingCommand
|
||||
from .rage import RageCommand
|
||||
from .reminder import ReminderCommand
|
||||
from .ship import ShipCommand
|
||||
|
@ -17,14 +12,22 @@ from .dnditem import DnditemCommand
|
|||
from .dndspell import DndspellCommand
|
||||
from .trivia import TriviaCommand
|
||||
from .mm import MmCommand
|
||||
from .pause import PauseCommand
|
||||
from .play import PlayCommand
|
||||
from .playmode import PlaymodeCommand
|
||||
from .queue import QueueCommand
|
||||
from .skip import SkipCommand
|
||||
from .summon import SummonCommand
|
||||
from .youtube import YoutubeCommand
|
||||
from .soundcloud import SoundcloudCommand
|
||||
from .zawarudo import ZawarudoCommand
|
||||
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
commands = [
|
||||
CiaoruoziCommand,
|
||||
ColorCommand,
|
||||
CvCommand,
|
||||
DiarioCommand,
|
||||
PingCommand,
|
||||
RageCommand,
|
||||
ReminderCommand,
|
||||
ShipCommand,
|
||||
|
@ -34,7 +37,16 @@ commands = [
|
|||
DndspellCommand,
|
||||
TriviaCommand,
|
||||
MmCommand,
|
||||
PauseCommand,
|
||||
PlayCommand,
|
||||
PlaymodeCommand,
|
||||
QueueCommand,
|
||||
SkipCommand,
|
||||
SummonCommand,
|
||||
YoutubeCommand,
|
||||
SoundcloudCommand,
|
||||
ZawarudoCommand
|
||||
]
|
||||
|
||||
|
||||
__all__ = [command.__name__ for command in commands]
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [command.__class__.__qualname__ for command in commands]
|
|
@ -1,8 +1,6 @@
|
|||
import typing
|
||||
import telegram
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
|
||||
|
||||
class CiaoruoziCommand(Command):
|
||||
|
@ -12,7 +10,7 @@ class CiaoruoziCommand(Command):
|
|||
|
||||
syntax: str = ""
|
||||
|
||||
require_alchemy_tables: typing.Set = set()
|
||||
tables: typing.Set = set()
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
if self.interface.name == "telegram":
|
|
@ -1,7 +1,4 @@
|
|||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
|
||||
|
||||
class ColorCommand(Command):
|
|
@ -1,20 +1,16 @@
|
|||
import discord
|
||||
import typing
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ...utils import NetworkHandler, andformat
|
||||
from ...bots import DiscordBot
|
||||
from ..commanderrors import CommandError
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import NetworkHandler, andformat
|
||||
from royalnet.bots import DiscordBot
|
||||
from royalherald import Request, ResponseSuccess
|
||||
|
||||
|
||||
class CvNH(NetworkHandler):
|
||||
message_type = "discord_cv"
|
||||
|
||||
@classmethod
|
||||
async def discord(cls, bot: "DiscordBot", data: dict):
|
||||
async def discord(cls, bot: DiscordBot, data: dict):
|
||||
# Find the matching guild
|
||||
if data["guild_name"]:
|
||||
guilds: typing.List[discord.Guild] = bot.client.find_guild_by_name(data["guild_name"])
|
|
@ -3,12 +3,9 @@ import re
|
|||
import datetime
|
||||
import telegram
|
||||
import aiohttp
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...database.tables import User, Diario, Alias
|
||||
from ...utils import asyncify
|
||||
from ..commanderrors import CommandError, InvalidInputError
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import asyncify
|
||||
from ..tables import User, Diario, Alias
|
||||
|
||||
|
||||
async def to_imgur(imgur_api_key, photosizes: typing.List[telegram.PhotoSize], caption="") -> str:
|
||||
|
@ -38,7 +35,7 @@ class DiarioCommand(Command):
|
|||
|
||||
syntax = "[!] \"(testo)\" --[autore], [contesto]"
|
||||
|
||||
require_alchemy_tables = {User, Diario, Alias}
|
||||
tables = {User, Diario, Alias}
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
if self.interface.name == "telegram":
|
|
@ -1,11 +1,8 @@
|
|||
import typing
|
||||
import aiohttp
|
||||
import sortedcontainers
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ..commandinterface import CommandInterface
|
||||
from ...utils import parse_5etools_entry
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import parse_5etools_entry
|
||||
|
||||
|
||||
class DnditemCommand(Command):
|
|
@ -1,11 +1,8 @@
|
|||
import typing
|
||||
import aiohttp
|
||||
import sortedcontainers
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ..commandinterface import CommandInterface
|
||||
from ...utils import parse_5etools_entry, ordinalformat, andformat
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import parse_5etools_entry, ordinalformat, andformat
|
||||
|
||||
|
||||
class DndspellCommand(Command):
|
|
@ -5,12 +5,10 @@ import asyncio
|
|||
import re
|
||||
import logging
|
||||
import typing
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...database.tables import MMEvent, MMDecision, MMResponse
|
||||
from ..commanderrors import InvalidInputError, UnsupportedError
|
||||
from ...utils import asyncify, telegram_escape, sleep_until
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import asyncify, telegram_escape, sleep_until
|
||||
from ..tables import MMEvent, MMDecision, MMResponse
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -27,7 +25,7 @@ class MmCommand(Command):
|
|||
|
||||
syntax: str = "[ (data) ] (nomegioco)\n[descrizione]"
|
||||
|
||||
require_alchemy_tables = {MMEvent, MMDecision, MMResponse}
|
||||
tables = {MMEvent, MMDecision, MMResponse}
|
||||
|
||||
_cycle_duration = 10
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
import typing
|
||||
import urllib.parse
|
||||
import asyncio
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...utils import asyncify
|
||||
from ...audio import YtdlMp3
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import asyncify
|
||||
from royalnet.audio import YtdlMp3
|
||||
|
||||
|
||||
class Mp3Command(Command):
|
|
@ -1,14 +1,9 @@
|
|||
import typing
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...utils import NetworkHandler
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
||||
if typing.TYPE_CHECKING:
|
||||
from ...bots import DiscordBot
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import NetworkHandler
|
||||
from royalnet.bots import DiscordBot
|
||||
from royalherald import Request, ResponseSuccess
|
||||
|
||||
|
||||
class PauseNH(NetworkHandler):
|
||||
|
@ -16,7 +11,7 @@ class PauseNH(NetworkHandler):
|
|||
|
||||
# noinspection PyProtectedMember
|
||||
@classmethod
|
||||
async def discord(cls, bot: "DiscordBot", data: dict):
|
||||
async def discord(cls, bot: DiscordBot, data: dict):
|
||||
# Find the matching guild
|
||||
if data["guild_name"]:
|
||||
guilds: typing.List[discord.Guild] = bot.client.find_guild_by_name(data["guild_name"])
|
|
@ -2,16 +2,11 @@ import typing
|
|||
import pickle
|
||||
import datetime
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...utils import NetworkHandler, asyncify
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
||||
from ...audio import YtdlDiscord
|
||||
if typing.TYPE_CHECKING:
|
||||
from ...bots import DiscordBot
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import NetworkHandler, asyncify
|
||||
from royalnet.audio import YtdlDiscord
|
||||
from royalnet.bots import DiscordBot
|
||||
from royalherald import Request, ResponseSuccess
|
||||
|
||||
|
||||
class PlayNH(NetworkHandler):
|
|
@ -1,16 +1,11 @@
|
|||
import typing
|
||||
import pickle
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ...utils import NetworkHandler
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
||||
from ...audio.playmodes import Playlist, Pool, Layers
|
||||
if typing.TYPE_CHECKING:
|
||||
from ...bots import DiscordBot
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import NetworkHandler
|
||||
from royalnet.audio.playmodes import Playlist, Pool, Layers
|
||||
from royalnet.bots import DiscordBot
|
||||
from royalherald import Request, ResponseSuccess
|
||||
|
||||
|
||||
class PlaymodeNH(NetworkHandler):
|
|
@ -1,10 +1,7 @@
|
|||
import typing
|
||||
import pickle
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler, numberemojiformat
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
|
@ -1,8 +1,6 @@
|
|||
import typing
|
||||
import random
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
|
||||
|
||||
class RageCommand(Command):
|
|
@ -5,10 +5,7 @@ import pickle
|
|||
import telegram
|
||||
import discord
|
||||
from sqlalchemy import and_
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import sleep_until, asyncify, telegram_escape, discord_escape
|
||||
from ...database.tables import Reminder
|
||||
from ..commanderrors import InvalidInputError, UnsupportedError
|
||||
|
@ -22,7 +19,7 @@ class ReminderCommand(Command):
|
|||
|
||||
syntax: str = "[ (data) ] (messaggio)"
|
||||
|
||||
require_alchemy_tables = {Reminder}
|
||||
tables = {Reminder}
|
||||
|
||||
def __init__(self, interface: CommandInterface):
|
||||
super().__init__(interface)
|
|
@ -1,8 +1,6 @@
|
|||
import typing
|
||||
import re
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import safeformat
|
||||
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
import typing
|
||||
import pickle
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler, asyncify
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
|
@ -1,8 +1,6 @@
|
|||
import typing
|
||||
import random
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import safeformat
|
||||
|
||||
|
|
@ -2,13 +2,9 @@ import typing
|
|||
import pickle
|
||||
import datetime
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler, asyncify
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
||||
from ...audio import YtdlDiscord
|
||||
|
||||
if typing.TYPE_CHECKING:
|
|
@ -1,9 +1,6 @@
|
|||
import typing
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
|
@ -4,10 +4,7 @@ import aiohttp
|
|||
import random
|
||||
import uuid
|
||||
import html
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ..commandinterface import CommandInterface
|
||||
from royalnet.commands import *
|
||||
from ...utils import asyncify
|
||||
from ..commanderrors import CommandError, KeyboardExpiredError
|
||||
from ...database.tables import TriviaScore
|
||||
|
@ -20,7 +17,7 @@ class TriviaCommand(Command):
|
|||
|
||||
description: str = "Manda una domanda dell'OpenTDB in chat."
|
||||
|
||||
require_alchemy_tables = {TriviaScore}
|
||||
tables = {TriviaScore}
|
||||
|
||||
_letter_emojis = ["🇦", "🇧", "🇨", "🇩"]
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
import typing
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from ..commanderrors import CommandError, UnsupportedError
|
||||
from royalnet.commands import *
|
||||
|
||||
|
||||
class VideochannelCommand(Command):
|
|
@ -2,13 +2,9 @@ import typing
|
|||
import pickle
|
||||
import datetime
|
||||
import discord
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler, asyncify
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError
|
||||
from ...audio import YtdlDiscord
|
||||
if typing.TYPE_CHECKING:
|
||||
from ...bots import DiscordBot
|
|
@ -2,13 +2,9 @@ import typing
|
|||
import discord
|
||||
import asyncio
|
||||
import datetime
|
||||
from ..command import Command
|
||||
from ..commandinterface import CommandInterface
|
||||
from ..commandargs import CommandArgs
|
||||
from ..commanddata import CommandData
|
||||
from royalnet.commands import *
|
||||
from ...utils import NetworkHandler, asyncify
|
||||
from ...network import Request, ResponseSuccess
|
||||
from ..commanderrors import CommandError, InvalidInputError, UnsupportedError, KeyboardExpiredError
|
||||
from ...audio import YtdlDiscord
|
||||
from ...audio.playmodes import Playlist
|
||||
if typing.TYPE_CHECKING:
|
41
royalnet/packs/royal/tables/__init__.py
Normal file
41
royalnet/packs/royal/tables/__init__.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Imports go here!
|
||||
from royalnet.packs.common.tables import User
|
||||
from royalnet.packs.common.tables import Telegram
|
||||
from royalnet.packs.common.tables import Discord
|
||||
|
||||
from .diario import Diario
|
||||
from .aliases import Alias
|
||||
from .activekvgroups import ActiveKvGroup
|
||||
from .keyvalues import Keyvalue
|
||||
from .keygroups import Keygroup
|
||||
from .wikipages import WikiPage
|
||||
from .wikirevisions import WikiRevision
|
||||
from .bios import Bio
|
||||
from .reminders import Reminder
|
||||
from .triviascores import TriviaScore
|
||||
from .mmdecisions import MMDecision
|
||||
from .mmevents import MMEvent
|
||||
from .mmresponse import MMResponse
|
||||
|
||||
# Enter the tables of your Pack here!
|
||||
tables = [
|
||||
User,
|
||||
Telegram,
|
||||
Discord,
|
||||
Diario,
|
||||
Alias,
|
||||
ActiveKvGroup,
|
||||
Keyvalue,
|
||||
Keygroup,
|
||||
WikiPage,
|
||||
WikiRevision,
|
||||
Bio,
|
||||
Reminder,
|
||||
TriviaScore,
|
||||
MMDecision,
|
||||
MMEvent,
|
||||
MMResponse,
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
__all__ = [table.__class__.__qualname__ for table in tables]
|
|
@ -4,10 +4,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .users import User
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .keygroups import Keygroup
|
||||
|
||||
|
||||
class ActiveKvGroup:
|
|
@ -4,8 +4,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .users import User
|
||||
|
||||
|
||||
class Alias:
|
|
@ -4,7 +4,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from .users import User
|
||||
|
||||
|
||||
class Bio:
|
|
@ -8,8 +8,6 @@ from sqlalchemy import Column, \
|
|||
String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .users import User
|
||||
|
||||
|
||||
class Diario:
|
|
@ -3,8 +3,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .keygroups import Keygroup
|
||||
|
||||
|
||||
class Keyvalue:
|
|
@ -4,8 +4,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from .users import User
|
||||
from .mmevents import MMEvent
|
||||
|
||||
|
||||
class MMDecision:
|
|
@ -1,5 +1,3 @@
|
|||
import telegram
|
||||
import typing
|
||||
from sqlalchemy import Column, \
|
||||
Integer, \
|
||||
DateTime, \
|
||||
|
@ -9,10 +7,6 @@ from sqlalchemy import Column, \
|
|||
BigInteger
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from .users import User
|
||||
if typing.TYPE_CHECKING:
|
||||
from .mmdecisions import MMDecision
|
||||
from .mmresponse import MMResponse
|
||||
|
||||
|
||||
class MMEvent:
|
|
@ -4,8 +4,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from .users import User
|
||||
from .mmevents import MMEvent
|
||||
|
||||
|
||||
class MMResponse:
|
|
@ -6,8 +6,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .users import User
|
||||
|
||||
|
||||
class Reminder:
|
|
@ -3,7 +3,6 @@ from sqlalchemy import Column, \
|
|||
ForeignKey
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from .users import User
|
||||
|
||||
|
||||
class TriviaScore:
|
|
@ -6,10 +6,6 @@ from sqlalchemy import Column, \
|
|||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .wikipages import WikiPage
|
||||
# noinspection PyUnresolvedReferences
|
||||
from .users import User
|
||||
|
||||
|
||||
class WikiRevision:
|
|
@ -41,14 +41,14 @@
|
|||
{% if session["royal"]["avatar"] %}
|
||||
<img class="nav-image" alt="" src="{{ session["royal"]["avatar"] }}">
|
||||
{% else %}
|
||||
<img class="nav-image" alt="" src="{{ url_for("static", filename="generic.png") }}">
|
||||
<img class="nav-image" alt="" src="{{ url_for("static", filename="common.png") }}">
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="nav-login">
|
||||
<a class="no-icon" href="{{ url_for("tglogin.tglogin_index") }}">
|
||||
Login
|
||||
<img class="nav-image disabled" alt="" src="{{ url_for("static", filename="generic.png") }}">
|
||||
<img class="nav-image disabled" alt="" src="{{ url_for("static", filename="common.png") }}">
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
|
Loading…
Reference in a new issue