mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 11:34:18 +00:00
Start porting to 5.11 (sigh)
This commit is contained in:
parent
c1145550dd
commit
3f1c8a57d3
30 changed files with 746 additions and 1045 deletions
779
poetry.lock
generated
779
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
|
||||
[tool.poetry]
|
||||
name = "royalpack"
|
||||
version = "5.13.9"
|
||||
version = "5.14.0"
|
||||
description = "A Royalnet command pack for the Royal Games community"
|
||||
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
|
||||
license = "AGPL-3.0+"
|
||||
|
@ -28,13 +28,12 @@
|
|||
itsdangerous = "^1.1.0"
|
||||
|
||||
[tool.poetry.dependencies.royalnet]
|
||||
version = "~5.10.4"
|
||||
version = "~5.11.0"
|
||||
# Maybe... there is a way to make these selectable?
|
||||
extras = [
|
||||
"telegram",
|
||||
"discord",
|
||||
"alchemy_easy",
|
||||
"bard",
|
||||
"constellation",
|
||||
"sentry",
|
||||
"herald",
|
||||
|
|
|
@ -23,7 +23,6 @@ from .leagueoflegends import LeagueoflegendsCommand
|
|||
from .magickfiorygi import MagickfiorygiCommand
|
||||
from .magicktreasure import MagicktreasureCommand
|
||||
from .matchmaking import MatchmakingCommand
|
||||
from .peertubeupdates import PeertubeUpdatesCommand
|
||||
from .ping import PingCommand
|
||||
from .pmots import PmotsCommand
|
||||
from .dog import DogCommand
|
||||
|
@ -37,7 +36,6 @@ from .steammatch import SteammatchCommand
|
|||
from .steampowered import SteampoweredCommand
|
||||
from .treasure import TreasureCommand
|
||||
from .trivia import TriviaCommand
|
||||
from .userinfo import UserinfoCommand
|
||||
from .osu import OsuCommand
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
|
@ -66,7 +64,6 @@ available_commands = [
|
|||
MagickfiorygiCommand,
|
||||
MagicktreasureCommand,
|
||||
MatchmakingCommand,
|
||||
PeertubeUpdatesCommand,
|
||||
PingCommand,
|
||||
PmotsCommand,
|
||||
DogCommand,
|
||||
|
@ -80,7 +77,6 @@ available_commands = [
|
|||
SteampoweredCommand,
|
||||
TreasureCommand,
|
||||
TriviaCommand,
|
||||
UserinfoCommand,
|
||||
OsuCommand,
|
||||
]
|
||||
|
||||
|
|
|
@ -14,37 +14,37 @@ log = logging.getLogger(__name__)
|
|||
|
||||
class LinkerCommand(rc.Command, metaclass=abc.ABCMeta):
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
self.updater_task = None
|
||||
if self.enabled():
|
||||
self.updater_task = self.loop.create_task(self.run_updater())
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
author = await data.get_author(error_if_none=True)
|
||||
if len(args) == 0:
|
||||
message = []
|
||||
for obj in await self.get_updatables_of_user(session=data.session, user=author):
|
||||
async def change(attribute: str, value: Any):
|
||||
"""A shortcut for self.__change."""
|
||||
await self._change(session=data.session,
|
||||
obj=obj,
|
||||
attribute=attribute,
|
||||
new=value)
|
||||
async with data.session_acm() as session:
|
||||
if len(args) == 0:
|
||||
message = []
|
||||
for obj in await self.get_updatables_of_user(session=session, user=author):
|
||||
async def change(attribute: str, value: Any):
|
||||
"""A shortcut for self.__change."""
|
||||
await self._change(session=session,
|
||||
obj=obj,
|
||||
attribute=attribute,
|
||||
new=value)
|
||||
|
||||
await self.update(session=data.session, obj=obj, change=change)
|
||||
message.append(self.describe(obj))
|
||||
if len(message) == 0:
|
||||
raise rc.UserError("Nessun account connesso.")
|
||||
await data.session_commit()
|
||||
await data.reply("\n".join(message))
|
||||
else:
|
||||
created = await self.create(session=data.session, user=author, args=args, data=data)
|
||||
await data.session_commit()
|
||||
if created is not None:
|
||||
message = ["🔗 Account collegato!", "", self.describe(created)]
|
||||
await self.update(session=session, obj=obj, change=change)
|
||||
message.append(self.describe(obj))
|
||||
if len(message) == 0:
|
||||
raise rc.UserError("Nessun account connesso.")
|
||||
await ru.asyncify(session.commit)
|
||||
await data.reply("\n".join(message))
|
||||
else:
|
||||
created = await self.create(session=session, user=author, args=args, data=data)
|
||||
await ru.asyncify(session.commit)
|
||||
if created is not None:
|
||||
message = ["🔗 Account collegato!", "", self.describe(created)]
|
||||
await data.reply("\n".join(message))
|
||||
|
||||
def describe(self, obj: Updatable) -> str:
|
||||
"""The text that should be appended to the report message for a given Updatable."""
|
||||
|
@ -143,7 +143,7 @@ class LinkerCommand(rc.Command, metaclass=abc.ABCMeta):
|
|||
|
||||
def enabled(self) -> bool:
|
||||
"""Whether the updater is enabled or not."""
|
||||
return self.config[self.name]["updater"]["enabled"] and self.interface.name == "telegram"
|
||||
return self.config[self.name]["updater"]["enabled"] and isinstance(self.serf, rst.TelegramSerf)
|
||||
|
||||
def period(self) -> int:
|
||||
"""The time between two updater cycles."""
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
from typing import *
|
||||
import telegram
|
||||
from royalnet.commands import *
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.telegram as rst
|
||||
|
||||
|
||||
class CiaoruoziCommand(Command):
|
||||
class CiaoruoziCommand(rc.Command):
|
||||
name: str = "ciaoruozi"
|
||||
|
||||
description: str = "Saluta Ruozi, un leggendario essere che è tornato in Royal Games."
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
if self.interface.name == "telegram":
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
if isinstance(self.serf, rst.TelegramSerf):
|
||||
user: telegram.User = data.message.from_user
|
||||
# Se sei Ruozi, salutati da solo!
|
||||
if user.id == 112437036:
|
||||
|
|
|
@ -9,9 +9,6 @@ class CvCommand(Command):
|
|||
|
||||
syntax: str = "[a][o][n][d][h]"
|
||||
|
||||
def __init__(self, interface: CommandInterface):
|
||||
super().__init__(interface)
|
||||
|
||||
def _render_member(self,
|
||||
member,
|
||||
display_nick: bool,
|
||||
|
@ -92,7 +89,7 @@ class CvCommand(Command):
|
|||
return f"{status}{voice} {name}{activity}\n"
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
response: Dict[str, Any] = await self.interface.call_herald_event("discord", "discord_cv")
|
||||
response: Dict[str, Any] = await self.serf.call_herald_event("discord", "discord_cv")
|
||||
|
||||
flags = args.optional(0, default="")
|
||||
display_nicks = "n" in flags
|
||||
|
|
|
@ -4,6 +4,7 @@ import asyncio
|
|||
import datetime
|
||||
import royalnet.commands as rc
|
||||
import royalnet.utils as ru
|
||||
import royalnet.serf.discord as rsd
|
||||
|
||||
from ..tables import Cvstats
|
||||
|
||||
|
@ -18,14 +19,14 @@ class CvstatsCommand(rc.Command):
|
|||
|
||||
syntax: str = ""
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
if self.interface.name == "discord":
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf=serf, config=config)
|
||||
if isinstance(self.serf, rsd.DiscordSerf):
|
||||
self.loop.create_task(self._updater(1800))
|
||||
|
||||
def _is_ryg_member(self, member: dict):
|
||||
for role in member["roles"]:
|
||||
if role["id"] == self.interface.config["Cv"]["displayed_role_id"]:
|
||||
if role["id"] == self.config["Cv"]["displayed_role_id"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -33,7 +34,7 @@ class CvstatsCommand(rc.Command):
|
|||
log.info(f"Gathering Cvstats...")
|
||||
while True:
|
||||
try:
|
||||
response: Dict[str, Any] = await self.interface.call_herald_event("discord", "discord_cv")
|
||||
response: Dict[str, Any] = await self.serf.call_herald_event("discord", "discord_cv")
|
||||
except rc.ConfigurationError:
|
||||
await asyncio.sleep(10)
|
||||
continue
|
||||
|
@ -118,7 +119,8 @@ class CvstatsCommand(rc.Command):
|
|||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
CvstatsT = self.alchemy.get(Cvstats)
|
||||
|
||||
cvstats = data.session.query(CvstatsT).order_by(CvstatsT.timestamp.desc()).first()
|
||||
async with data.session_acm() as session:
|
||||
cvstats = session.query(CvstatsT).order_by(CvstatsT.timestamp.desc()).first()
|
||||
|
||||
message = [
|
||||
f"ℹ️ [b]Statistiche[/b]",
|
||||
|
|
|
@ -6,6 +6,7 @@ import aiohttp
|
|||
import royalnet.commands as rc
|
||||
import royalnet.utils as ru
|
||||
import royalnet.backpack.tables as rbt
|
||||
import royalnet.serf.telegram as rst
|
||||
|
||||
from ..tables import *
|
||||
|
||||
|
@ -38,169 +39,166 @@ class DiarioCommand(rc.Command):
|
|||
syntax = "[!] \"{testo}\" --[autore], [contesto]"
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
if self.interface.name == "telegram":
|
||||
message: telegram.Message = data.message
|
||||
reply: telegram.Message = message.reply_to_message
|
||||
creator = await data.get_author()
|
||||
# noinspection PyUnusedLocal
|
||||
quoted: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
text: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
context: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
timestamp: datetime.datetime
|
||||
# noinspection PyUnusedLocal
|
||||
media_url: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
spoiler: bool
|
||||
if creator is None:
|
||||
await data.reply("⚠️ Devi essere registrato a Royalnet per usare questo comando!")
|
||||
return
|
||||
if reply is not None:
|
||||
# Get the message text
|
||||
text = reply.text
|
||||
# Check if there's an image associated with the reply
|
||||
photosizes: Optional[List[telegram.PhotoSize]] = reply.photo
|
||||
if photosizes:
|
||||
# Text is a caption
|
||||
text = reply.caption
|
||||
media_url = await to_imgur(self.interface.config["Imgur"]["token"],
|
||||
photosizes, text if text is not None else "")
|
||||
else:
|
||||
media_url = None
|
||||
# Ensure there is a text or an image
|
||||
if not (text or media_url):
|
||||
raise rc.InvalidInputError("Il messaggio a cui hai risposto non contiene testo o immagini.")
|
||||
# Find the Royalnet account associated with the sender
|
||||
quoted_tg = await ru.asyncify(data.session.query(self.alchemy.get(rbt.Telegram))
|
||||
.filter_by(tg_id=reply.from_user.id)
|
||||
.one_or_none)
|
||||
quoted_account = quoted_tg.user if quoted_tg is not None else None
|
||||
# Find the quoted name to assign
|
||||
quoted_user: telegram.User = reply.from_user
|
||||
quoted = quoted_user.full_name
|
||||
# Get the timestamp
|
||||
timestamp = reply.date
|
||||
# Set the other properties
|
||||
spoiler = False
|
||||
context = None
|
||||
else:
|
||||
# Get the current timestamp
|
||||
timestamp = datetime.datetime.now()
|
||||
# Get the message text
|
||||
raw_text = " ".join(args)
|
||||
# Check if there's an image associated with the reply
|
||||
photosizes: Optional[List[telegram.PhotoSize]] = message.photo
|
||||
if photosizes:
|
||||
media_url = await to_imgur(self.interface.config["Imgur"]["token"],
|
||||
photosizes, raw_text if raw_text is not None else "")
|
||||
else:
|
||||
media_url = None
|
||||
# Parse the text, if it exists
|
||||
if raw_text:
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(
|
||||
r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?',
|
||||
raw_text)
|
||||
# Find the corresponding matches
|
||||
if match is not None:
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
# Otherwise, consider everything part of the text
|
||||
async with data.session_acm() as session:
|
||||
if isinstance(self.serf, rst.TelegramSerf):
|
||||
message: telegram.Message = data.message
|
||||
reply: telegram.Message = message.reply_to_message
|
||||
creator = await data.get_author()
|
||||
# noinspection PyUnusedLocal
|
||||
quoted: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
text: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
context: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
timestamp: datetime.datetime
|
||||
# noinspection PyUnusedLocal
|
||||
media_url: Optional[str]
|
||||
# noinspection PyUnusedLocal
|
||||
spoiler: bool
|
||||
if creator is None:
|
||||
await data.reply("⚠️ Devi essere registrato a Royalnet per usare questo comando!")
|
||||
return
|
||||
if reply is not None:
|
||||
# Get the message text
|
||||
text = reply.text
|
||||
# Check if there's an image associated with the reply
|
||||
photosizes: Optional[List[telegram.PhotoSize]] = reply.photo
|
||||
if photosizes:
|
||||
# Text is a caption
|
||||
text = reply.caption
|
||||
media_url = await to_imgur(self.config["Imgur"]["token"],
|
||||
photosizes, text if text is not None else "")
|
||||
else:
|
||||
spoiler = False
|
||||
text = raw_text
|
||||
quoted = None
|
||||
context = None
|
||||
# Ensure there's a quoted
|
||||
if not quoted:
|
||||
quoted = None
|
||||
if not context:
|
||||
context = None
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
if quoted is not None:
|
||||
quoted_alias = await ru.asyncify(
|
||||
data.session.query(self.alchemy.get(rbt.Alias))
|
||||
.filter_by(alias=quoted.lower()).one_or_none
|
||||
)
|
||||
else:
|
||||
quoted_alias = None
|
||||
quoted_account = quoted_alias.user if quoted_alias is not None else None
|
||||
else:
|
||||
text = None
|
||||
quoted = None
|
||||
quoted_account = None
|
||||
media_url = None
|
||||
# Ensure there is a text or an image
|
||||
if not (text or media_url):
|
||||
raise rc.InvalidInputError("Il messaggio a cui hai risposto non contiene testo o immagini.")
|
||||
# Find the Royalnet account associated with the sender
|
||||
quoted_tg = await ru.asyncify(session.query(self.alchemy.get(rbt.Telegram))
|
||||
.filter_by(tg_id=reply.from_user.id)
|
||||
.one_or_none)
|
||||
quoted_account = quoted_tg.user if quoted_tg is not None else None
|
||||
# Find the quoted name to assign
|
||||
quoted_user: telegram.User = reply.from_user
|
||||
quoted = quoted_user.full_name
|
||||
# Get the timestamp
|
||||
timestamp = reply.date
|
||||
# Set the other properties
|
||||
spoiler = False
|
||||
context = None
|
||||
# Ensure there is a text or an image
|
||||
if not (text or media_url):
|
||||
else:
|
||||
# Get the current timestamp
|
||||
timestamp = datetime.datetime.now()
|
||||
# Get the message text
|
||||
raw_text = " ".join(args)
|
||||
# Check if there's an image associated with the reply
|
||||
photosizes: Optional[List[telegram.PhotoSize]] = message.photo
|
||||
if photosizes:
|
||||
media_url = await to_imgur(self.config["Imgur"]["token"],
|
||||
photosizes, raw_text if raw_text is not None else "")
|
||||
else:
|
||||
media_url = None
|
||||
# Parse the text, if it exists
|
||||
if raw_text:
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(
|
||||
r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?',
|
||||
raw_text)
|
||||
# Find the corresponding matches
|
||||
if match is not None:
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
# Otherwise, consider everything part of the text
|
||||
else:
|
||||
spoiler = False
|
||||
text = raw_text
|
||||
quoted = None
|
||||
context = None
|
||||
# Ensure there's a quoted
|
||||
if not quoted:
|
||||
quoted = None
|
||||
if not context:
|
||||
context = None
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
if quoted is not None:
|
||||
quoted_alias = await ru.asyncify(
|
||||
session.query(self.alchemy.get(rbt.Alias))
|
||||
.filter_by(alias=quoted.lower()).one_or_none
|
||||
)
|
||||
else:
|
||||
quoted_alias = None
|
||||
quoted_account = quoted_alias.user if quoted_alias is not None else None
|
||||
else:
|
||||
text = None
|
||||
quoted = None
|
||||
quoted_account = None
|
||||
spoiler = False
|
||||
context = None
|
||||
# Ensure there is a text or an image
|
||||
if not (text or media_url):
|
||||
raise rc.InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
||||
# Create the diario quote
|
||||
diario = self.alchemy.get(Diario)(creator=creator,
|
||||
quoted_account=quoted_account,
|
||||
quoted=quoted,
|
||||
text=text,
|
||||
context=context,
|
||||
timestamp=timestamp,
|
||||
media_url=media_url,
|
||||
spoiler=spoiler)
|
||||
session.add(diario)
|
||||
await ru.asyncify(session.commit)
|
||||
await data.reply(f"✅ {str(diario)}")
|
||||
else:
|
||||
# Find the creator of the quotes
|
||||
creator = await data.get_author(error_if_none=True)
|
||||
# Recreate the full sentence
|
||||
raw_text = " ".join(args)
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?',
|
||||
raw_text)
|
||||
# Find the corresponding matches
|
||||
if match is not None:
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
# Otherwise, consider everything part of the text
|
||||
else:
|
||||
spoiler = False
|
||||
text = raw_text
|
||||
quoted = None
|
||||
context = None
|
||||
timestamp = datetime.datetime.now()
|
||||
# Ensure there is some text
|
||||
if not text:
|
||||
raise rc.InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
||||
# Create the diario quote
|
||||
diario = self.alchemy.get(Diario)(creator=creator,
|
||||
quoted_account=quoted_account,
|
||||
quoted=quoted,
|
||||
text=text,
|
||||
context=context,
|
||||
timestamp=timestamp,
|
||||
media_url=media_url,
|
||||
spoiler=spoiler)
|
||||
data.session.add(diario)
|
||||
await ru.asyncify(data.session.commit)
|
||||
await data.reply(f"✅ {str(diario)}")
|
||||
else:
|
||||
# Find the creator of the quotes
|
||||
creator = await data.get_author(error_if_none=True)
|
||||
# Recreate the full sentence
|
||||
raw_text = " ".join(args)
|
||||
# Pass the sentence through the diario regex
|
||||
match = re.match(r'(!)? *["«‘“‛‟❛❝〝"`]([^"]+)["»’”❜❞〞"`] *(?:(?:-{1,2}|—) *([^,]+))?(?:, *([^ ].*))?',
|
||||
raw_text)
|
||||
# Find the corresponding matches
|
||||
if match is not None:
|
||||
spoiler = bool(match.group(1))
|
||||
text = match.group(2)
|
||||
quoted = match.group(3)
|
||||
context = match.group(4)
|
||||
# Otherwise, consider everything part of the text
|
||||
else:
|
||||
spoiler = False
|
||||
text = raw_text
|
||||
quoted = None
|
||||
context = None
|
||||
timestamp = datetime.datetime.now()
|
||||
# Ensure there is some text
|
||||
if not text:
|
||||
raise rc.InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
||||
# Or a quoted
|
||||
if not quoted:
|
||||
quoted = None
|
||||
if not context:
|
||||
context = None
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
if quoted is not None:
|
||||
quoted_alias = await ru.asyncify(
|
||||
data.session.query(self.alchemy.get(rbt.Alias))
|
||||
.filter_by(alias=quoted.lower())
|
||||
.one_or_none
|
||||
)
|
||||
else:
|
||||
quoted_alias = None
|
||||
quoted_account = quoted_alias.user if quoted_alias is not None else None
|
||||
if quoted_alias is not None and quoted_account is None:
|
||||
raise rc.UserError("Il nome dell'autore è ambiguo, quindi la riga non è stata aggiunta.\n"
|
||||
"Per piacere, ripeti il comando con un nome più specifico!")
|
||||
# Create the diario quote
|
||||
diario = self.alchemy.Diario(creator=creator,
|
||||
quoted_account=quoted_account,
|
||||
quoted=quoted,
|
||||
text=text,
|
||||
context=context,
|
||||
timestamp=timestamp,
|
||||
media_url=None,
|
||||
spoiler=spoiler)
|
||||
data.session.add(diario)
|
||||
await ru.asyncify(data.session.commit)
|
||||
await data.reply(f"✅ {str(diario)}")
|
||||
# Or a quoted
|
||||
if not quoted:
|
||||
quoted = None
|
||||
if not context:
|
||||
context = None
|
||||
# Find if there's a Royalnet account associated with the quoted name
|
||||
if quoted is not None:
|
||||
quoted_account = await rbt.User.find(self.alchemy, session, quoted)
|
||||
else:
|
||||
quoted_account = None
|
||||
if quoted_account is None:
|
||||
raise rc.UserError("Il nome dell'autore è ambiguo, quindi la riga non è stata aggiunta.\n"
|
||||
"Per piacere, ripeti il comando con un nome più specifico!")
|
||||
# Create the diario quote
|
||||
DiarioT = self.alchemy.get(Diario)
|
||||
diario = DiarioT(creator=creator,
|
||||
quoted_account=quoted_account,
|
||||
quoted=quoted,
|
||||
text=text,
|
||||
context=context,
|
||||
timestamp=timestamp,
|
||||
media_url=None,
|
||||
spoiler=spoiler)
|
||||
session.add(diario)
|
||||
await ru.asyncify(session.commit)
|
||||
await data.reply(f"✅ {str(diario)}")
|
||||
|
|
|
@ -19,7 +19,8 @@ class DiarioquoteCommand(rc.Command):
|
|||
entry_id = int(args[0].lstrip("#"))
|
||||
except ValueError:
|
||||
raise rc.CommandError("L'id che hai specificato non è valido.")
|
||||
entry: Diario = await ru.asyncify(data.session.query(self.alchemy.get(Diario)).get, entry_id)
|
||||
async with data.session_acm() as session:
|
||||
entry: Diario = await ru.asyncify(session.query(self.alchemy.get(Diario)).get, entry_id)
|
||||
if entry is None:
|
||||
raise rc.CommandError("Nessuna riga con quell'id trovata.")
|
||||
await data.reply(f"ℹ️ {entry}")
|
||||
|
|
|
@ -16,14 +16,11 @@ class DiarioshuffleCommand(rc.Command):
|
|||
syntax = ""
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
DiarioT = self.alchemy.get(Diario)
|
||||
entry: List[Diario] = await ru.asyncify(
|
||||
data.session
|
||||
.query(DiarioT)
|
||||
.order_by(func.random())
|
||||
.limit(1)
|
||||
.one_or_none
|
||||
)
|
||||
if entry is None:
|
||||
raise rc.CommandError("Nessuna riga del diario trovata.")
|
||||
await data.reply(f"ℹ️ {entry}")
|
||||
async with data.session_acm() as session:
|
||||
DiarioT = self.alchemy.get(Diario)
|
||||
entry: List[Diario] = await ru.asyncify(
|
||||
session.query(DiarioT).order_by(func.random()).limit(1).one_or_none
|
||||
)
|
||||
if entry is None:
|
||||
raise rc.CommandError("Nessuna riga del diario trovata.")
|
||||
await data.reply(f"ℹ️ {entry}")
|
||||
|
|
|
@ -15,7 +15,7 @@ class EvalCommand(rc.Command):
|
|||
user: rbt.User = await data.get_author(error_if_none=True)
|
||||
if "admin" not in user.roles:
|
||||
raise rc.CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||
try:
|
||||
result = eval(args.joined(require_at_least=1))
|
||||
except Exception as e:
|
||||
|
|
|
@ -15,7 +15,7 @@ class ExecCommand(rc.Command):
|
|||
user: rbt.User = await data.get_author(error_if_none=True)
|
||||
if "admin" not in user.roles:
|
||||
raise rc.CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||
try:
|
||||
exec(args.joined(require_at_least=1))
|
||||
except Exception as e:
|
||||
|
|
|
@ -20,7 +20,8 @@ class GivefiorygiCommand(rc.Command):
|
|||
|
||||
if user_arg is None:
|
||||
raise rc.InvalidInputError("Non hai specificato un destinatario!")
|
||||
user = await rbt.User.find(self.alchemy, data.session, user_arg)
|
||||
async with data.session_acm() as session:
|
||||
user = await rbt.User.find(self.alchemy, session, user_arg)
|
||||
if user is None:
|
||||
raise rc.InvalidInputError("L'utente specificato non esiste!")
|
||||
if user.uid == author.uid:
|
||||
|
|
|
@ -13,14 +13,14 @@ class GivetreasureCommand(MagicktreasureCommand):
|
|||
|
||||
syntax: str = "{codice} {valore}"
|
||||
|
||||
async def _permission_check(self, author, code, value, data):
|
||||
async def _permission_check(self, author, code, value, data, session):
|
||||
if author.fiorygi.fiorygi < value:
|
||||
raise rc.UserError("Non hai abbastanza fiorygi per creare questo Treasure.")
|
||||
|
||||
async def _create_treasure(self, author, code, value, data):
|
||||
async def _create_treasure(self, author, code, value, data, session):
|
||||
TreasureT = self.alchemy.get(Treasure)
|
||||
|
||||
treasure = await ru.asyncify(data.session.query(TreasureT).get, code)
|
||||
treasure = await ru.asyncify(session.query(TreasureT).get, code)
|
||||
if treasure is not None:
|
||||
raise rc.UserError("Esiste già un Treasure con quel codice.")
|
||||
|
||||
|
|
|
@ -17,19 +17,19 @@ class HelpCommand(rc.Command):
|
|||
]
|
||||
|
||||
for command in sorted(list(set(self.serf.commands.values())), key=lambda c: c.name):
|
||||
message.append(f"- [c]{self.interface.prefix}{command.name}[/c]")
|
||||
message.append(f"- [c]{self.serf.prefix}{command.name}[/c]")
|
||||
|
||||
await data.reply("\n".join(message))
|
||||
else:
|
||||
name: str = args[0].lstrip(self.interface.prefix)
|
||||
name: str = args[0].lstrip(self.serf.prefix)
|
||||
|
||||
try:
|
||||
command: rc.Command = self.serf.commands[f"{self.interface.prefix}{name}"]
|
||||
command: rc.Command = self.serf.commands[f"{self.serf.prefix}{name}"]
|
||||
except KeyError:
|
||||
raise rc.InvalidInputError("Il comando richiesto non esiste.")
|
||||
|
||||
message = [
|
||||
f"ℹ️ [c]{self.interface.prefix}{command.name} {command.syntax}[/c]",
|
||||
f"ℹ️ [c]{self.serf.prefix}{command.name} {command.syntax}[/c]",
|
||||
"",
|
||||
f"{command.description}"
|
||||
]
|
||||
|
|
|
@ -29,8 +29,8 @@ class LeagueoflegendsCommand(LinkerCommand):
|
|||
"rank_flexq": "Flex",
|
||||
}
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
self._lolwatcher: Optional[riotwatcher.RiotWatcher] = None
|
||||
self._tftwatcher: Optional[riotwatcher.RiotWatcher] = None
|
||||
if self.enabled():
|
||||
|
|
|
@ -23,7 +23,8 @@ class MagickfiorygiCommand(rc.Command):
|
|||
|
||||
if user_arg is None:
|
||||
raise rc.InvalidInputError("Non hai specificato un destinatario!")
|
||||
user = await rbt.User.find(self.alchemy, data.session, user_arg)
|
||||
async with data.session_acm() as session:
|
||||
user = await rbt.User.find(self.alchemy, session, user_arg)
|
||||
if user is None:
|
||||
raise rc.InvalidInputError("L'utente specificato non esiste!")
|
||||
|
||||
|
|
|
@ -12,15 +12,15 @@ class MagicktreasureCommand(rc.Command):
|
|||
|
||||
syntax: str = "{codice} {valore}"
|
||||
|
||||
async def _permission_check(self, author, code, value, data):
|
||||
async def _permission_check(self, author, code, value, data, session):
|
||||
if "banker" not in author.roles:
|
||||
raise rc.UserError("Non hai permessi sufficienti per eseguire questo comando.")
|
||||
return author
|
||||
|
||||
async def _create_treasure(self, author, code, value, data):
|
||||
async def _create_treasure(self, author, code, value, data, session):
|
||||
TreasureT = self.alchemy.get(Treasure)
|
||||
|
||||
treasure = await ru.asyncify(data.session.query(TreasureT).get, code)
|
||||
treasure = await ru.asyncify(session.query(TreasureT).get, code)
|
||||
if treasure is not None:
|
||||
raise rc.UserError("Esiste già un Treasure con quel codice.")
|
||||
|
||||
|
@ -44,10 +44,10 @@ class MagicktreasureCommand(rc.Command):
|
|||
if value < 0:
|
||||
raise rc.InvalidInputError("Il valore deve essere maggiore o uguale a 0.")
|
||||
|
||||
await self._permission_check(author, code, value, data)
|
||||
treasure = await self._create_treasure(author, code, value, data)
|
||||
|
||||
data.session.add(treasure)
|
||||
await data.session_commit()
|
||||
async with data.session_acm() as session:
|
||||
await self._permission_check(author, code, value, data, session)
|
||||
treasure = await self._create_treasure(author, code, value, data, session)
|
||||
session.add(treasure)
|
||||
await ru.asyncify(session.commit)
|
||||
|
||||
await data.reply("✅ Treasure creato!")
|
||||
|
|
|
@ -3,7 +3,9 @@ import datetime
|
|||
import re
|
||||
import dateparser
|
||||
import typing
|
||||
import royalnet.utils as ru
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.telegram as rst
|
||||
|
||||
from ..tables import MMEvent
|
||||
from ..utils import MMTask
|
||||
|
@ -18,20 +20,20 @@ class MatchmakingCommand(rc.Command):
|
|||
|
||||
aliases = ["mm", "lfg"]
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
|
||||
# Find all active MMEvents and run the tasks for them
|
||||
session = self.alchemy.Session()
|
||||
|
||||
# Create a new MMEvent and run it
|
||||
if self.interface.name == "telegram":
|
||||
if isinstance(self.serf, rst.TelegramSerf):
|
||||
MMEventT = self.alchemy.get(MMEvent)
|
||||
active_mmevents = (
|
||||
session
|
||||
.query(MMEventT)
|
||||
.filter(
|
||||
MMEventT.interface == self.interface.name,
|
||||
MMEventT.interface == self.serf.interface_name,
|
||||
MMEventT.interrupted == False
|
||||
)
|
||||
.all()
|
||||
|
@ -74,13 +76,14 @@ class MatchmakingCommand(rc.Command):
|
|||
dt, title, description = self._parse_args(args)
|
||||
|
||||
# Add the MMEvent to the database
|
||||
mmevent: MMEvent = self.alchemy.get(MMEvent)(creator=author,
|
||||
datetime=dt,
|
||||
title=title,
|
||||
description=description,
|
||||
interface=self.interface.name)
|
||||
data.session.add(mmevent)
|
||||
await data.session_commit()
|
||||
async with data.session_acm() as session:
|
||||
mmevent: MMEvent = self.alchemy.get(MMEvent)(creator=author,
|
||||
datetime=dt,
|
||||
title=title,
|
||||
description=description,
|
||||
interface=self.serf.interface_name)
|
||||
session.add(mmevent)
|
||||
await ru.asyncify(session.commit)
|
||||
|
||||
# Create and run a task for the newly created MMEvent
|
||||
task = MMTask(mmevent.mmid, command=self)
|
||||
|
|
|
@ -7,7 +7,6 @@ import royalnet.commands as rc
|
|||
import royalnet.utils as ru
|
||||
|
||||
from .abstract.linker import LinkerCommand
|
||||
from ..types import Updatable
|
||||
from ..tables import Osu
|
||||
from ..stars.api_auth_login_osu import ApiAuthLoginOsuStar
|
||||
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
from typing import *
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import datetime
|
||||
import logging
|
||||
import dateparser
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.telegram as rst
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PeertubeUpdatesCommand(rc.Command):
|
||||
name: str = "peertubeupdates"
|
||||
|
||||
description: str = "Guarda quando è uscito l'ultimo video su PeerTube."
|
||||
|
||||
aliases = ["ptu"]
|
||||
|
||||
_ready = asyncio.Event()
|
||||
|
||||
_latest_date: datetime.datetime = None
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
if self.interface.name == "telegram":
|
||||
self.loop.create_task(self._ready_up())
|
||||
self.loop.create_task(self._update())
|
||||
|
||||
async def _get_json(self):
|
||||
log.debug("Getting jsonfeed")
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(self.config["Peertube"]["instance_url"] +
|
||||
"/feeds/videos.json?sort=-publishedAt&filter=local") as response:
|
||||
log.debug("Parsing jsonfeed")
|
||||
if response.status != 200:
|
||||
raise rc.ExternalError("Peertube is unavailable")
|
||||
j = await response.json()
|
||||
log.debug("Jsonfeed parsed successfully")
|
||||
return j
|
||||
|
||||
async def _send(self, message):
|
||||
client = self.interface.bot.client
|
||||
await self.interface.bot.safe_api_call(client.send_message,
|
||||
chat_id=self.config["Telegram"]["main_group_id"],
|
||||
text=rst.escape(message),
|
||||
parse_mode="HTML",
|
||||
disable_webpage_preview=True)
|
||||
|
||||
async def _ready_up(self):
|
||||
j = await self._get_json()
|
||||
if j["version"] != "https://jsonfeed.org/version/1":
|
||||
raise rc.ConfigurationError("url is not a jsonfeed")
|
||||
videos = j["items"]
|
||||
for video in reversed(videos):
|
||||
date_modified = dateparser.parse(video["date_modified"])
|
||||
if self._latest_date is None or date_modified > self._latest_date:
|
||||
log.debug(f"Found newer video: {date_modified}")
|
||||
self._latest_date = date_modified
|
||||
self._ready.set()
|
||||
|
||||
async def _update(self):
|
||||
await self._ready.wait()
|
||||
while True:
|
||||
j = await self._get_json()
|
||||
videos = j["items"]
|
||||
for video in reversed(videos):
|
||||
date_modified = dateparser.parse(video["date_modified"])
|
||||
if date_modified > self._latest_date:
|
||||
log.debug(f"Found newer video: {date_modified}")
|
||||
self._latest_date = date_modified
|
||||
await self._send(f"🆕 Nuovo video su RoyalTube!\n"
|
||||
f"[b]{video['title']}[/b]\n"
|
||||
f"{video['url']}")
|
||||
await asyncio.sleep(self.config["Peertube"]["feed_update_timeout"])
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
if self.interface.name != "telegram":
|
||||
raise rc.UnsupportedError()
|
||||
await data.reply(f"ℹ️ Ultimo video caricato il: [b]{self._latest_date.isoformat()}[/b]")
|
|
@ -12,7 +12,7 @@ class PingCommand(rc.Command):
|
|||
|
||||
syntax: str = ""
|
||||
|
||||
_targets = ["telegram", "discord", "matrix", "constellation"]
|
||||
_targets = ["telegram", "discord", "constellation"]
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
await data.reply("📶 Ping...")
|
||||
|
@ -21,7 +21,7 @@ class PingCommand(rc.Command):
|
|||
|
||||
start = datetime.datetime.now()
|
||||
for target in self._targets:
|
||||
tasks[target] = self.loop.create_task(self.interface.call_herald_event(target, "pong"))
|
||||
tasks[target] = self.loop.create_task(self.serf.call_herald_event(target, "pong"))
|
||||
|
||||
await asyncio.sleep(10)
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import discord
|
|||
from sqlalchemy import and_
|
||||
import royalnet.commands as rc
|
||||
import royalnet.utils as ru
|
||||
from royalnet.serf.telegram import escape as telegram_escape
|
||||
from royalnet.serf.discord import escape as discord_escape
|
||||
import royalnet.serf.telegram as rst
|
||||
import royalnet.serf.discord as rsd
|
||||
|
||||
from ..tables import Reminder
|
||||
|
||||
|
@ -22,34 +22,35 @@ class ReminderCommand(rc.Command):
|
|||
|
||||
syntax: str = "[ {data} ] {messaggio}"
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
session = interface.alchemy.Session()
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
|
||||
session = self.alchemy.Session()
|
||||
reminders = (
|
||||
session.query(interface.alchemy.get(Reminder))
|
||||
session.query(self.alchemy.get(Reminder))
|
||||
.filter(and_(
|
||||
interface.alchemy.get(Reminder).datetime >= datetime.datetime.now(),
|
||||
interface.alchemy.get(Reminder).interface_name == interface.name))
|
||||
self.alchemy.get(Reminder).datetime >= datetime.datetime.now(),
|
||||
self.alchemy.get(Reminder).interface_name == self.serf.interface_name))
|
||||
.all()
|
||||
)
|
||||
for reminder in reminders:
|
||||
interface.loop.create_task(self._remind(reminder))
|
||||
self.loop.create_task(self._remind(reminder))
|
||||
|
||||
async def _remind(self, reminder):
|
||||
await ru.sleep_until(reminder.datetime)
|
||||
if self.interface.name == "telegram":
|
||||
if isinstance(self.serf, rst.TelegramSerf):
|
||||
chat_id: int = pickle.loads(reminder.interface_data)
|
||||
client: telegram.Bot = self.serf.client
|
||||
await self.serf.api_call(client.send_message,
|
||||
chat_id=chat_id,
|
||||
text=telegram_escape(f"❗️ {reminder.message}"),
|
||||
text=rst.escape(f"❗️ {reminder.message}"),
|
||||
parse_mode="HTML",
|
||||
disable_web_page_preview=True)
|
||||
elif self.interface.name == "discord":
|
||||
elif isinstance(self.serf, rsd.DiscordSerf):
|
||||
channel_id: int = pickle.loads(reminder.interface_data)
|
||||
client: discord.Client = self.serf.client
|
||||
channel = client.get_channel(channel_id)
|
||||
await channel.send(discord_escape(f"❗️ {reminder.message}"))
|
||||
await channel.send(rsd.escape(f"❗️ {reminder.message}"))
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
try:
|
||||
|
@ -70,18 +71,19 @@ class ReminderCommand(rc.Command):
|
|||
await data.reply("⚠️ La data che hai specificato è nel passato.")
|
||||
return
|
||||
await data.reply(f"✅ Promemoria impostato per [b]{date.strftime('%Y-%m-%d %H:%M:%S')}[/b]")
|
||||
if self.interface.name == "telegram":
|
||||
if isinstance(self.serf, rst.TelegramSerf):
|
||||
interface_data = pickle.dumps(data.message.chat.id)
|
||||
elif self.interface.name == "discord":
|
||||
elif isinstance(self.serf, rsd.DiscordSerf):
|
||||
interface_data = pickle.dumps(data.message.channel.id)
|
||||
else:
|
||||
raise rc.UnsupportedError("This command does not support the current interface.")
|
||||
creator = await data.get_author()
|
||||
reminder = self.interface.alchemy.get(Reminder)(creator=creator,
|
||||
interface_name=self.interface.name,
|
||||
interface_data=interface_data,
|
||||
datetime=date,
|
||||
message=reminder_text)
|
||||
self.interface.loop.create_task(self._remind(reminder))
|
||||
data.session.add(reminder)
|
||||
await ru.asyncify(data.session.commit)
|
||||
async with data.session_acm() as session:
|
||||
reminder = self.alchemy.get(Reminder)(creator=creator,
|
||||
interface_name=self.serf.interface_name,
|
||||
interface_data=interface_data,
|
||||
datetime=date,
|
||||
message=reminder_text)
|
||||
self.loop.create_task(self._remind(reminder))
|
||||
session.add(reminder)
|
||||
await ru.asyncify(session.commit)
|
||||
|
|
|
@ -16,10 +16,7 @@ class RoyalpackCommand(rc.Command):
|
|||
return pkg_resources.get_distribution("royalpack").version
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
if __debug__:
|
||||
message = f"ℹ️ Royalpack [url=https://github.com/Steffo99/royalpack/]Unreleased[/url]\n"
|
||||
else:
|
||||
message = f"ℹ️ Royalpack [url=https://github.com/Steffo99/royalpack/releases/tag/{self.royalpack_version}]{self.royalpack_version}[/url]\n"
|
||||
message = f"ℹ️ Royalpack [url=https://github.com/Steffo99/royalpack/releases/tag/{self.royalpack_version}]{self.royalpack_version}[/url]\n"
|
||||
if "69" in self.royalpack_version:
|
||||
message += "(Nice.)"
|
||||
await data.reply(message)
|
||||
|
|
|
@ -53,8 +53,8 @@ class SteammatchCommand(rc.Command):
|
|||
|
||||
syntax: str = "{royalnet_username}+"
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
self._api = steam.webapi.WebAPI(self.config["steampowered"]["token"])
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
|
@ -64,7 +64,8 @@ class SteammatchCommand(rc.Command):
|
|||
users.append(author)
|
||||
|
||||
for arg in args:
|
||||
user = await rbt.User.find(self.alchemy, data.session, arg)
|
||||
async with data.session_acm() as session:
|
||||
user = await rbt.User.find(self.alchemy, session, arg)
|
||||
users.append(user)
|
||||
|
||||
if len(users) < 2:
|
||||
|
|
|
@ -22,8 +22,8 @@ class SteampoweredCommand(LinkerCommand):
|
|||
|
||||
syntax: str = "{url_profilo}"
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
self._api = steam.webapi.WebAPI(self.token())
|
||||
|
||||
def token(self):
|
||||
|
|
|
@ -16,16 +16,17 @@ class TreasureCommand(rc.Command):
|
|||
author = await data.get_author(error_if_none=True)
|
||||
code = args[0].lower()
|
||||
|
||||
TreasureT = self.alchemy.get(Treasure)
|
||||
async with data.session_acm() as session:
|
||||
TreasureT = self.alchemy.get(Treasure)
|
||||
|
||||
treasure = await ru.asyncify(data.session.query(TreasureT).get, code)
|
||||
if treasure is None:
|
||||
raise rc.UserError("Non esiste nessun Treasure con quel codice.")
|
||||
if treasure.redeemed_by is not None:
|
||||
raise rc.UserError(f"Quel tesoro è già stato riscattato da {treasure.redeemed_by}.")
|
||||
treasure = await ru.asyncify(session.query(TreasureT).get, code)
|
||||
if treasure is None:
|
||||
raise rc.UserError("Non esiste nessun Treasure con quel codice.")
|
||||
if treasure.redeemed_by is not None:
|
||||
raise rc.UserError(f"Quel tesoro è già stato riscattato da {treasure.redeemed_by}.")
|
||||
|
||||
treasure.redeemed_by = author
|
||||
await data.session_commit()
|
||||
treasure.redeemed_by = author
|
||||
await ru.asyncify(session.commit)
|
||||
await FiorygiTransaction.spawn_fiorygi(data,
|
||||
author,
|
||||
treasure.value,
|
||||
|
|
|
@ -31,117 +31,116 @@ class TriviaCommand(rc.Command):
|
|||
|
||||
# _question_lock: bool = False
|
||||
|
||||
def __init__(self, interface: rc.CommandInterface):
|
||||
super().__init__(interface)
|
||||
def __init__(self, serf, config):
|
||||
super().__init__(serf, config)
|
||||
self._answerers: Dict[uuid.UUID, Dict[str, bool]] = {}
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
arg = args.optional(0)
|
||||
if arg == "credits":
|
||||
await data.reply(f"ℹ️ [c]{self.interface.prefix}{self.name}[/c] di [i]Steffo[/i]\n"
|
||||
f"\n"
|
||||
f"Tutte le domande vengono dall'[b]Open Trivia Database[/b] di [i]Pixeltail Games[/i],"
|
||||
f" creatori di Tower Unite, e sono rilasciate sotto la licenza [b]CC BY-SA 4.0[/b].")
|
||||
return
|
||||
elif arg == "scores":
|
||||
trivia_scores = await ru.asyncify(data.session.query(self.alchemy.get(TriviaScore)).all)
|
||||
strings = ["🏆 [b]Trivia Leaderboards[/b]\n"]
|
||||
for index, ts in enumerate(sorted(trivia_scores, key=lambda ts: -ts.score)):
|
||||
if index > 3:
|
||||
index = 3
|
||||
strings.append(f"{self._medal_emojis[index]} {ts.user.username}: [b]{ts.score:.0f}p[/b]"
|
||||
f" ({ts.correct_answers}/{ts.total_answers})")
|
||||
await data.reply("\n".join(strings))
|
||||
return
|
||||
# if self._question_lock:
|
||||
# raise rc.CommandError("C'è già un'altra domanda attiva!")
|
||||
# self._question_lock = True
|
||||
# Fetch the question
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get("https://opentdb.com/api.php?amount=1") as response:
|
||||
j = await response.json()
|
||||
# Parse the question
|
||||
if j["response_code"] != 0:
|
||||
raise rc.CommandError(f"OpenTDB returned an error response_code ({j['response_code']}).")
|
||||
question = j["results"][0]
|
||||
text = f'❓ [b]{question["category"]}[/b]\n' \
|
||||
f'{html.unescape(question["question"])}'
|
||||
# Prepare answers
|
||||
correct_answer: str = question["correct_answer"]
|
||||
wrong_answers: List[str] = question["incorrect_answers"]
|
||||
answers: List[str] = [correct_answer, *wrong_answers]
|
||||
if question["type"] == "multiple":
|
||||
random.shuffle(answers)
|
||||
elif question["type"] == "boolean":
|
||||
answers.sort(key=lambda a: a)
|
||||
answers.reverse()
|
||||
else:
|
||||
raise NotImplementedError("Unknown question type")
|
||||
# Find the correct index
|
||||
for index, answer in enumerate(answers):
|
||||
if answer == correct_answer:
|
||||
correct_index = index
|
||||
break
|
||||
else:
|
||||
raise ValueError("correct_index not found")
|
||||
# Add emojis
|
||||
for index, answer in enumerate(answers):
|
||||
answers[index] = f"{self._letter_emojis[index]} {html.unescape(answers[index])}"
|
||||
# Create the question id
|
||||
question_id = uuid.uuid4()
|
||||
self._answerers[question_id] = {}
|
||||
|
||||
# Create the correct and wrong functions
|
||||
async def correct(data: rc.CommandData):
|
||||
answerer_ = await data.get_author(error_if_none=True)
|
||||
try:
|
||||
self._answerers[question_id][answerer_.uid] = True
|
||||
except KeyError:
|
||||
raise rc.UserError("Tempo scaduto!")
|
||||
await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!")
|
||||
|
||||
async def wrong(data: rc.CommandData):
|
||||
answerer_ = await data.get_author(error_if_none=True)
|
||||
try:
|
||||
self._answerers[question_id][answerer_.uid] = False
|
||||
except KeyError:
|
||||
raise rc.UserError("Tempo scaduto!")
|
||||
await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!")
|
||||
|
||||
# Add question
|
||||
keyboard: List[rc.KeyboardKey] = []
|
||||
for index, answer in enumerate(answers):
|
||||
if index == correct_index:
|
||||
keyboard.append(rc.KeyboardKey(interface=self.interface,
|
||||
short=self._letter_emojis[index],
|
||||
text=answers[index],
|
||||
callback=correct))
|
||||
async with data.session_acm() as session:
|
||||
if arg == "credits":
|
||||
await data.reply(f"ℹ️ [c]{self.serf.prefix}{self.name}[/c] di [i]Steffo[/i]\n"
|
||||
f"\n"
|
||||
f"Tutte le domande vengono dall'[b]Open Trivia Database[/b] di [i]Pixeltail Games[/i],"
|
||||
f" creatori di Tower Unite, e sono rilasciate sotto la licenza [b]CC BY-SA 4.0[/b].")
|
||||
return
|
||||
elif arg == "scores":
|
||||
trivia_scores = await ru.asyncify(session.query(self.alchemy.get(TriviaScore)).all)
|
||||
strings = ["🏆 [b]Trivia Leaderboards[/b]\n"]
|
||||
for index, ts in enumerate(sorted(trivia_scores, key=lambda ts: -ts.score)):
|
||||
if index > 3:
|
||||
index = 3
|
||||
strings.append(f"{self._medal_emojis[index]} {ts.user.username}: [b]{ts.score:.0f}p[/b]"
|
||||
f" ({ts.correct_answers}/{ts.total_answers})")
|
||||
await data.reply("\n".join(strings))
|
||||
return
|
||||
# if self._question_lock:
|
||||
# raise rc.CommandError("C'è già un'altra domanda attiva!")
|
||||
# self._question_lock = True
|
||||
# Fetch the question
|
||||
async with aiohttp.ClientSession() as ws:
|
||||
async with ws.get("https://opentdb.com/api.php?amount=1") as response:
|
||||
j = await response.json()
|
||||
# Parse the question
|
||||
if j["response_code"] != 0:
|
||||
raise rc.CommandError(f"OpenTDB returned an error response_code ({j['response_code']}).")
|
||||
question = j["results"][0]
|
||||
text = f'❓ [b]{question["category"]}[/b]\n' \
|
||||
f'{html.unescape(question["question"])}'
|
||||
# Prepare answers
|
||||
correct_answer: str = question["correct_answer"]
|
||||
wrong_answers: List[str] = question["incorrect_answers"]
|
||||
answers: List[str] = [correct_answer, *wrong_answers]
|
||||
if question["type"] == "multiple":
|
||||
random.shuffle(answers)
|
||||
elif question["type"] == "boolean":
|
||||
answers.sort(key=lambda a: a)
|
||||
answers.reverse()
|
||||
else:
|
||||
keyboard.append(rc.KeyboardKey(interface=self.interface,
|
||||
short=self._letter_emojis[index],
|
||||
text=answers[index],
|
||||
callback=wrong))
|
||||
async with data.keyboard(text=text, keys=keyboard):
|
||||
await asyncio.sleep(self._answer_time)
|
||||
results = f"❗️ Tempo scaduto!\n" \
|
||||
f"La risposta corretta era [b]{answers[correct_index]}[/b]!\n\n"
|
||||
for answerer_id in self._answerers[question_id]:
|
||||
answerer = data.session.query(self.alchemy.get(rbt.users.User)).get(answerer_id)
|
||||
if answerer.trivia_score is None:
|
||||
ts = self.interface.alchemy.get(TriviaScore)(user=answerer)
|
||||
data.session.add(ts)
|
||||
await ru.asyncify(data.session.commit)
|
||||
previous_score = answerer.trivia_score.score
|
||||
if self._answerers[question_id][answerer_id]:
|
||||
results += self._correct_emoji
|
||||
answerer.trivia_score.correct_answers += 1
|
||||
raise NotImplementedError("Unknown question type")
|
||||
# Find the correct index
|
||||
for index, answer in enumerate(answers):
|
||||
if answer == correct_answer:
|
||||
correct_index = index
|
||||
break
|
||||
else:
|
||||
results += self._wrong_emoji
|
||||
answerer.trivia_score.wrong_answers += 1
|
||||
current_score = answerer.trivia_score.score
|
||||
score_difference = current_score - previous_score
|
||||
results += f" {answerer}: [b]{current_score:.0f}p[/b] ({score_difference:+.0f}p)\n"
|
||||
await data.reply(results)
|
||||
del self._answerers[question_id]
|
||||
await ru.asyncify(data.session.commit)
|
||||
# self._question_lock = False
|
||||
raise ValueError("correct_index not found")
|
||||
# Add emojis
|
||||
for index, answer in enumerate(answers):
|
||||
answers[index] = f"{self._letter_emojis[index]} {html.unescape(answers[index])}"
|
||||
# Create the question id
|
||||
question_id = uuid.uuid4()
|
||||
self._answerers[question_id] = {}
|
||||
|
||||
# Create the correct and wrong functions
|
||||
async def correct(data: rc.CommandData):
|
||||
answerer_ = await data.get_author(error_if_none=True)
|
||||
try:
|
||||
self._answerers[question_id][answerer_.uid] = True
|
||||
except KeyError:
|
||||
raise rc.UserError("Tempo scaduto!")
|
||||
await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!")
|
||||
|
||||
async def wrong(data: rc.CommandData):
|
||||
answerer_ = await data.get_author(error_if_none=True)
|
||||
try:
|
||||
self._answerers[question_id][answerer_.uid] = False
|
||||
except KeyError:
|
||||
raise rc.UserError("Tempo scaduto!")
|
||||
await data.reply("🆗 Hai risposto alla domanda. Ora aspetta un attimo per i risultati!")
|
||||
|
||||
# Add question
|
||||
keyboard: List[rc.KeyboardKey] = []
|
||||
for index, answer in enumerate(answers):
|
||||
if index == correct_index:
|
||||
keyboard.append(rc.KeyboardKey(short=self._letter_emojis[index],
|
||||
text=answers[index],
|
||||
callback=correct))
|
||||
else:
|
||||
keyboard.append(rc.KeyboardKey(short=self._letter_emojis[index],
|
||||
text=answers[index],
|
||||
callback=wrong))
|
||||
async with data.keyboard(text=text, keys=keyboard):
|
||||
await asyncio.sleep(self._answer_time)
|
||||
results = f"❗️ Tempo scaduto!\n" \
|
||||
f"La risposta corretta era [b]{answers[correct_index]}[/b]!\n\n"
|
||||
for answerer_id in self._answerers[question_id]:
|
||||
answerer = session.query(self.alchemy.get(rbt.users.User)).get(answerer_id)
|
||||
if answerer.trivia_score is None:
|
||||
ts = self.alchemy.get(TriviaScore)(user=answerer)
|
||||
session.add(ts)
|
||||
await ru.asyncify(session.commit)
|
||||
previous_score = answerer.trivia_score.score
|
||||
if self._answerers[question_id][answerer_id]:
|
||||
results += self._correct_emoji
|
||||
answerer.trivia_score.correct_answers += 1
|
||||
else:
|
||||
results += self._wrong_emoji
|
||||
answerer.trivia_score.wrong_answers += 1
|
||||
current_score = answerer.trivia_score.score
|
||||
score_difference = current_score - previous_score
|
||||
results += f" {answerer}: [b]{current_score:.0f}p[/b] ({score_difference:+.0f}p)\n"
|
||||
await data.reply(results)
|
||||
del self._answerers[question_id]
|
||||
await ru.asyncify(session.commit)
|
||||
# self._question_lock = False
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
from typing import *
|
||||
import royalnet.commands as rc
|
||||
import royalnet.backpack.tables as rbt
|
||||
|
||||
|
||||
class UserinfoCommand(rc.Command):
|
||||
name: str = "userinfo"
|
||||
|
||||
aliases = ["uinfo", "ui", "useri"]
|
||||
|
||||
description: str = "Visualizza informazioni su un utente."
|
||||
|
||||
syntax = "[username]"
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||
username = args.optional(0)
|
||||
if username is None:
|
||||
user: rbt.User = await data.get_author(error_if_none=True)
|
||||
else:
|
||||
found: Optional[rbt.User] = await rbt.User.find(self.alchemy, data.session, username)
|
||||
if not found:
|
||||
raise rc.InvalidInputError("Utente non trovato.")
|
||||
else:
|
||||
user = found
|
||||
|
||||
r = [
|
||||
f"ℹ️ [url=https://ryg.steffo.eu/#/user/{user.uid}]{user.username}[/url]",
|
||||
f"{', '.join(user.roles)}",
|
||||
]
|
||||
|
||||
if user.email:
|
||||
r.append(f"{user.email}")
|
||||
|
||||
r.append("")
|
||||
|
||||
# Bios are a bit too long
|
||||
# if user.bio:
|
||||
# r.append(f"{user.bio}")
|
||||
|
||||
for account in user.telegram:
|
||||
r.append(f"{account}")
|
||||
|
||||
for account in user.discord:
|
||||
r.append(f"{account}")
|
||||
|
||||
for account in user.steam:
|
||||
r.append(f"{account}")
|
||||
if account.dota is not None:
|
||||
r.append(f"{account.dota}")
|
||||
if account.brawlhalla is not None:
|
||||
r.append(f"{account.brawlhalla}")
|
||||
|
||||
for account in user.leagueoflegends:
|
||||
r.append(f"{account}")
|
||||
|
||||
r.append("")
|
||||
|
||||
r.append(f"Ha creato [b]{len(user.diario_created)}[/b] righe di "
|
||||
f"[url=https://ryg.steffo.eu/#/diario]Diario[/url], e vi compare in"
|
||||
f" [b]{len(user.diario_quoted)}[/b] righe.")
|
||||
|
||||
r.append("")
|
||||
|
||||
if user.trivia_score:
|
||||
r.append(f"Ha [b]{user.trivia_score.score:.0f}[/b] punti Trivia, avendo risposto correttamente a"
|
||||
f" [b]{user.trivia_score.correct_answers}[/b] domande su"
|
||||
f" [b]{user.trivia_score.total_answers}[/b].")
|
||||
r.append("")
|
||||
|
||||
if user.fiorygi:
|
||||
r.append(f"Ha [b]{user.fiorygi}[/b].")
|
||||
r.append("")
|
||||
|
||||
await data.reply("\n".join(r))
|
|
@ -4,6 +4,7 @@ import datetime
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
import royalnet.utils as ru
|
||||
|
||||
from .fiorygi import Fiorygi
|
||||
|
||||
|
@ -48,35 +49,38 @@ class FiorygiTransaction:
|
|||
@classmethod
|
||||
async def spawn_fiorygi(cls, data: "CommandData", user, qty: int, reason: str):
|
||||
if user.fiorygi is None:
|
||||
data.session.add(data._interface.alchemy.get(Fiorygi)(
|
||||
async with data.session_acm() as session:
|
||||
session.add(data.alchemy.get(Fiorygi)(
|
||||
user_id=user.uid,
|
||||
fiorygi=0
|
||||
))
|
||||
await ru.asyncify(session.commit)
|
||||
|
||||
async with data.session_acm() as session:
|
||||
transaction = data.alchemy.get(FiorygiTransaction)(
|
||||
user_id=user.uid,
|
||||
fiorygi=0
|
||||
))
|
||||
await data.session_commit()
|
||||
change=qty,
|
||||
reason=reason,
|
||||
timestamp=datetime.datetime.now()
|
||||
)
|
||||
session.add(transaction)
|
||||
|
||||
transaction = data._interface.alchemy.get(FiorygiTransaction)(
|
||||
user_id=user.uid,
|
||||
change=qty,
|
||||
reason=reason,
|
||||
timestamp=datetime.datetime.now()
|
||||
)
|
||||
data.session.add(transaction)
|
||||
user.fiorygi.fiorygi += qty
|
||||
await ru.asyncify(session.commit)
|
||||
|
||||
user.fiorygi.fiorygi += qty
|
||||
await data.session_commit()
|
||||
if len(user.telegram) > 0:
|
||||
user_str = user.telegram[0].mention()
|
||||
else:
|
||||
user_str = user.username
|
||||
|
||||
if len(user.telegram) > 0:
|
||||
user_str = user.telegram[0].mention()
|
||||
else:
|
||||
user_str = user.username
|
||||
if qty > 0:
|
||||
msg = f"💰 [b]{user_str}[/b] ha ottenuto [b]{qty}[/b] fioryg{'i' if qty != 1 else ''} per [i]{reason}[/i]!"
|
||||
elif qty == 0:
|
||||
msg = f"❓ [b]{user_str}[/b] ha mantenuto i suoi fiorygi attuali per [i]{reason}[/i].\nWait, cosa?"
|
||||
else:
|
||||
msg = f"💸 [b]{user_str}[/b] ha perso [b]{-qty}[/b] fioryg{'i' if qty != -1 else ''} per [i]{reason}[/i]."
|
||||
|
||||
if qty > 0:
|
||||
msg = f"💰 [b]{user_str}[/b] ha ottenuto [b]{qty}[/b] fioryg{'i' if qty != 1 else ''} per [i]{reason}[/i]!"
|
||||
elif qty == 0:
|
||||
msg = f"❓ [b]{user_str}[/b] ha mantenuto i suoi fiorygi attuali per [i]{reason}[/i].\nWait, cosa?"
|
||||
else:
|
||||
msg = f"💸 [b]{user_str}[/b] ha perso [b]{-qty}[/b] fioryg{'i' if qty != -1 else ''} per [i]{reason}[/i]."
|
||||
|
||||
await data._interface.call_herald_event("telegram", "telegram_message",
|
||||
chat_id=data._interface.config["Telegram"]["main_group_id"],
|
||||
text=msg)
|
||||
await data.command.serf.call_herald_event(
|
||||
"telegram", "telegram_message",
|
||||
chat_id=data.command.config["Telegram"]["main_group_id"],
|
||||
text=msg)
|
||||
|
|
Loading…
Reference in a new issue