1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-27 13:34:28 +00:00

Integrate Alchemy in calls, commands and Telegram bot

This commit is contained in:
Steffo 2019-03-31 19:39:25 +02:00
parent d7bf281f61
commit 6e89c53835
5 changed files with 35 additions and 8 deletions

View file

@ -5,12 +5,14 @@ import logging as _logging
from ..commands import NullCommand from ..commands import NullCommand
from ..utils import asyncify, Call, Command from ..utils import asyncify, Call, Command
from ..network import RoyalnetLink, Message from ..network import RoyalnetLink, Message
from ..database import Alchemy
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
log = _logging.getLogger(__name__) log = _logging.getLogger(__name__)
# noinspection PyUnusedLocal
async def todo(message: Message): async def todo(message: Message):
pass pass
@ -21,6 +23,7 @@ class TelegramBot:
master_server_uri: str, master_server_uri: str,
master_server_secret: str, master_server_secret: str,
commands: typing.List[typing.Type[Command]], commands: typing.List[typing.Type[Command]],
database_uri: str,
missing_command: Command = NullCommand): missing_command: Command = NullCommand):
self.bot: telegram.Bot = telegram.Bot(api_key) self.bot: telegram.Bot = telegram.Bot(api_key)
self.should_run: bool = False self.should_run: bool = False
@ -29,17 +32,23 @@ 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 = []
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
# Generate the Alchemy database
self.alchemy = Alchemy(database_uri, required_tables)
# noinspection PyMethodParameters
class TelegramCall(Call): class TelegramCall(Call):
interface_name = "telegram" interface_name = "telegram"
interface_obj = self interface_obj = self
Session = self.alchemy.Session
async def reply(self, text: str): async def reply(call, text: str):
await asyncify(self.channel.send_message, text, parse_mode="HTML") await asyncify(call.channel.send_message, text, parse_mode="HTML")
async def net_request(self, message: Message, destination: str): async def net_request(call, message: Message, destination: str):
response = await self.network.request(message, destination) response = await self.network.request(message, destination)
return response return response

View file

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

View file

@ -3,7 +3,7 @@ import asyncio
from sqlalchemy import create_engine 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 asynccontextmanager from contextlib import contextmanager, asynccontextmanager
from ..utils import classdictjanitor from ..utils import classdictjanitor
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
@ -13,7 +13,7 @@ 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.List] = 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)
self._create_tables(tables) self._create_tables(tables)
def _create_tables(self, tables: typing.Optional[typing.List]): def _create_tables(self, tables: typing.Optional[typing.List]):
@ -28,9 +28,20 @@ class Alchemy:
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()
@asynccontextmanager @contextmanager
async def Session(self): async def session_cm(self):
session = await loop.run_in_executor(None, self._Session) session = self.Session()
try:
yield session
except Exception:
session.rollback()
raise
finally:
session.close()
@asynccontextmanager
async def session_acm(self):
session = await loop.run_in_executor(None, self.Session)
try: try:
yield session yield session
except Exception: except Exception:

View file

@ -9,6 +9,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
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."""

View file

@ -39,5 +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 = []
async def common(self, call: "Call", args: CommandArgs): async def common(self, call: "Call", args: CommandArgs):
raise NotImplementedError() raise NotImplementedError()