1
Fork 0
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:
Steffo 2019-04-01 12:33:20 +02:00
parent 472da17a7d
commit 7100193bd1
14 changed files with 110 additions and 25 deletions

17
royalgames.py Normal file
View 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()

View file

@ -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")

View file

@ -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"]

View file

@ -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...?"

View 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!")

View file

@ -1,4 +1,4 @@
from .alchemy import Alchemy
from .tables import Role, Royal
from .tables import Royal
__all__ = ["Alchemy", "Role", "Royal"]
__all__ = ["Alchemy", "Royal"]

View file

@ -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()

View file

@ -1,3 +1,3 @@
from .royals import Role, Royal
from .royals import Royal
__all__ = ["Role", "Royal"]
__all__ = ["Royal"]

View file

@ -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

View 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

View file

@ -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"]

View file

@ -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

View file

@ -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__"]

View file

@ -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()