diff --git a/royalnet/bots/discord.py b/royalnet/bots/discord.py index d1637c49..0e3423e5 100644 --- a/royalnet/bots/discord.py +++ b/royalnet/bots/discord.py @@ -132,6 +132,12 @@ class DiscordBot(GenericBot): error_message += '\n'.join(e.args) await data.reply(error_message) + async def on_connect(cli): + log.debug("Connected to Discord") + + async def on_disconnect(cli): + log.error("Disconnected from Discord!") + async def on_ready(cli) -> None: log.debug("Connection successful, client is ready") await cli.change_presence(status=discord.Status.online) @@ -196,7 +202,6 @@ class DiscordBot(GenericBot): await self.client.login(token) log.info(f"Connecting to Discord") await self.client.connect() - # TODO: how to stop? async def add_to_music_data(self, dfiles: typing.List[YtdlDiscord], guild: discord.Guild): """Add a list of :py:class:`royalnet.audio.YtdlDiscord` to the corresponding music_data object.""" diff --git a/royalnet/bots/telegram.py b/royalnet/bots/telegram.py index 3cb2b9f1..847fe7b0 100644 --- a/royalnet/bots/telegram.py +++ b/royalnet/bots/telegram.py @@ -75,7 +75,7 @@ class TelegramBot(GenericBot): if error_if_none: raise CommandError("No command caller for this message") return None - query = data.interface.session.query(self.master_table) + query = data.session.query(self.master_table) for link in self.identity_chain: query = query.join(link.mapper.class_) query = query.filter(self.identity_column == user.id) @@ -90,7 +90,7 @@ class TelegramBot(GenericBot): for key in keyboard: press_id = uuid.uuid4() tg_keyboard.append([telegram.InlineKeyboardButton(key, callback_data=str(press_id))]) - data.interface.register_keyboard_key(key_name=str(press_id), callback=keyboard[key]) + data._interface.register_keyboard_key(key_name=str(press_id), callback=keyboard[key]) await TelegramBot.safe_api_call(data.update.effective_chat.send_message, telegram_escape(text), reply_markup=telegram.InlineKeyboardMarkup(tg_keyboard), @@ -109,8 +109,7 @@ class TelegramBot(GenericBot): try: return await asyncify(f, *args, **kwargs) except telegram.error.TimedOut as error: - log.debug(f"Timed out during {f.__qualname__} (retrying in 15s): {error}") - await asyncio.sleep(15) + log.debug(f"Timed out during {f.__qualname__} (retrying immediatly): {error}") continue except telegram.error.NetworkError as error: log.debug(f"Network error during {f.__qualname__} (skipping): {error}") @@ -179,6 +178,8 @@ class TelegramBot(GenericBot): error_message = f"🦀 [b]{e.__class__.__name__}[/b] 🦀\n" error_message += '\n'.join(e.args) await data.reply(error_message) + if __debug__: + raise async def _handle_callback_query(self, update: telegram.Update): query: telegram.CallbackQuery = update.callback_query @@ -204,7 +205,10 @@ class TelegramBot(GenericBot): error_text = f"⛔️ {e.__class__.__name__}\n" error_text += '\n'.join(e.args) await self.safe_api_call(query.answer, text=error_text) - return + if __debug__: + raise + else: + return else: await self.safe_api_call(query.answer, text=response) diff --git a/royalnet/packs/royal/commands/cv.py b/royalnet/packs/royal/commands/cv.py index e3df914b..d15dad37 100644 --- a/royalnet/packs/royal/commands/cv.py +++ b/royalnet/packs/royal/commands/cv.py @@ -61,11 +61,11 @@ class CvCommand(Command): elif member.status == discord.Status.online: message += "🔵 " elif member.status == discord.Status.idle: - message += "⚫️ " + message += "⚫ " elif member.status == discord.Status.dnd: message += "🔴 " elif member.status == discord.Status.offline: - message += "⚪️ " + message += "⚪ " # Voice if channel != 0: # Voice status @@ -75,15 +75,15 @@ class CvCommand(Command): message += "🔇 " elif member.voice.self_mute or member.voice.mute: message += "🔈 " - elif member.voice.self_video: - message += "📺 " + elif member.voice.self_video or member.voice.self_stream: + message += "🖥 " else: message += "🔊 " # Nickname - if member.nick is not None: - message += f"[i]{member.nick}[/i]" - else: - message += member.name + # if member.nick is not None: + # message += f"[i]{member.nick}[/i]" + # else: + message += member.name # Game or stream if member.activity is not None: if member.activity.type == discord.ActivityType.playing: diff --git a/royalnet/packs/royal/commands/mm.py b/royalnet/packs/royal/commands/mm.py index dcf78fd4..a2ea2252 100644 --- a/royalnet/packs/royal/commands/mm.py +++ b/royalnet/packs/royal/commands/mm.py @@ -18,7 +18,7 @@ class MmCommand(Command): Requires the MM_CHANNEL_ID envvar to be set.""" name: str = "mm" - aliases = ["matchmaking", "matchmake"] + aliases = ["matchmaking", "matchmake", "lfg", "lookingforgroup"] description: str = "Trova giocatori per una partita a qualcosa." @@ -117,33 +117,33 @@ class MmCommand(Command): async def decision_yes(data: CommandData): royal = await data.get_author() mmdecision: MMDecision = await asyncify( - data.session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent, + 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") - data.session.add(mmdecision) + session.add(mmdecision) else: mmdecision.decision = "YES" - await asyncify(data.session.commit) + 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( - data.session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent, + 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") - data.session.add(mmdecision) + session.add(mmdecision) else: mmdecision.decision = "MAYBE" # Can't asyncify this - data.session.commit() + 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!" @@ -151,17 +151,17 @@ class MmCommand(Command): async def decision_no(data: CommandData): royal = await data.get_author() mmdecision: MMDecision = await asyncify( - data.session.query(self.interface.alchemy.MMDecision).filter_by(mmevent=mmevent, + 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") - data.session.add(mmdecision) + session.add(mmdecision) else: mmdecision.decision = "NO" # Can't asyncify this - data.session.commit() + session.commit() await update_message() return "🔴 Hai detto che non ti interessa." @@ -185,11 +185,11 @@ class MmCommand(Command): async def response_yes(data: CommandData): royal = await data.get_author() mmresponse: MMResponse = await asyncify( - data.session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, + session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, royal=royal).one_or_none) mmresponse.response = "YES" # Can't asyncify this - data.session.commit() + session.commit() await update_message() return "✅ Sei pronto!" @@ -201,11 +201,11 @@ class MmCommand(Command): async def response_later(data: CommandData): royal = await data.get_author() mmresponse: MMResponse = await asyncify( - data.session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, + session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, royal=royal).one_or_none) mmresponse.response = "LATER" # Can't asyncify this - data.session.commit() + 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)), @@ -217,11 +217,11 @@ class MmCommand(Command): async def response_no(data: CommandData): royal = await data.get_author() mmresponse: MMResponse = await asyncify( - data.session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, + session.query(self.interface.alchemy.MMResponse).filter_by(mmevent=mmevent, royal=royal).one_or_none) mmresponse.response = "NO" # Can't asyncify this - data.session.commit() + session.commit() await update_message() return "❌ Hai detto che non ci sarai." @@ -344,57 +344,61 @@ class MmCommand(Command): 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 = self.interface.alchemy.Session() - interface.loop.create_task(self._run_mm(mmevent, session)) + # 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: - 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=-1001224004974, - 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) + 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)