FakeMessage is subclass and the implications

pull/168/head
bobloy 4 years ago
parent 3f997fa804
commit 6233db2272

@ -171,6 +171,7 @@ class FIFO(commands.Cog):
id=_assemble_job_id(task.name, task.guild_id), id=_assemble_job_id(task.name, task.guild_id),
trigger=combined_trigger_, trigger=combined_trigger_,
name=task.name, name=task.name,
replace_existing=True,
) )
async def _resume_job(self, task: Task): async def _resume_job(self, task: Task):

@ -3,12 +3,12 @@ from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple, Union from typing import Dict, List, Optional, Tuple, Union
import discord import discord
import pytz
from apscheduler.triggers.base import BaseTrigger from apscheduler.triggers.base import BaseTrigger
from apscheduler.triggers.combining import OrTrigger from apscheduler.triggers.combining import OrTrigger
from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.cron import CronTrigger
from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.interval import IntervalTrigger
from discord.utils import time_snowflake from discord.utils import time_snowflake
import pytz
from redbot.core import Config, commands from redbot.core import Config, commands
from redbot.core.bot import Red from redbot.core.bot import Red
@ -56,10 +56,67 @@ def parse_triggers(data: Union[Dict, None]):
return trigger return trigger
class FakeMessage: # class FakeMessage:
def __init__(self, message: discord.Message): # 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)} 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): 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}" f"Could not execute Task[{self.name}] due to missing channel: {self.channel_id}"
) )
return False return False
author: discord.User = guild.get_member(self.author_id) author: discord.Member = guild.get_member(self.author_id)
if author is None: if author is None:
log.warning( log.warning(
f"Could not execute Task[{self.name}] due to missing author: {self.author_id}" f"Could not execute Task[{self.name}] due to missing author: {self.author_id}"
@ -296,22 +353,27 @@ class Task:
return False return False
actual_message = actual_message[0] actual_message = actual_message[0]
message = FakeMessage(actual_message) # message._handle_author(author) # Option when message is subclass
# message = FakeMessage2 # message._state = self.bot._get_state()
message.author = author # Time to set the relevant attributes
message.guild = guild # Just in case we got desperate, see above # message.author = author
message.channel = channel # Don't need guild with subclass, guild is just channel.guild
message.id = time_snowflake(datetime.utcnow(), high=False) # Pretend to be now # message.guild = guild # Just in case we got desperate, see above
message = neuter_message(message) # message.channel = channel
# absolutely weird that this takes a message object instead of guild # 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): if isinstance(prefixes, str):
prefix = prefixes prefix = prefixes
else: else:
prefix = prefixes[0] 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 ( if (
not message.guild not message.guild
@ -319,7 +381,10 @@ class Task:
or not message.content or not message.content
or message.content == prefix 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 return False
new_ctx: commands.Context = await self.bot.get_context(message) new_ctx: commands.Context = await self.bot.get_context(message)

Loading…
Cancel
Save