diff --git a/fifo/fifo.py b/fifo/fifo.py index 89a9e83..d152609 100644 --- a/fifo/fifo.py +++ b/fifo/fifo.py @@ -171,6 +171,7 @@ class FIFO(commands.Cog): id=_assemble_job_id(task.name, task.guild_id), trigger=combined_trigger_, name=task.name, + replace_existing=True, ) async def _resume_job(self, task: Task): diff --git a/fifo/task.py b/fifo/task.py index 6f667b9..1d325a4 100644 --- a/fifo/task.py +++ b/fifo/task.py @@ -3,12 +3,12 @@ from datetime import datetime, timedelta from typing import Dict, List, Optional, Tuple, Union import discord +import pytz from apscheduler.triggers.base import BaseTrigger from apscheduler.triggers.combining import OrTrigger from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.interval import IntervalTrigger from discord.utils import time_snowflake -import pytz from redbot.core import Config, commands from redbot.core.bot import Red @@ -56,10 +56,67 @@ def parse_triggers(data: Union[Dict, None]): return trigger -class FakeMessage: - def __init__(self, message: discord.Message): +# class FakeMessage: +# def __init__(self, message: discord.Message): +# d = {k: getattr(message, k, None) for k in dir(message)} +# self.__dict__.update(**d) + + +# Potential FakeMessage subclass of Message +# class DeleteSlots(type): +# @classmethod +# def __prepare__(metacls, name, bases): +# """Borrowed a bit from https://stackoverflow.com/q/56579348""" +# super_prepared = super().__prepare__(name, bases) +# print(super_prepared) +# return super_prepared + + +class FakeMessage(discord.Message): + def __init__(self, *args, message: discord.Message, **kwargs): d = {k: getattr(message, k, None) for k in dir(message)} - self.__dict__.update(**d) + for k, v in d.items(): + if k.lower().startswith("_handle"): + continue + try: + # log.debug(f"{k=} {v=}") + setattr(self, k, v) + except TypeError: + # log.exception("This is fine") + pass + except AttributeError: + # log.exception("This is fine") + pass + + self.id = time_snowflake(datetime.utcnow(), high=False) # Pretend to be now + self.type = discord.MessageType.default + + def process_the_rest( + self, + author: discord.Member, + channel: discord.TextChannel, + content, + ): + # self.content = content + # log.debug(self.content) + self._handle_content(content) + # log.debug(self.content) + + self.mention_everyone = "@everyone" in self.content or "@here" in self.content + + # for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'): + # try: + # getattr(self, '_handle_%s' % handler)(data[handler]) + # except KeyError: + # continue + self.author = author + # self._handle_author(author._user._to_minimal_user_json()) + # self._handle_member(author) + self._rebind_channel_reference(channel) + self._handle_mention_roles(self.raw_role_mentions) + self._handle_mentions(self.raw_mentions) + + # self.__dict__.update(**d) def neuter_message(message: FakeMessage): @@ -270,7 +327,7 @@ class Task: f"Could not execute Task[{self.name}] due to missing channel: {self.channel_id}" ) return False - author: discord.User = guild.get_member(self.author_id) + author: discord.Member = guild.get_member(self.author_id) if author is None: log.warning( f"Could not execute Task[{self.name}] due to missing author: {self.author_id}" @@ -296,22 +353,27 @@ class Task: return False actual_message = actual_message[0] - message = FakeMessage(actual_message) - # message = FakeMessage2 - message.author = author - message.guild = guild # Just in case we got desperate, see above - message.channel = channel - message.id = time_snowflake(datetime.utcnow(), high=False) # Pretend to be now - message = neuter_message(message) + # message._handle_author(author) # Option when message is subclass + # message._state = self.bot._get_state() + # Time to set the relevant attributes + # message.author = author + # Don't need guild with subclass, guild is just channel.guild + # message.guild = guild # Just in case we got desperate, see above + # message.channel = channel # absolutely weird that this takes a message object instead of guild - prefixes = await self.bot.get_prefix(message) + prefixes = await self.bot.get_prefix(actual_message) if isinstance(prefixes, str): prefix = prefixes else: prefix = prefixes[0] - message.content = f"{prefix}{self.get_command_str()}" + new_content = f"{prefix}{self.get_command_str()}" + # log.debug(f"{new_content=}") + + message = FakeMessage(message=actual_message) + message = neuter_message(message) + message.process_the_rest(author=author, channel=channel, content=new_content) if ( not message.guild @@ -319,7 +381,10 @@ class Task: or not message.content or message.content == prefix ): - log.warning(f"Could not execute Task[{self.name}] due to message problem: {message}") + log.warning( + f"Could not execute Task[{self.name}] due to message problem: " + f"{message.guild=}, {message.author=}, {message.content=}" + ) return False new_ctx: commands.Context = await self.bot.get_context(message)