mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +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)
|
||||
# Generate commands
|
||||
self.commands = {}
|
||||
required_tables = []
|
||||
required_tables = set()
|
||||
for command in commands:
|
||||
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
|
||||
self.alchemy = Alchemy(database_uri, required_tables)
|
||||
|
||||
|
@ -45,7 +45,7 @@ class TelegramBot:
|
|||
class TelegramCall(Call):
|
||||
interface_name = "telegram"
|
||||
interface_obj = self
|
||||
Session = self.alchemy.Session
|
||||
interface_alchemy = self.alchemy
|
||||
|
||||
async def reply(call, text: str):
|
||||
await asyncify(call.channel.send_message, text, parse_mode="HTML")
|
||||
|
|
|
@ -2,5 +2,8 @@ from .null import NullCommand
|
|||
from .ping import PingCommand
|
||||
from .ship import ShipCommand
|
||||
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
|
||||
|
||||
|
||||
class PingCommand(Command):
|
||||
class ColorCommand(Command):
|
||||
|
||||
command_name = "color"
|
||||
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 .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.orm import sessionmaker
|
||||
from contextlib import contextmanager, asynccontextmanager
|
||||
from ..utils import classdictjanitor
|
||||
from ..utils import cdj
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
|
||||
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.Base = declarative_base(bind=self.engine)
|
||||
self.Session = sessionmaker(bind=self.engine)
|
||||
|
@ -23,7 +23,7 @@ class Alchemy:
|
|||
self.__getattribute__(name)
|
||||
except AttributeError:
|
||||
# Actually the intended result
|
||||
self.__setattr__(name, type(name, (self.Base,), classdictjanitor(table)))
|
||||
self.__setattr__(name, type(name, (self.Base,), cdj(table)))
|
||||
else:
|
||||
raise NameError(f"{name} is a reserved name and can't be used as a table name")
|
||||
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, \
|
||||
Integer, \
|
||||
String, \
|
||||
LargeBinary
|
||||
|
||||
|
||||
class Role(Enum):
|
||||
Guest = "Guest"
|
||||
Member = "Member"
|
||||
Admin = "Admin"
|
||||
|
||||
|
||||
class Royal:
|
||||
__tablename__ = "royals"
|
||||
|
||||
|
@ -18,3 +11,10 @@ class Royal:
|
|||
username = Column(String, unique=True, nullable=False)
|
||||
password = Column(LargeBinary)
|
||||
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 .command import Command, CommandArgs, InvalidInputError, UnsupportedError
|
||||
from .safeformat import safeformat
|
||||
from .classdictjanitor import classdictjanitor
|
||||
from .classdictjanitor import cdj
|
||||
|
||||
__all__ = ["asyncify", "Call", "Command", "safeformat", "InvalidInputError", "UnsupportedError", "CommandArgs",
|
||||
"classdictjanitor"]
|
||||
"cdj"]
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import typing
|
||||
import asyncio
|
||||
from ..network.messages import Message
|
||||
from .command import Command, CommandArgs
|
||||
from ..database import Alchemy
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
|
||||
class Call:
|
||||
|
@ -9,7 +14,7 @@ class Call:
|
|||
# These parameters / methods should be overridden
|
||||
interface_name = NotImplemented
|
||||
interface_obj = NotImplemented
|
||||
Session = NotImplemented
|
||||
interface_alchemy: Alchemy = NotImplemented
|
||||
|
||||
async def reply(self, text: str):
|
||||
"""Send a text message to the channel the call was made."""
|
||||
|
@ -26,10 +31,26 @@ class Call:
|
|||
self.command = command
|
||||
self.args = args
|
||||
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):
|
||||
await self.session_init()
|
||||
try:
|
||||
coroutine = getattr(self.command, self.interface_name)
|
||||
except AttributeError:
|
||||
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."""
|
||||
d = dict(class_.__dict__)
|
||||
del d["__module__"]
|
||||
|
|
|
@ -39,7 +39,7 @@ class Command:
|
|||
command_name: 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):
|
||||
raise NotImplementedError()
|
||||
|
|
Loading…
Reference in a new issue