mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Do some more stuff
This commit is contained in:
parent
472da17a7d
commit
7100193bd1
14 changed files with 110 additions and 25 deletions
17
royalgames.py
Normal file
17
royalgames.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import os
|
||||||
|
import asyncio
|
||||||
|
from royalnet.bots import TelegramBot
|
||||||
|
from royalnet.commands import PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand
|
||||||
|
from royalnet.commands.debug_create import DebugCreateCommand
|
||||||
|
from royalnet.network import RoyalnetServer
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand]
|
||||||
|
|
||||||
|
master = RoyalnetServer("localhost", 1234, "sas")
|
||||||
|
tg_bot = TelegramBot(os.environ["TG_AK"], "localhost:1234", "sas", commands, "sqlite://")
|
||||||
|
loop.create_task(master.run())
|
||||||
|
loop.create_task(tg_bot.run())
|
||||||
|
print("Starting loop...")
|
||||||
|
loop.run_forever()
|
|
@ -34,10 +34,10 @@ class TelegramBot:
|
||||||
self.network: RoyalnetLink = RoyalnetLink(master_server_uri, master_server_secret, "telegram", todo)
|
self.network: RoyalnetLink = RoyalnetLink(master_server_uri, master_server_secret, "telegram", todo)
|
||||||
# Generate commands
|
# Generate commands
|
||||||
self.commands = {}
|
self.commands = {}
|
||||||
required_tables = []
|
required_tables = set()
|
||||||
for command in commands:
|
for command in commands:
|
||||||
self.commands[f"/{command.command_name}"] = command
|
self.commands[f"/{command.command_name}"] = command
|
||||||
required_tables += command.require_alchemy_tables
|
required_tables = required_tables.union(command.require_alchemy_tables)
|
||||||
# Generate the Alchemy database
|
# Generate the Alchemy database
|
||||||
self.alchemy = Alchemy(database_uri, required_tables)
|
self.alchemy = Alchemy(database_uri, required_tables)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class TelegramBot:
|
||||||
class TelegramCall(Call):
|
class TelegramCall(Call):
|
||||||
interface_name = "telegram"
|
interface_name = "telegram"
|
||||||
interface_obj = self
|
interface_obj = self
|
||||||
Session = self.alchemy.Session
|
interface_alchemy = self.alchemy
|
||||||
|
|
||||||
async def reply(call, text: str):
|
async def reply(call, text: str):
|
||||||
await asyncify(call.channel.send_message, text, parse_mode="HTML")
|
await asyncify(call.channel.send_message, text, parse_mode="HTML")
|
||||||
|
|
|
@ -2,5 +2,8 @@ from .null import NullCommand
|
||||||
from .ping import PingCommand
|
from .ping import PingCommand
|
||||||
from .ship import ShipCommand
|
from .ship import ShipCommand
|
||||||
from .smecds import SmecdsCommand
|
from .smecds import SmecdsCommand
|
||||||
|
from .ciaoruozi import CiaoruoziCommand
|
||||||
|
from .color import ColorCommand
|
||||||
|
|
||||||
__all__ = ["NullCommand", "PingCommand", "ShipCommand", "SmecdsCommand"]
|
|
||||||
|
__all__ = ["NullCommand", "PingCommand", "ShipCommand", "SmecdsCommand", "CiaoruoziCommand", "ColorCommand"]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from ..utils import Command, CommandArgs, Call
|
from ..utils import Command, CommandArgs, Call
|
||||||
|
|
||||||
|
|
||||||
class PingCommand(Command):
|
class ColorCommand(Command):
|
||||||
|
|
||||||
command_name = "color"
|
command_name = "color"
|
||||||
command_title = "Invia un colore in chat...?"
|
command_title = "Invia un colore in chat...?"
|
||||||
|
|
16
royalnet/commands/debug_create.py
Normal file
16
royalnet/commands/debug_create.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from ..utils import Command, CommandArgs, Call
|
||||||
|
from ..database.tables import Royal
|
||||||
|
|
||||||
|
|
||||||
|
class DebugCreateCommand(Command):
|
||||||
|
|
||||||
|
command_name = "debug_create"
|
||||||
|
command_title = "Create a new Royalnet user account"
|
||||||
|
|
||||||
|
require_alchemy_tables = {Royal}
|
||||||
|
|
||||||
|
async def common(self, call: Call, args: CommandArgs):
|
||||||
|
royal = call.interface_alchemy.Royal(username=args[0], role="Member")
|
||||||
|
call.session.add(royal)
|
||||||
|
call.session.commit()
|
||||||
|
await call.reply(f"✅ Utente {royal} creato!")
|
|
@ -1,4 +1,4 @@
|
||||||
from .alchemy import Alchemy
|
from .alchemy import Alchemy
|
||||||
from .tables import Role, Royal
|
from .tables import Royal
|
||||||
|
|
||||||
__all__ = ["Alchemy", "Role", "Royal"]
|
__all__ = ["Alchemy", "Royal"]
|
||||||
|
|
|
@ -4,13 +4,13 @@ from sqlalchemy import create_engine
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
from contextlib import contextmanager, asynccontextmanager
|
from contextlib import contextmanager, asynccontextmanager
|
||||||
from ..utils import classdictjanitor
|
from ..utils import cdj
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
class Alchemy:
|
class Alchemy:
|
||||||
def __init__(self, database_uri: str = "sqlite://", tables: typing.Optional[typing.List] = None):
|
def __init__(self, database_uri: str = "sqlite://", tables: typing.Optional[typing.Set] = None):
|
||||||
self.engine = create_engine(database_uri)
|
self.engine = create_engine(database_uri)
|
||||||
self.Base = declarative_base(bind=self.engine)
|
self.Base = declarative_base(bind=self.engine)
|
||||||
self.Session = sessionmaker(bind=self.engine)
|
self.Session = sessionmaker(bind=self.engine)
|
||||||
|
@ -23,7 +23,7 @@ class Alchemy:
|
||||||
self.__getattribute__(name)
|
self.__getattribute__(name)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Actually the intended result
|
# Actually the intended result
|
||||||
self.__setattr__(name, type(name, (self.Base,), classdictjanitor(table)))
|
self.__setattr__(name, type(name, (self.Base,), cdj(table)))
|
||||||
else:
|
else:
|
||||||
raise NameError(f"{name} is a reserved name and can't be used as a table name")
|
raise NameError(f"{name} is a reserved name and can't be used as a table name")
|
||||||
self.Base.metadata.create_all()
|
self.Base.metadata.create_all()
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
from .royals import Role, Royal
|
from .royals import Royal
|
||||||
|
|
||||||
__all__ = ["Role", "Royal"]
|
__all__ = ["Royal"]
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
from enum import Enum
|
|
||||||
from sqlalchemy import Column, \
|
from sqlalchemy import Column, \
|
||||||
Integer, \
|
Integer, \
|
||||||
String, \
|
String, \
|
||||||
LargeBinary
|
LargeBinary
|
||||||
|
|
||||||
|
|
||||||
class Role(Enum):
|
|
||||||
Guest = "Guest"
|
|
||||||
Member = "Member"
|
|
||||||
Admin = "Admin"
|
|
||||||
|
|
||||||
|
|
||||||
class Royal:
|
class Royal:
|
||||||
__tablename__ = "royals"
|
__tablename__ = "royals"
|
||||||
|
|
||||||
|
@ -18,3 +11,10 @@ class Royal:
|
||||||
username = Column(String, unique=True, nullable=False)
|
username = Column(String, unique=True, nullable=False)
|
||||||
password = Column(LargeBinary)
|
password = Column(LargeBinary)
|
||||||
role = Column(String, nullable=False)
|
role = Column(String, nullable=False)
|
||||||
|
avatar = Column(LargeBinary)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Royal {self.username}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.username
|
||||||
|
|
28
royalnet/database/tables/telegram.py
Normal file
28
royalnet/database/tables/telegram.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from sqlalchemy import Column, \
|
||||||
|
Integer, \
|
||||||
|
String, \
|
||||||
|
BigInteger, \
|
||||||
|
LargeBinary
|
||||||
|
|
||||||
|
|
||||||
|
class Telegram:
|
||||||
|
__tablename__ = "telegram"
|
||||||
|
|
||||||
|
royal_id = Column(Integer)
|
||||||
|
tg_id = Column(BigInteger, primary_key=True)
|
||||||
|
tg_first_name = Column(String)
|
||||||
|
tg_last_name = Column(String)
|
||||||
|
tg_username = Column(String)
|
||||||
|
tg_avatar = Column(LargeBinary)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Telegram {str(self)}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.tg_username is not None:
|
||||||
|
return f"@{self.tg_username}"
|
||||||
|
elif self.tg_last_name is not None:
|
||||||
|
return f"{self.tg_first_name} {self.tg_last_name}"
|
||||||
|
else:
|
||||||
|
return self.tg_first_name
|
||||||
|
|
|
@ -2,7 +2,7 @@ from .asyncify import asyncify
|
||||||
from .call import Call
|
from .call import Call
|
||||||
from .command import Command, CommandArgs, InvalidInputError, UnsupportedError
|
from .command import Command, CommandArgs, InvalidInputError, UnsupportedError
|
||||||
from .safeformat import safeformat
|
from .safeformat import safeformat
|
||||||
from .classdictjanitor import classdictjanitor
|
from .classdictjanitor import cdj
|
||||||
|
|
||||||
__all__ = ["asyncify", "Call", "Command", "safeformat", "InvalidInputError", "UnsupportedError", "CommandArgs",
|
__all__ = ["asyncify", "Call", "Command", "safeformat", "InvalidInputError", "UnsupportedError", "CommandArgs",
|
||||||
"classdictjanitor"]
|
"cdj"]
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import typing
|
import typing
|
||||||
|
import asyncio
|
||||||
from ..network.messages import Message
|
from ..network.messages import Message
|
||||||
from .command import Command, CommandArgs
|
from .command import Command, CommandArgs
|
||||||
|
from ..database import Alchemy
|
||||||
|
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
class Call:
|
class Call:
|
||||||
|
@ -9,7 +14,7 @@ class Call:
|
||||||
# These parameters / methods should be overridden
|
# These parameters / methods should be overridden
|
||||||
interface_name = NotImplemented
|
interface_name = NotImplemented
|
||||||
interface_obj = NotImplemented
|
interface_obj = NotImplemented
|
||||||
Session = NotImplemented
|
interface_alchemy: Alchemy = NotImplemented
|
||||||
|
|
||||||
async def reply(self, text: str):
|
async def reply(self, text: str):
|
||||||
"""Send a text message to the channel the call was made."""
|
"""Send a text message to the channel the call was made."""
|
||||||
|
@ -26,10 +31,26 @@ class Call:
|
||||||
self.command = command
|
self.command = command
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
self.session = None
|
||||||
|
|
||||||
|
async def session_init(self):
|
||||||
|
if not self.command.require_alchemy_tables:
|
||||||
|
return
|
||||||
|
self.session = await loop.run_in_executor(self.interface_alchemy.Session)
|
||||||
|
|
||||||
|
async def session_end(self):
|
||||||
|
if not self.session:
|
||||||
|
return
|
||||||
|
self.session.close()
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
await self.session_init()
|
||||||
try:
|
try:
|
||||||
coroutine = getattr(self.command, self.interface_name)
|
coroutine = getattr(self.command, self.interface_name)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
coroutine = getattr(self.command, "common")
|
coroutine = getattr(self.command, "common")
|
||||||
return await coroutine(self.command, self, CommandArgs(*self.args, **self.kwargs))
|
try:
|
||||||
|
result = await coroutine(self.command, self, CommandArgs(*self.args, **self.kwargs))
|
||||||
|
finally:
|
||||||
|
self.session.close()
|
||||||
|
return result
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
def classdictjanitor(class_) -> dict:
|
def cdj(class_) -> dict:
|
||||||
"""Return the cleaned class attributes in a dict."""
|
"""Return the cleaned class attributes in a dict."""
|
||||||
d = dict(class_.__dict__)
|
d = dict(class_.__dict__)
|
||||||
del d["__module__"]
|
del d["__module__"]
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Command:
|
||||||
command_name: str = NotImplemented
|
command_name: str = NotImplemented
|
||||||
command_title: str = NotImplemented
|
command_title: str = NotImplemented
|
||||||
|
|
||||||
require_alchemy_tables: typing.List = []
|
require_alchemy_tables: typing.Set = set()
|
||||||
|
|
||||||
async def common(self, call: "Call", args: CommandArgs):
|
async def common(self, call: "Call", args: CommandArgs):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
Loading…
Reference in a new issue