mirror of
https://github.com/RYGhub/royalnet.git
synced 2025-03-28 02:40:31 +00:00
SO STUFF MUCH DOGE
This commit is contained in:
parent
6ec151835d
commit
202e33bdf0
12 changed files with 118 additions and 16 deletions
royalgames.py
royalnet
|
@ -3,14 +3,17 @@ import asyncio
|
|||
from royalnet.bots import TelegramBot
|
||||
from royalnet.commands import PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, SyncCommand
|
||||
from royalnet.commands.debug_create import DebugCreateCommand
|
||||
from royalnet.commands.debug_author import DebugAuthorCommand
|
||||
from royalnet.network import RoyalnetServer
|
||||
from royalnet.database.tables import Royal, Telegram
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand, SyncCommand]
|
||||
commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand, SyncCommand,
|
||||
DebugAuthorCommand]
|
||||
|
||||
master = RoyalnetServer("localhost", 1234, "sas")
|
||||
tg_bot = TelegramBot(os.environ["TG_AK"], "localhost:1234", "sas", commands, os.environ["DB_PATH"])
|
||||
tg_bot = TelegramBot(os.environ["TG_AK"], "localhost:1234", "sas", commands, os.environ["DB_PATH"], Royal, Telegram, "tg_id")
|
||||
loop.create_task(master.run())
|
||||
loop.create_task(tg_bot.run())
|
||||
print("Starting loop...")
|
||||
|
|
|
@ -5,8 +5,7 @@ import logging as _logging
|
|||
from ..commands import NullCommand
|
||||
from ..utils import asyncify, Call, Command
|
||||
from ..network import RoyalnetLink, Message
|
||||
from ..database import Alchemy
|
||||
|
||||
from ..database import Alchemy, relationshiplinkchain
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
log = _logging.getLogger(__name__)
|
||||
|
@ -24,6 +23,9 @@ class TelegramBot:
|
|||
master_server_secret: str,
|
||||
commands: typing.List[typing.Type[Command]],
|
||||
database_uri: str,
|
||||
master_table,
|
||||
identity_table,
|
||||
identity_column_name: str,
|
||||
missing_command: Command = NullCommand,
|
||||
error_command: Command = NullCommand):
|
||||
self.bot: telegram.Bot = telegram.Bot(api_key)
|
||||
|
@ -40,6 +42,10 @@ class TelegramBot:
|
|||
required_tables = required_tables.union(command.require_alchemy_tables)
|
||||
# Generate the Alchemy database
|
||||
self.alchemy = Alchemy(database_uri, required_tables)
|
||||
self.master_table = self.alchemy.__getattribute__(master_table.__name__)
|
||||
self.identity_table = self.alchemy.__getattribute__(identity_table.__name__)
|
||||
self.identity_column = self.identity_table.__getattribute__(self.identity_table, identity_column_name)
|
||||
self.identity_chain = relationshiplinkchain(self.master_table, self.identity_table)
|
||||
|
||||
# noinspection PyMethodParameters
|
||||
class TelegramCall(Call):
|
||||
|
@ -54,6 +60,17 @@ class TelegramBot:
|
|||
response = await self.network.request(message, destination)
|
||||
return response
|
||||
|
||||
async def get_author(call):
|
||||
update: telegram.Update = call.kwargs["update"]
|
||||
user: telegram.User = update.effective_user
|
||||
if user is None:
|
||||
return None
|
||||
query = call.session.query(self.master_table)
|
||||
for link in self.identity_chain:
|
||||
query = query.join(link.mapper.class_)
|
||||
query = query.filter(self.identity_column == user.id)
|
||||
return await asyncify(query.one_or_none)
|
||||
|
||||
self.Call = TelegramCall
|
||||
|
||||
async def run(self):
|
||||
|
|
16
royalnet/commands/debug_author.py
Normal file
16
royalnet/commands/debug_author.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from ..utils import Command, CommandArgs, Call
|
||||
from ..database.tables import Royal, Telegram
|
||||
|
||||
|
||||
class DebugAuthorCommand(Command):
|
||||
|
||||
command_name = "debug_author"
|
||||
command_title = "Ottieni informazioni sull'autore di questa chiamata."
|
||||
|
||||
require_alchemy_tables = {Royal, Telegram}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
author = await call.get_author()
|
||||
if author is None:
|
||||
await call.reply(f"☁️ L'autore di questa chiamata è sconosciuto.")
|
||||
await call.reply(f"🌞 <code>{str(author)}</code> è l'autore di questa chiamata.")
|
|
@ -1,5 +1,7 @@
|
|||
from ..utils import Command, CommandArgs, Call
|
||||
import re
|
||||
import datetime
|
||||
from ..utils import Command, CommandArgs, Call, InvalidInputError
|
||||
from ..database.tables import Royal, Diario, Alias
|
||||
|
||||
|
||||
class DiarioCommand(Command):
|
||||
|
@ -7,9 +9,21 @@ class DiarioCommand(Command):
|
|||
command_name = "diario"
|
||||
command_title = "Aggiungi una citazione al Diario."
|
||||
|
||||
require_alchemy_tables = {Royal, Diario, Alias}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
# Recreate the full sentence
|
||||
text = " ".join(args)
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(r'["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *(\w+))?(?:,? *([^ ].*))?', text)
|
||||
# TODO
|
||||
# Find the corresponding matches
|
||||
if match is None:
|
||||
raise InvalidInputError("No match found.")
|
||||
text = match.group(1)
|
||||
quoted = match.group(2)
|
||||
context = match.group(3)
|
||||
timestamp = datetime.datetime.now()
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
quoted_alias = call.session.query(call.alchemy.Alias).filter_by(alias=quoted).one_or_none()
|
||||
quoted_account = quoted_alias.royal if quoted_alias is not None else None
|
||||
# Find the creator of the quote
|
|
@ -1,6 +1,6 @@
|
|||
import typing
|
||||
from telegram import Update, User
|
||||
from ..utils import Command, CommandArgs, Call, asyncify
|
||||
from ..utils import Command, CommandArgs, Call, asyncify, UnsupportedError
|
||||
from ..database.tables import Royal, Telegram
|
||||
|
||||
|
||||
|
@ -9,10 +9,10 @@ class SyncCommand(Command):
|
|||
command_name = "sync"
|
||||
command_title = "Connect your current account to Royalnet"
|
||||
|
||||
require_alchemy_tables = [Royal, Telegram]
|
||||
require_alchemy_tables = {Royal, Telegram}
|
||||
|
||||
async def common(self, call: Call, args: CommandArgs):
|
||||
raise NotImplementedError()
|
||||
raise UnsupportedError()
|
||||
|
||||
async def telegram(self, call: Call, args: CommandArgs):
|
||||
update: Update = args.kwargs["update"]
|
||||
|
@ -24,6 +24,7 @@ class SyncCommand(Command):
|
|||
royal = await asyncify(call.session.query(call.alchemy.Royal).filter_by(username=args[0]).one_or_none)
|
||||
if royal is None:
|
||||
await call.reply("⚠️ Non esiste alcun account Royalnet con quel nome.")
|
||||
return
|
||||
# Find if the user is already synced
|
||||
telegram = await asyncify(call.session.query(call.alchemy.Telegram).filter_by(tg_id=user.id).one_or_none)
|
||||
if telegram is None:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from .alchemy import Alchemy
|
||||
from .relationshiplinkchain import relationshiplinkchain
|
||||
|
||||
__all__ = ["Alchemy"]
|
||||
__all__ = ["Alchemy", "relationshiplinkchain"]
|
||||
|
|
22
royalnet/database/relationshiplinkchain.py
Normal file
22
royalnet/database/relationshiplinkchain.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
import typing
|
||||
from sqlalchemy.inspection import inspect
|
||||
|
||||
|
||||
def relationshiplinkchain(starting_class, ending_class) -> typing.Optional[tuple]:
|
||||
"""Find the path to follow to get from the starting table to the ending table."""
|
||||
inspected = set()
|
||||
|
||||
def search(_mapper, chain):
|
||||
inspected.add(_mapper)
|
||||
if _mapper.class_ == ending_class:
|
||||
return chain
|
||||
relationships = _mapper.relationships
|
||||
for _relationship in set(relationships):
|
||||
if _relationship.mapper in inspected:
|
||||
continue
|
||||
result = search(_relationship.mapper, chain + (_relationship,))
|
||||
if len(result) == 0:
|
||||
return result
|
||||
return ()
|
||||
|
||||
return search(inspect(starting_class), tuple())
|
|
@ -1,5 +1,6 @@
|
|||
from .royals import Royal
|
||||
from .telegram import Telegram
|
||||
from .diario import Diario
|
||||
from .aliases import Alias
|
||||
|
||||
__all__ = ["Royal", "Telegram", "Diario"]
|
||||
__all__ = ["Royal", "Telegram", "Diario", "Alias"]
|
||||
|
|
23
royalnet/database/tables/aliases.py
Normal file
23
royalnet/database/tables/aliases.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from sqlalchemy import Column, \
|
||||
Integer, \
|
||||
String, \
|
||||
BigInteger, \
|
||||
LargeBinary, \
|
||||
ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from .royals import Royal
|
||||
|
||||
|
||||
class Alias:
|
||||
__tablename__ = "aliases"
|
||||
|
||||
royal_id = Column(Integer, ForeignKey("royals.uid"))
|
||||
alias = Column(String, primary_key=True)
|
||||
|
||||
royal = relationship("Royal", backref="aliases")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Alias {str(self)}>"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.alias}->{self.royal_id}"
|
|
@ -14,9 +14,9 @@ class Diario:
|
|||
|
||||
diario_id = Column(Integer, primary_key=True)
|
||||
|
||||
creator_id = Column(Integer, ForeignKey("royals.id"))
|
||||
quoted_id = Column(Integer, ForeignKey("royals.id"))
|
||||
quoted_name = Column(String)
|
||||
creator_id = Column(Integer, ForeignKey("royals.uid"))
|
||||
quoted_account_id = Column(Integer, ForeignKey("royals.uid"))
|
||||
quoted = Column(String)
|
||||
text = Column(Text, nullable=False)
|
||||
context = Column(Text)
|
||||
timestamp = Column(DateTime, nullable=False)
|
||||
|
@ -24,7 +24,7 @@ class Diario:
|
|||
spoiler = Column(Boolean, default=False)
|
||||
|
||||
creator = relationship("Royal", foreign_keys=creator_id, backref="diario_created")
|
||||
quoted = relationship("Royal", foreign_keys=quoted_id, backref="diario_quoted")
|
||||
quoted_account = relationship("Royal", foreign_keys=quoted_account_id, backref="diario_quoted")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Diario {self.diario_id}>"
|
||||
|
|
|
@ -17,7 +17,6 @@ class Telegram:
|
|||
tg_last_name = Column(String)
|
||||
tg_username = Column(String)
|
||||
tg_avatar = Column(LargeBinary)
|
||||
# TODO: Add an index? https://www.citusdata.com/blog/2016/10/12/count-performance/
|
||||
|
||||
royal = relationship("Royal", backref="telegram")
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ class Call:
|
|||
The data must be pickleable."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def get_author(self):
|
||||
"""Try to find the universal identifier of the user that sent the message.
|
||||
That probably means, the database row identifying the user."""
|
||||
raise NotImplementedError()
|
||||
|
||||
# These parameters / methods should be left alone
|
||||
def __init__(self, channel, command: Command, *args, **kwargs):
|
||||
self.channel = channel
|
||||
|
|
Loading…
Add table
Reference in a new issue