mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Progress on mm
This commit is contained in:
parent
c7ebfe3622
commit
add6170183
21 changed files with 189 additions and 475 deletions
|
@ -11,7 +11,7 @@ from .videochannel import VideochannelCommand
|
||||||
from .dnditem import DnditemCommand
|
from .dnditem import DnditemCommand
|
||||||
from .dndspell import DndspellCommand
|
from .dndspell import DndspellCommand
|
||||||
from .trivia import TriviaCommand
|
from .trivia import TriviaCommand
|
||||||
from .mm import MmCommand
|
from .matchmaking import MmCommand
|
||||||
from .pause import PauseCommand
|
from .pause import PauseCommand
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
from .playmode import PlaymodeCommand
|
from .playmode import PlaymodeCommand
|
||||||
|
|
|
@ -10,7 +10,7 @@ class CvCommand(Command):
|
||||||
|
|
||||||
description: str = "Elenca le persone attualmente connesse alla chat vocale."
|
description: str = "Elenca le persone attualmente connesse alla chat vocale."
|
||||||
|
|
||||||
syntax: str = "[guildname] ['all']"
|
syntax: str = "[guildname] [all]"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _legacy_cv_handler(bot: DiscordBot, guild_name: typing.Optional[str], everyone: bool):
|
async def _legacy_cv_handler(bot: DiscordBot, guild_name: typing.Optional[str], everyone: bool):
|
||||||
|
|
|
@ -33,7 +33,7 @@ class DiarioCommand(Command):
|
||||||
|
|
||||||
description: str = "Aggiungi una citazione al Diario."
|
description: str = "Aggiungi una citazione al Diario."
|
||||||
|
|
||||||
syntax = "[!] \"(testo)\" --[autore], [contesto]"
|
syntax = "[!] \"{testo}\" --[autore], [contesto]"
|
||||||
|
|
||||||
tables = {User, Diario, Alias}
|
tables = {User, Diario, Alias}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class DnditemCommand(Command):
|
||||||
|
|
||||||
description: str = "Ottieni informazioni su un oggetto di D&D5e."
|
description: str = "Ottieni informazioni su un oggetto di D&D5e."
|
||||||
|
|
||||||
syntax = "(nomeoggetto)"
|
syntax = "{nomeoggetto}"
|
||||||
|
|
||||||
_dnddata: sortedcontainers.SortedKeyList = None
|
_dnddata: sortedcontainers.SortedKeyList = None
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class DndspellCommand(Command):
|
||||||
|
|
||||||
description: str = "Ottieni informazioni su una magia di D&D5e."
|
description: str = "Ottieni informazioni su una magia di D&D5e."
|
||||||
|
|
||||||
syntax = "(nomemagia)"
|
syntax = "{nomemagia}"
|
||||||
|
|
||||||
_dnddata: sortedcontainers.SortedKeyList = None
|
_dnddata: sortedcontainers.SortedKeyList = None
|
||||||
|
|
||||||
|
|
129
royalnet/packs/royal/commands/matchmaking.py
Normal file
129
royalnet/packs/royal/commands/matchmaking.py
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
import pickle
|
||||||
|
from telegram import Bot as PTBBot
|
||||||
|
from telegram import Message as PTBMessage
|
||||||
|
from telegram.error import BadRequest
|
||||||
|
from telegram import InlineKeyboardMarkup as IKM
|
||||||
|
from telegram import InlineKeyboardButton as IKB
|
||||||
|
from royalnet.commands import *
|
||||||
|
from royalnet.bots import TelegramBot
|
||||||
|
from royalnet.utils import telegram_escape, asyncify
|
||||||
|
from ..tables import MMEvent, MMResponse
|
||||||
|
from ..utils import MMChoice, MMInterfaceData, MMInterfaceDataTelegram
|
||||||
|
|
||||||
|
|
||||||
|
class MatchmakingCommand(Command):
|
||||||
|
name: str = "matchmaking"
|
||||||
|
|
||||||
|
description: str = "Cerca persone per una partita a qualcosa!"
|
||||||
|
|
||||||
|
syntax: str = "[ {ora} ] {nome}\n[descrizione]"
|
||||||
|
|
||||||
|
aliases = ["mm", "lfg"]
|
||||||
|
|
||||||
|
tables = {MMEvent, MMResponse}
|
||||||
|
|
||||||
|
def __init__(self, interface: CommandInterface):
|
||||||
|
super().__init__(interface)
|
||||||
|
# Find all relevant MMEvents and run them
|
||||||
|
...
|
||||||
|
|
||||||
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
|
# Create a new MMEvent and run it
|
||||||
|
...
|
||||||
|
|
||||||
|
_mm_chat_id = -1001224004974
|
||||||
|
|
||||||
|
def _gen_mm_message(self, mmevent: MMEvent) -> str:
|
||||||
|
text = f"🌐 [{mmevent.datetime.strftime('%Y-%m-%d %H:%M')}] [b]{mmevent.title}[/b]\n"
|
||||||
|
if mmevent.description:
|
||||||
|
text += f"{mmevent.description}\n"
|
||||||
|
text += "\n"
|
||||||
|
for response in mmevent.responses:
|
||||||
|
response: MMResponse
|
||||||
|
text += f"{response.choice.value} {response.royal}\n"
|
||||||
|
return text
|
||||||
|
|
||||||
|
def _gen_telegram_keyboard(self, mmevent: MMEvent):
|
||||||
|
return IKM([
|
||||||
|
[IKB(f"{MMChoice.YES.value} Ci sarò!", callback_data=f"mm{mmevent.mmid}_YES")],
|
||||||
|
[IKB(f"{MMChoice.MAYBE.value} (Forse.)", callback_data=f"mm{mmevent.mmid}_MAYBE")],
|
||||||
|
[IKB(f"{MMChoice.LATE_SHORT.value} Arrivo dopo 5-10 min.", callback_data=f"mm{mmevent.mmid}_LATE_SHORT")],
|
||||||
|
[IKB(f"{MMChoice.LATE_MEDIUM.value} Arrivo dopo 15-35 min.", callback_data=f"mm{mmevent.mmid}_LATE_MEDIUM")],
|
||||||
|
[IKB(f"{MMChoice.LATE_LONG.value} Arrivo dopo 40+ min.", callback_data=f"mm{mmevent.mmid}_LATE_LONG")],
|
||||||
|
[IKB(f"{MMChoice.NO_TIME} Non posso a quell'ora...", callback_data=f"mm{mmevent.mmid}_NO_TIME")],
|
||||||
|
[IKB(f"{MMChoice.NO_INTEREST} Non mi interessa.", callback_data=f"mm{mmevent.mmid}_NO_INTEREST")],
|
||||||
|
[IKB(f"{MMChoice.NO_TECH} Ho un problema!", callback_data=f"mm{mmevent.mmid}_NO_TECH")],
|
||||||
|
])
|
||||||
|
|
||||||
|
async def _update_telegram_mm_message(self, client: PTBBot, mmevent: MMEvent):
|
||||||
|
try:
|
||||||
|
await self.interface.bot.safe_api_call(client.edit_message_text,
|
||||||
|
chat_id=self._mm_chat_id,
|
||||||
|
text=telegram_escape(self._gen_mm_message(mmevent)),
|
||||||
|
message_id=mmevent.interface_data,
|
||||||
|
parse_mode="HTML",
|
||||||
|
disable_web_page_preview=True,
|
||||||
|
reply_markup=self._gen_telegram_keyboard(mmevent))
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _gen_mm_telegram_callback(self, client: PTBBot, mmid: int, choice: MMChoice):
|
||||||
|
async def callback(data: CommandData):
|
||||||
|
author = await data.get_author(error_if_none=True)
|
||||||
|
# Find the MMEvent with the current session
|
||||||
|
mmevent: MMEvent = await asyncify(data.session.query(self.alchemy.MMEvent).get, mmid)
|
||||||
|
mmresponse: MMResponse = await asyncify(data.session.query(self.alchemy.MMResponse).filter_by(royal=author, mmevent=mmevent).one_or_none)
|
||||||
|
if mmresponse is None:
|
||||||
|
mmresponse = self.alchemy.MMResponse(royal=author, mmevent=mmevent, choice=choice)
|
||||||
|
data.session.add(mmresponse)
|
||||||
|
else:
|
||||||
|
mmresponse.choice = choice
|
||||||
|
await data.session_commit()
|
||||||
|
await self._update_telegram_mm_message(client, mmevent)
|
||||||
|
return f"✅ Messaggio ricevuto!"
|
||||||
|
return callback
|
||||||
|
|
||||||
|
async def _run_mmevent(self, mmid: int):
|
||||||
|
"""Run a MMEvent."""
|
||||||
|
# Open a new Alchemy Session
|
||||||
|
session = self.alchemy.Session()
|
||||||
|
# Find the MMEvent with the current session
|
||||||
|
mmevent: MMEvent = await asyncify(session.query(self.alchemy.MMEvent).get, mmid)
|
||||||
|
if mmevent is None:
|
||||||
|
raise ValueError("Invalid mmid.")
|
||||||
|
# Ensure the MMEvent interface matches the current one
|
||||||
|
if mmevent.interface != self.interface.name:
|
||||||
|
raise ValueError("Invalid interface.")
|
||||||
|
# If the matchmaking message hasn't been sent yet, do so now
|
||||||
|
if mmevent.interface_data is None:
|
||||||
|
if self.interface.name == "telegram":
|
||||||
|
bot: TelegramBot = self.interface.bot
|
||||||
|
client: PTBBot = bot.client
|
||||||
|
# Build the Telegram keyboard
|
||||||
|
# Send the keyboard
|
||||||
|
message: PTBMessage = await self.interface.bot.safe_api_call(client.send_message,
|
||||||
|
chat_id=self._mm_chat_id,
|
||||||
|
text=telegram_escape(self._gen_mm_message(mmevent)),
|
||||||
|
parse_mode="HTML",
|
||||||
|
disable_webpage_preview=True,
|
||||||
|
reply_markup=self._gen_telegram_keyboard(mmevent.mmid))
|
||||||
|
# Store message data in the interface data object
|
||||||
|
mmevent.interface_data = MMInterfaceDataTelegram(chat_id=self._mm_chat_id, message_id=message.message_id)
|
||||||
|
else:
|
||||||
|
raise UnsupportedError()
|
||||||
|
# Register handlers for the keyboard events
|
||||||
|
if self.interface.name == "telegram":
|
||||||
|
bot: TelegramBot = self.interface.bot
|
||||||
|
client: PTBBot = bot.client
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_YES", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.YES))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_MAYBE", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.MAYBE))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_LATE_SHORT", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_SHORT))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_LATE_MEDIUM", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_MEDIUM))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_LATE_LONG", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.LATE_LONG))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_NO_TIME", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.NO_TIME))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_NO_INTEREST", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.NO_INTEREST))
|
||||||
|
self.interface.register_keyboard_key(f"mm{mmevent.mmid}_NO_TECH", callback=self._gen_mm_telegram_callback(client, mmid, MMChoice.NO_TECH))
|
||||||
|
else:
|
||||||
|
raise UnsupportedError()
|
||||||
|
# Sleep until the time of the event
|
||||||
|
...
|
|
@ -1,404 +0,0 @@
|
||||||
import datetime
|
|
||||||
import dateparser
|
|
||||||
import telegram
|
|
||||||
import asyncio
|
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
import typing
|
|
||||||
from royalnet.commands import *
|
|
||||||
from royalnet.utils import asyncify, telegram_escape, sleep_until
|
|
||||||
from ..tables import MMEvent, MMDecision, MMResponse
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class MmCommand(Command):
|
|
||||||
"""Matchmaking command.
|
|
||||||
|
|
||||||
Requires the MM_CHANNEL_ID envvar to be set."""
|
|
||||||
name: str = "mm"
|
|
||||||
|
|
||||||
aliases = ["matchmaking", "matchmake", "lfg", "lookingforgroup"]
|
|
||||||
|
|
||||||
description: str = "Trova giocatori per una partita a qualcosa."
|
|
||||||
|
|
||||||
syntax: str = "[ (data) ] (nomegioco)\n[descrizione]"
|
|
||||||
|
|
||||||
tables = {MMEvent, MMDecision, MMResponse}
|
|
||||||
|
|
||||||
_cycle_duration = 10
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _main_keyboard(mmevent: MMEvent) -> typing.Optional[telegram.InlineKeyboardMarkup]:
|
|
||||||
if mmevent.state == "WAITING":
|
|
||||||
return telegram.InlineKeyboardMarkup([
|
|
||||||
[telegram.InlineKeyboardButton("🔵 Ci sarò!", callback_data=f"mm_{mmevent.mmid}_d_YES")],
|
|
||||||
[telegram.InlineKeyboardButton("⚫️ Forse...", callback_data=f"mm_{mmevent.mmid}_d_MAYBE")],
|
|
||||||
[telegram.InlineKeyboardButton("🔴 Non mi interessa.", callback_data=f"mm_{mmevent.mmid}_d_NO")]
|
|
||||||
])
|
|
||||||
elif mmevent.state == "DECISION":
|
|
||||||
return telegram.InlineKeyboardMarkup([
|
|
||||||
[telegram.InlineKeyboardButton("🔵 Ci sarò!", callback_data=f"mm_{mmevent.mmid}_d_YES"),
|
|
||||||
telegram.InlineKeyboardButton("🔴 Non mi interessa...", callback_data=f"mm_{mmevent.mmid}_d_NO")]
|
|
||||||
])
|
|
||||||
elif mmevent.state == "READY_CHECK":
|
|
||||||
return telegram.InlineKeyboardMarkup([
|
|
||||||
[telegram.InlineKeyboardButton("🚩 Avvia la partita", callback_data=f"mm_{mmevent.mmid}_start")]
|
|
||||||
])
|
|
||||||
elif mmevent.state == "STARTED":
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
raise ValueError(f"state is of an unknown value ({mmevent.state})")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _main_text(mmevent: MMEvent):
|
|
||||||
text = f"🌐 [{mmevent.datetime.strftime('%Y-%m-%d %H:%M')}] [b]{mmevent.title}[/b]\n"
|
|
||||||
if mmevent.description:
|
|
||||||
text += f"{mmevent.description}\n"
|
|
||||||
text += "\n"
|
|
||||||
if mmevent.state == "WAITING" or mmevent.state == "DECISION":
|
|
||||||
for mmdecision in sorted(mmevent.decisions, key=lambda mmd: mmd.royal.username):
|
|
||||||
mmdecision: "MMDecision"
|
|
||||||
if mmdecision.decision == "YES":
|
|
||||||
text += "🔵 "
|
|
||||||
elif mmdecision.decision == "MAYBE":
|
|
||||||
text += "⚫️ "
|
|
||||||
elif mmdecision.decision == "NO":
|
|
||||||
text += "🔴 "
|
|
||||||
else:
|
|
||||||
raise ValueError(f"decision is of an unknown value ({mmdecision.decision})")
|
|
||||||
text += f"{mmdecision.royal}\n"
|
|
||||||
elif mmevent.state == "READY_CHECK":
|
|
||||||
for mmresponse in sorted(mmevent.responses, key=lambda mmr: mmr.royal.username):
|
|
||||||
mmresponse: "MMResponse"
|
|
||||||
if mmresponse.response is None:
|
|
||||||
text += "❔ "
|
|
||||||
elif mmresponse.response == "YES":
|
|
||||||
text += "✅ "
|
|
||||||
elif mmresponse.response == "LATER":
|
|
||||||
text += "🕒 "
|
|
||||||
elif mmresponse.response == "NO":
|
|
||||||
text += "❌ "
|
|
||||||
else:
|
|
||||||
raise ValueError(f"response is of an unknown value ({mmresponse.response})")
|
|
||||||
text += f"{mmresponse.royal}\n"
|
|
||||||
elif mmevent.state == "STARTED":
|
|
||||||
for mmresponse in sorted(mmevent.responses, key=lambda mmr: mmr.response, reverse=True):
|
|
||||||
if mmresponse.response == "YES":
|
|
||||||
text += f"✅ {mmresponse.royal}\n"
|
|
||||||
elif mmresponse.response == "NO":
|
|
||||||
text += f"❌ {mmresponse.royal}\n"
|
|
||||||
return text
|
|
||||||
|
|
||||||
async def _run_mm(self, mmevent: MMEvent, session) -> None:
|
|
||||||
client: telegram.Bot = self.interface.bot.client
|
|
||||||
|
|
||||||
async def update_message() -> None:
|
|
||||||
try:
|
|
||||||
await self.interface.bot.safe_api_call(client.edit_message_text,
|
|
||||||
text=telegram_escape(self._main_text(mmevent)),
|
|
||||||
chat_id=-1001224004974,
|
|
||||||
message_id=mmevent.message_id,
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_web_page_preview=True,
|
|
||||||
reply_markup=self._main_keyboard(mmevent))
|
|
||||||
except telegram.error.BadRequest:
|
|
||||||
pass
|
|
||||||
|
|
||||||
decision_string = f"⚫️ Hai detto che forse parteciperai a [b]{mmevent.title}[/b]" \
|
|
||||||
f" alle [b]{mmevent.datetime.strftime('%H:%M')}[/b].\n" \
|
|
||||||
f"Confermi di volerci essere? (Metti sì anche se arrivi un po' in ritardo!)"
|
|
||||||
|
|
||||||
decision_keyboard = telegram.InlineKeyboardMarkup([
|
|
||||||
[telegram.InlineKeyboardButton("🔵 Ci sarò!", callback_data=f"mm_{mmevent.mmid}_d_YES"),
|
|
||||||
telegram.InlineKeyboardButton("🔴 Non mi interessa più.", callback_data=f"mm_{mmevent.mmid}_d_NO")]
|
|
||||||
])
|
|
||||||
|
|
||||||
async def decision_yes(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmdecision: MMDecision = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
if mmdecision is None:
|
|
||||||
mmdecision: MMDecision = self.interface.alchemy.MMDecision(royal=royal,
|
|
||||||
mmevent=mmevent,
|
|
||||||
decision="YES")
|
|
||||||
session.add(mmdecision)
|
|
||||||
else:
|
|
||||||
mmdecision.decision = "YES"
|
|
||||||
await asyncify(session.commit)
|
|
||||||
await update_message()
|
|
||||||
return "🔵 Hai detto che ci sarai!"
|
|
||||||
|
|
||||||
async def decision_maybe(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmdecision: MMDecision = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
if mmdecision is None:
|
|
||||||
mmdecision: MMDecision = self.interface.alchemy.MMDecision(royal=royal,
|
|
||||||
mmevent=mmevent,
|
|
||||||
decision="MAYBE")
|
|
||||||
session.add(mmdecision)
|
|
||||||
else:
|
|
||||||
mmdecision.decision = "MAYBE"
|
|
||||||
# Can't asyncify this
|
|
||||||
session.commit()
|
|
||||||
await update_message()
|
|
||||||
return f"⚫️ Hai detto che forse ci sarai." \
|
|
||||||
f"Rispondi al messaggio di conferma {self._cycle_duration} minuti prima dell'inizio!"
|
|
||||||
|
|
||||||
async def decision_no(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmdecision: MMDecision = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
if mmdecision is None:
|
|
||||||
mmdecision: MMDecision = self.interface.alchemy.MMDecision(royal=royal,
|
|
||||||
mmevent=mmevent,
|
|
||||||
decision="NO")
|
|
||||||
session.add(mmdecision)
|
|
||||||
else:
|
|
||||||
mmdecision.decision = "NO"
|
|
||||||
# Can't asyncify this
|
|
||||||
session.commit()
|
|
||||||
await update_message()
|
|
||||||
return "🔴 Hai detto che non ti interessa."
|
|
||||||
|
|
||||||
def response_string() -> str:
|
|
||||||
delay = (datetime.datetime.now() - mmevent.datetime).total_seconds()
|
|
||||||
if delay < 60:
|
|
||||||
return f"🚩 E' ora di [b]{mmevent.title}[/b]!\n" \
|
|
||||||
f"Sei pronto?"
|
|
||||||
return f"🕒 Sei in ritardo di [b]{int(delay / 60)} minuti[/b] per [b]{mmevent.title}[/b]...\n" \
|
|
||||||
f"Sei pronto?"
|
|
||||||
|
|
||||||
response_keyboard = telegram.InlineKeyboardMarkup([
|
|
||||||
[telegram.InlineKeyboardButton("✅ Ci sono!",
|
|
||||||
callback_data=f"mm_{mmevent.mmid}_r_YES")],
|
|
||||||
[telegram.InlineKeyboardButton("🕒 Aspettatemi ancora un po'!",
|
|
||||||
callback_data=f"mm_{mmevent.mmid}_r_LATER")],
|
|
||||||
[telegram.InlineKeyboardButton("❌ Non vengo più, mi spiace.",
|
|
||||||
callback_data=f"mm_{mmevent.mmid}_r_NO")]
|
|
||||||
])
|
|
||||||
|
|
||||||
async def response_yes(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmresponse: MMResponse = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
mmresponse.response = "YES"
|
|
||||||
# Can't asyncify this
|
|
||||||
session.commit()
|
|
||||||
await update_message()
|
|
||||||
return "✅ Sei pronto!"
|
|
||||||
|
|
||||||
def later_string(royal) -> str:
|
|
||||||
return f"🕒 {royal.username} ha chiesto di aspettare {self._cycle_duration} prima di iniziare la" \
|
|
||||||
f" partita.\n\n" \
|
|
||||||
f"Se vuoi iniziare la partita senza aspettarlo, premi Avvia partita su Royal Matchmaking!"
|
|
||||||
|
|
||||||
async def response_later(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmresponse: MMResponse = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
mmresponse.response = "LATER"
|
|
||||||
# Can't asyncify this
|
|
||||||
session.commit()
|
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
chat_id=mmevent.creator.telegram[0].tg_id,
|
|
||||||
text=telegram_escape(later_string(royal)),
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_webpage_preview=True)
|
|
||||||
await update_message()
|
|
||||||
return f"🕒 Hai chiesto agli altri di aspettarti {self._cycle_duration} minuti."
|
|
||||||
|
|
||||||
async def response_no(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
mmresponse: MMResponse = await asyncify(
|
|
||||||
session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent,
|
|
||||||
royal=royal).one_or_none)
|
|
||||||
mmresponse.response = "NO"
|
|
||||||
# Can't asyncify this
|
|
||||||
session.commit()
|
|
||||||
await update_message()
|
|
||||||
return "❌ Hai detto che non ci sarai."
|
|
||||||
|
|
||||||
def started_string():
|
|
||||||
text = f"🚩 L'evento [b]{mmevent.title}[/b] è iniziato!\n\n" \
|
|
||||||
f"Partecipano:\n"
|
|
||||||
for mmresponse in sorted(mmevent.responses, key=lambda mmr: mmr.response, reverse=True):
|
|
||||||
if mmresponse.response == "YES":
|
|
||||||
text += f"✅ {mmresponse.royal}\n"
|
|
||||||
elif mmresponse.response == "NO":
|
|
||||||
text += f"❌ {mmresponse.royal}\n"
|
|
||||||
return text
|
|
||||||
|
|
||||||
started_without_you_string = f"🚩 Non hai confermato la tua presenza in tempo e [b]{mmevent.title}[/b] è" \
|
|
||||||
f" iniziato senza di te.\n" \
|
|
||||||
f"Mi dispiace!"
|
|
||||||
|
|
||||||
async def start_event():
|
|
||||||
mmevent.state = "STARTED"
|
|
||||||
for mmresponse in mmevent.responses:
|
|
||||||
if mmresponse.response is None:
|
|
||||||
mmresponse.response = "NO"
|
|
||||||
if mmresponse.response == "LATER":
|
|
||||||
mmresponse.response = "NO"
|
|
||||||
|
|
||||||
if mmresponse.response == "YES":
|
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
chat_id=mmresponse.royal.telegram[0].tg_id,
|
|
||||||
text=telegram_escape(started_string()),
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_webpage_preview=True)
|
|
||||||
else:
|
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
chat_id=mmresponse.royal.telegram[0].tg_id,
|
|
||||||
text=telegram_escape(started_without_you_string),
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_webpage_preview=True)
|
|
||||||
await asyncify(session.commit)
|
|
||||||
await update_message()
|
|
||||||
|
|
||||||
async def start_key(data: CommandData):
|
|
||||||
royal = await data.get_author()
|
|
||||||
if royal == mmevent.creator:
|
|
||||||
await start_event()
|
|
||||||
|
|
||||||
if mmevent.state == "WAITING":
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_d_YES", decision_yes)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_d_MAYBE", decision_maybe)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_d_NO", decision_no)
|
|
||||||
await sleep_until(mmevent.datetime - datetime.timedelta(minutes=10))
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_d_YES")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_d_MAYBE")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_d_NO")
|
|
||||||
mmevent.state = "DECISION"
|
|
||||||
for mmdecision in mmevent.decisions:
|
|
||||||
mmdecision: MMDecision
|
|
||||||
if mmdecision.decision == "MAYBE":
|
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
chat_id=mmdecision.royal.telegram[0].tg_id,
|
|
||||||
text=telegram_escape(decision_string),
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_webpage_preview=True,
|
|
||||||
reply_markup=decision_keyboard)
|
|
||||||
await asyncify(session.commit)
|
|
||||||
await update_message()
|
|
||||||
|
|
||||||
if mmevent.state == "DECISION":
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_d_YES", decision_yes)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_d_NO", decision_no)
|
|
||||||
await sleep_until(mmevent.datetime)
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_d_YES")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_d_NO")
|
|
||||||
mmevent.state = "READY_CHECK"
|
|
||||||
for mmdecision in mmevent.decisions:
|
|
||||||
if mmdecision.decision == "MAYBE":
|
|
||||||
mmdecision.decision = "NO"
|
|
||||||
elif mmdecision.decision == "YES":
|
|
||||||
mmresponse: MMResponse = self.interface.alchemy.MMResponse(royal=mmdecision.royal, mmevent=mmevent)
|
|
||||||
session.add(mmresponse)
|
|
||||||
await asyncify(session.commit)
|
|
||||||
await update_message()
|
|
||||||
|
|
||||||
if mmevent.state == "READY_CHECK":
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_r_YES", response_yes)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_r_LATER", response_later)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_r_NO", response_no)
|
|
||||||
self.interface.register_keyboard_key(f"mm_{mmevent.mmid}_forcestart", start_key)
|
|
||||||
cycle = 0
|
|
||||||
while True:
|
|
||||||
for mmresponse in mmevent.responses:
|
|
||||||
# Send messages
|
|
||||||
if mmresponse.response is None:
|
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
chat_id=mmresponse.royal.telegram[0].tg_id,
|
|
||||||
text=telegram_escape(response_string()),
|
|
||||||
parse_mode="HTML",
|
|
||||||
disable_webpage_preview=True,
|
|
||||||
reply_markup=response_keyboard)
|
|
||||||
# Wait
|
|
||||||
await asyncio.sleep(60 * self._cycle_duration)
|
|
||||||
# Advance cycle
|
|
||||||
for mmresponse in mmevent.responses:
|
|
||||||
if mmresponse.response is None:
|
|
||||||
mmresponse.response = "NO"
|
|
||||||
if mmresponse.response == "LATER":
|
|
||||||
mmresponse.response = None
|
|
||||||
# Check if the event can start
|
|
||||||
for mmresponse in mmevent.responses:
|
|
||||||
if mmresponse.response is None:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
cycle += 1
|
|
||||||
|
|
||||||
await start_event()
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_r_YES")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_r_LATER")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_r_NO")
|
|
||||||
self.interface.unregister_keyboard_key(f"mm_{mmevent.mmid}_forcestart")
|
|
||||||
|
|
||||||
def __init__(self, interface):
|
|
||||||
super().__init__(interface)
|
|
||||||
# if self.interface.name != "telegram":
|
|
||||||
# return
|
|
||||||
# log.debug("Loading pending MMEvents from the database")
|
|
||||||
# session = interface.alchemy.Session()
|
|
||||||
# mmevents = session.query(self.interface.alchemy.MMEvent) \
|
|
||||||
# .filter(self.interface.alchemy.MMEvent.datetime > datetime.datetime.now()) \
|
|
||||||
# .all()
|
|
||||||
# log.info(f"Found {len(mmevents)} pending MMEvents")
|
|
||||||
# for mmevent in mmevents:
|
|
||||||
# session = interface.alchemy.Session()
|
|
||||||
# new_mmevent = session.query(MMEvent).get(mmevent.mmid)
|
|
||||||
# interface.loop.create_task(self._run_mm(new_mmevent, session, close_at_end=True))
|
|
||||||
# session.close()
|
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
|
||||||
raise UnsupportedError("MmCommand è attualmente disabilitato per via di bug introdotti da cambiamenti nella"
|
|
||||||
" gestione del database del bot.")
|
|
||||||
# if self.interface.name != "telegram":
|
|
||||||
# raise UnsupportedError("mm is supported only on Telegram")
|
|
||||||
# client: telegram.Bot = self.interface.bot.client
|
|
||||||
# creator = await data.get_author(error_if_none=True)
|
|
||||||
# try:
|
|
||||||
# timestring, title, description = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
|
||||||
# except InvalidInputError:
|
|
||||||
# timestring, title, description = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*\n?\s*(.+)?\s*", re.DOTALL)
|
|
||||||
# try:
|
|
||||||
# dt: typing.Optional[datetime.datetime] = dateparser.parse(timestring, settings={
|
|
||||||
# "PREFER_DATES_FROM": "future"
|
|
||||||
# })
|
|
||||||
# except OverflowError:
|
|
||||||
# dt = None
|
|
||||||
# if dt is None:
|
|
||||||
# await data.reply("⚠️ La data che hai specificato non è valida.")
|
|
||||||
# return
|
|
||||||
# if dt <= datetime.datetime.now():
|
|
||||||
# await data.reply("⚠️ La data che hai specificato è nel passato.")
|
|
||||||
# return
|
|
||||||
# mmevent: MMEvent = self.interface.alchemy.MMEvent(creator=creator,
|
|
||||||
# datetime=dt,
|
|
||||||
# title=title,
|
|
||||||
# description=description,
|
|
||||||
# state="WAITING")
|
|
||||||
# data.session.add(mmevent)
|
|
||||||
# await asyncify(data.session.commit)
|
|
||||||
#
|
|
||||||
# message: telegram.Message = await self.interface.bot.safe_api_call(client.send_message,
|
|
||||||
# chat_id=-1001287169422,
|
|
||||||
# text=telegram_escape(
|
|
||||||
# self._main_text(mmevent)),
|
|
||||||
# parse_mode="HTML",
|
|
||||||
# disable_webpage_preview=True,
|
|
||||||
# reply_markup=self._main_keyboard(mmevent))
|
|
||||||
#
|
|
||||||
# mmevent.message_id = message.message_id
|
|
||||||
# # Can't asyncify this
|
|
||||||
# await asyncify(data.session.commit)
|
|
||||||
#
|
|
||||||
# await self._run_mm(mmevent, data.session)
|
|
|
@ -13,7 +13,7 @@ class Mp3Command(Command):
|
||||||
|
|
||||||
description: str = "Scarica un video con youtube-dl e invialo in chat."
|
description: str = "Scarica un video con youtube-dl e invialo in chat."
|
||||||
|
|
||||||
syntax = "(ytdlstring)"
|
syntax = "{ytdlstring}"
|
||||||
|
|
||||||
ytdl_args = {
|
ytdl_args = {
|
||||||
"format": "bestaudio",
|
"format": "bestaudio",
|
||||||
|
|
|
@ -15,7 +15,7 @@ class PlayCommand(Command):
|
||||||
|
|
||||||
description: str = "Aggiunge un url alla coda della chat vocale."
|
description: str = "Aggiunge un url alla coda della chat vocale."
|
||||||
|
|
||||||
syntax = "[ [guild] ] (url)"
|
syntax = "[ [guild] ] {url}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _legacy_play_handler(bot: "DiscordBot", guild_name: typing.Optional[str], url: str):
|
async def _legacy_play_handler(bot: "DiscordBot", guild_name: typing.Optional[str], url: str):
|
||||||
|
|
|
@ -12,7 +12,7 @@ class PlaymodeCommand(Command):
|
||||||
|
|
||||||
description: str = "Cambia modalità di riproduzione per la chat vocale."
|
description: str = "Cambia modalità di riproduzione per la chat vocale."
|
||||||
|
|
||||||
syntax = "[ [guild] ] (mode)"
|
syntax = "[ [guild] ] {mode}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _legacy_playmode_handler(bot: "DiscordBot", guild_name: typing.Optional[str], mode_name: str):
|
async def _legacy_playmode_handler(bot: "DiscordBot", guild_name: typing.Optional[str], mode_name: str):
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ReminderCommand(Command):
|
||||||
|
|
||||||
description: str = "Ti ricorda di fare qualcosa dopo un po' di tempo."
|
description: str = "Ti ricorda di fare qualcosa dopo un po' di tempo."
|
||||||
|
|
||||||
syntax: str = "[ (data) ] (messaggio)"
|
syntax: str = "[ {data} ] {messaggio}"
|
||||||
|
|
||||||
tables = {Reminder}
|
tables = {Reminder}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class ReminderCommand(Command):
|
||||||
async def _remind(self, reminder):
|
async def _remind(self, reminder):
|
||||||
await sleep_until(reminder.datetime)
|
await sleep_until(reminder.datetime)
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
chat_id: int = pickle.loads(reminder.interface_data)
|
chat_id: int = pickle.loads(reminder.raw_interface_data)
|
||||||
bot: telegram.Bot = self.interface.bot.client
|
bot: telegram.Bot = self.interface.bot.client
|
||||||
await asyncify(bot.send_message,
|
await asyncify(bot.send_message,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
|
@ -45,7 +45,7 @@ class ReminderCommand(Command):
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_web_page_preview=True)
|
disable_web_page_preview=True)
|
||||||
elif self.interface.name == "discord":
|
elif self.interface.name == "discord":
|
||||||
channel_id: int = pickle.loads(reminder.interface_data)
|
channel_id: int = pickle.loads(reminder.raw_interface_data)
|
||||||
bot: discord.Client = self.interface.bot.client
|
bot: discord.Client = self.interface.bot.client
|
||||||
channel = bot.get_channel(channel_id)
|
channel = bot.get_channel(channel_id)
|
||||||
await channel.send(discord_escape(f"❗️ {reminder.message}"))
|
await channel.send(discord_escape(f"❗️ {reminder.message}"))
|
||||||
|
|
|
@ -11,7 +11,7 @@ class ShipCommand(Command):
|
||||||
|
|
||||||
description: str = "Crea una ship tra due nomi."
|
description: str = "Crea una ship tra due nomi."
|
||||||
|
|
||||||
syntax = "(nomeuno) (nomedue)"
|
syntax = "{nomeuno} {nomedue}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
name_one = args[0]
|
name_one = args[0]
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SoundcloudCommand(Command):
|
||||||
|
|
||||||
description: str = "Cerca una canzone su Soundcloud e la aggiunge alla coda della chat vocale."
|
description: str = "Cerca una canzone su Soundcloud e la aggiunge alla coda della chat vocale."
|
||||||
|
|
||||||
syntax = "[ [guild] ] (url)"
|
syntax = "[ [guild] ] {url}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _legacy_soundcloud_handler(bot: "DiscordBot", guild_name: typing.Optional[str], search: str):
|
async def _legacy_soundcloud_handler(bot: "DiscordBot", guild_name: typing.Optional[str], search: str):
|
||||||
|
|
|
@ -15,7 +15,7 @@ class YoutubeCommand(Command):
|
||||||
|
|
||||||
description: str = "Cerca un video su YouTube e lo aggiunge alla coda della chat vocale."
|
description: str = "Cerca un video su YouTube e lo aggiunge alla coda della chat vocale."
|
||||||
|
|
||||||
syntax = "[ [guild] ] (url)"
|
syntax = "[ [guild] ] {url}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def _legacy_youtube_handler(cls, bot: "DiscordBot", guild_name: typing.Optional[str], search: str):
|
async def _legacy_youtube_handler(cls, bot: "DiscordBot", guild_name: typing.Optional[str], search: str):
|
||||||
|
|
|
@ -10,7 +10,6 @@ from .wikirevisions import WikiRevision
|
||||||
from .bios import Bio
|
from .bios import Bio
|
||||||
from .reminders import Reminder
|
from .reminders import Reminder
|
||||||
from .triviascores import TriviaScore
|
from .triviascores import TriviaScore
|
||||||
from .mmdecisions import MMDecision
|
|
||||||
from .mmevents import MMEvent
|
from .mmevents import MMEvent
|
||||||
from .mmresponse import MMResponse
|
from .mmresponse import MMResponse
|
||||||
|
|
||||||
|
@ -26,7 +25,6 @@ available_tables = [
|
||||||
Bio,
|
Bio,
|
||||||
Reminder,
|
Reminder,
|
||||||
TriviaScore,
|
TriviaScore,
|
||||||
MMDecision,
|
|
||||||
MMEvent,
|
MMEvent,
|
||||||
MMResponse,
|
MMResponse,
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
from sqlalchemy import Column, \
|
|
||||||
Integer, \
|
|
||||||
String, \
|
|
||||||
ForeignKey
|
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
|
||||||
|
|
||||||
|
|
||||||
class MMDecision:
|
|
||||||
__tablename__ = "mmdecisions"
|
|
||||||
|
|
||||||
@declared_attr
|
|
||||||
def royal_id(self):
|
|
||||||
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
|
|
||||||
|
|
||||||
@declared_attr
|
|
||||||
def royal(self):
|
|
||||||
return relationship("User", backref="mmdecisions_taken")
|
|
||||||
|
|
||||||
@declared_attr
|
|
||||||
def mmevent_id(self):
|
|
||||||
return Column(Integer, ForeignKey("mmevents.mmid"), primary_key=True)
|
|
||||||
|
|
||||||
@declared_attr
|
|
||||||
def mmevent(self):
|
|
||||||
return relationship("MMEvent", backref="decisions")
|
|
||||||
|
|
||||||
@declared_attr
|
|
||||||
def decision(self):
|
|
||||||
# Valid decisions are YES, MAYBE or NO
|
|
||||||
return Column(String, nullable=False)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"<MMDecision of {self.royal}: {self.decision}>"
|
|
|
@ -1,10 +1,5 @@
|
||||||
from sqlalchemy import Column, \
|
import pickle
|
||||||
Integer, \
|
from sqlalchemy import *
|
||||||
DateTime, \
|
|
||||||
String, \
|
|
||||||
Text, \
|
|
||||||
ForeignKey, \
|
|
||||||
BigInteger
|
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
|
||||||
|
@ -37,14 +32,21 @@ class MMEvent:
|
||||||
return Column(Text, nullable=False, default="")
|
return Column(Text, nullable=False, default="")
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def state(self):
|
def interface(self):
|
||||||
# Valid states are WAITING, DECISION, READY_CHECK, STARTED
|
return Column(String, nullable=False)
|
||||||
return Column(String, nullable=False, default="WAITING")
|
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def message_id(self):
|
def raw_interface_data(self):
|
||||||
return Column(BigInteger)
|
# The default is a pickled None
|
||||||
|
return Column(Binary, nullable=False, default=b'\x80\x03N.')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def interface_data(self):
|
||||||
|
return pickle.loads(self.raw_interface_data)
|
||||||
|
|
||||||
|
@interface_data.setter
|
||||||
|
def interface_data(self, value):
|
||||||
|
self.raw_interface_data = pickle.dumps(value)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<MMEvent {self.mmid}: {self.title}>"
|
return f"<MMEvent {self.mmid}: {self.title}>"
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
from sqlalchemy import Column, \
|
from sqlalchemy import *
|
||||||
Integer, \
|
|
||||||
String, \
|
|
||||||
ForeignKey
|
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
from ..utils import MMChoice
|
||||||
|
|
||||||
|
|
||||||
class MMResponse:
|
class MMResponse:
|
||||||
|
@ -26,9 +24,8 @@ class MMResponse:
|
||||||
return relationship("MMEvent", backref="responses")
|
return relationship("MMEvent", backref="responses")
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def response(self):
|
def choice(self):
|
||||||
# Valid decisions are YES, LATER or NO
|
return Column(Enum(MMChoice), nullable=False)
|
||||||
return Column(String)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<MMResponse of {self.royal}: {self.response}>"
|
return f"<MMResponse of {self.royal}: {self.choice}>"
|
||||||
|
|
4
royalnet/packs/royal/utils/__init__.py
Normal file
4
royalnet/packs/royal/utils/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from .mmchoice import MMChoice
|
||||||
|
from .mminterfacedata import MMInterfaceData, MMInterfaceDataTelegram
|
||||||
|
|
||||||
|
__all__ = ["MMChoice", "MMInterfaceData", "MMInterfaceDataTelegram"]
|
12
royalnet/packs/royal/utils/mmchoice.py
Normal file
12
royalnet/packs/royal/utils/mmchoice.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import enum
|
||||||
|
|
||||||
|
|
||||||
|
class MMChoice(enum.Enum):
|
||||||
|
YES = "🔵"
|
||||||
|
MAYBE = "❔"
|
||||||
|
LATE_SHORT = "🕐"
|
||||||
|
LATE_MEDIUM = "🕒"
|
||||||
|
LATE_LONG = "🕗"
|
||||||
|
NO_TIME = "🔴"
|
||||||
|
NO_INTEREST = "❌"
|
||||||
|
NO_TECH = "❗️"
|
10
royalnet/packs/royal/utils/mminterfacedata.py
Normal file
10
royalnet/packs/royal/utils/mminterfacedata.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class MMInterfaceData:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MMInterfaceDataTelegram(MMInterfaceData):
|
||||||
|
def __init__(self, chat_id: int, message_id: int):
|
||||||
|
super().__init__()
|
||||||
|
self.chat_id = chat_id
|
||||||
|
self.message_id = message_id
|
Loading…
Reference in a new issue