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

Some more progress on mm

This commit is contained in:
Steffo 2019-10-26 14:35:05 +02:00
parent add6170183
commit d4e2b2b8d8
3 changed files with 108 additions and 26 deletions

View file

@ -11,7 +11,7 @@ from .videochannel import VideochannelCommand
from .dnditem import DnditemCommand
from .dndspell import DndspellCommand
from .trivia import TriviaCommand
from .matchmaking import MmCommand
from .matchmaking import MatchmakingCommand
from .pause import PauseCommand
from .play import PlayCommand
from .playmode import PlaymodeCommand
@ -37,7 +37,7 @@ available_commands = [
DnditemCommand,
DndspellCommand,
TriviaCommand,
MmCommand,
MatchmakingCommand,
PauseCommand,
PlayCommand,
PlaymodeCommand,

View file

@ -1,13 +1,13 @@
import pickle
import datetime
from telegram import Bot as PTBBot
from telegram import Message as PTBMessage
from telegram.error import BadRequest
from telegram.error import BadRequest, Unauthorized
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 royalnet.utils import telegram_escape, asyncify, sleep_until
from ..tables import MMEvent, MMResponse, User, Telegram
from ..utils import MMChoice, MMInterfaceData, MMInterfaceDataTelegram
@ -25,14 +25,27 @@ class MatchmakingCommand(Command):
def __init__(self, interface: CommandInterface):
super().__init__(interface)
# Find all relevant MMEvents and run them
...
session = self.interface.Session()
mmevents = await asyncify(
session.query(self.alchemy.MMEvent)
.filter(self.alchemy.MMEvent.interface == self.interface.name,
self.alchemy.MMEvent.datetime > datetime.datetime.now())
.all
)
for mmevent in mmevents:
self._run_mmevent(mmevent.mmid)
async def run(self, args: CommandArgs, data: CommandData) -> None:
# Create a new MMEvent and run it
if self.interface.name != "telegram":
raise UnsupportedError(f"{self.interface.prefix}matchmaking funziona solo su Telegram. Per ora.")
author = await data.get_author(error_if_none=True)
...
_mm_chat_id = -1001224004974
_mm_error_chat_id = -1001153723135
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:
@ -40,7 +53,7 @@ class MatchmakingCommand(Command):
text += "\n"
for response in mmevent.responses:
response: MMResponse
text += f"{response.choice.value} {response.royal}\n"
text += f"{response.choice.value} {response.user}\n"
return text
def _gen_telegram_keyboard(self, mmevent: MMEvent):
@ -48,7 +61,8 @@ class MatchmakingCommand(Command):
[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_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")],
@ -72,17 +86,33 @@ class MatchmakingCommand(Command):
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)
mmresponse: MMResponse = await asyncify(
data.session.query(self.alchemy.MMResponse).filter_by(user=author, mmevent=mmevent).one_or_none)
if mmresponse is None:
mmresponse = self.alchemy.MMResponse(royal=author, mmevent=mmevent, choice=choice)
mmresponse = self.alchemy.MMResponse(user=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
def _gen_event_start_message(self, mmevent: MMEvent):
text = f"🚩 L'evento [b]{mmevent.title}[/b] è iniziato!\n\n" \
f"Partecipano:\n"
for mmresponse in sorted(mmevent.responses, key=lambda mmr: mmr.user.username):
if mmresponse.response == "YES":
text += f"{mmresponse.user}\n"
elif mmresponse.response == "NO":
text += f"{mmresponse.user}\n"
return text
def _gen_unauth_message(self, user: User):
return f"⚠️ Non sono autorizzato a mandare messaggi a [b]{user.username}[/b]!\n" \
f"{user.telegram.mention()}, apri una chat privata con me e mandami un messaggio!"
async def _run_mmevent(self, mmid: int):
"""Run a MMEvent."""
# Open a new Alchemy Session
@ -91,6 +121,9 @@ class MatchmakingCommand(Command):
mmevent: MMEvent = await asyncify(session.query(self.alchemy.MMEvent).get, mmid)
if mmevent is None:
raise ValueError("Invalid mmid.")
# Ensure the MMEvent hasn't already started
if mmevent.datetime <= datetime.datetime.now():
raise ValueError("MMEvent has already started.")
# Ensure the MMEvent interface matches the current one
if mmevent.interface != self.interface.name:
raise ValueError("Invalid interface.")
@ -103,27 +136,76 @@ class MatchmakingCommand(Command):
# 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)),
text=telegram_escape(
self._gen_mm_message(mmevent)),
parse_mode="HTML",
disable_webpage_preview=True,
reply_markup=self._gen_telegram_keyboard(mmevent.mmid))
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)
mmevent.interface_data = MMInterfaceDataTelegram(chat_id=self._mm_chat_id,
message_id=message.message_id)
await asyncify(session.commit)
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))
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
...
await sleep_until(mmevent.datetime)
# Notify the positive answers of the event start
if self.interface.name == "telegram":
bot: TelegramBot = self.interface.bot
client: PTBBot = bot.client
for response in mmevent.responses:
if response.choice == MMChoice.NO_INTEREST or response.choice == MMChoice.NO_TIME:
return
try:
await self.interface.bot.safe_api_call(client.send_message,
chat_id=response.user.telegram.tg_id,
text=telegram_escape(self._gen_event_start_message(mmevent)),
parse_mode="HTML",
disable_webpage_preview=True)
except Unauthorized:
await self.interface.bot.safe_api_call(client.send_message,
chat_id=self._mm_error_chat_id,
text=telegram_escape(
self._gen_unauth_message(response.user)),
parse_mode="HTML",
disable_webpage_preview=True)
else:
raise UnsupportedError()
# Delete the event message
if self.interface.name == "telegram":
await self.interface.bot.safe_api_call(client.delete_message,
chat_id=mmevent.interface_data.chat_id,
message_id=mmevent.interface_data.message_id,
parse_mode="HTML",
disable_webpage_preview=True)
# The end!
await asyncify(session.close)

View file

@ -8,11 +8,11 @@ class MMResponse:
__tablename__ = "mmresponse"
@declared_attr
def royal_id(self):
def user_id(self):
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
@declared_attr
def royal(self):
def user(self):
return relationship("User", backref="mmresponses_given")
@declared_attr
@ -28,4 +28,4 @@ class MMResponse:
return Column(Enum(MMChoice), nullable=False)
def __repr__(self):
return f"<MMResponse of {self.royal}: {self.choice}>"
return f"<MMResponse of {self.user}: {self.choice}>"