fix black formatting errors for sfx and scheduler

This commit is contained in:
brandons209 2020-08-22 20:29:46 -04:00
parent 349d9436d3
commit e3afe10299
7 changed files with 42 additions and 126 deletions

View file

@ -11,9 +11,7 @@ def can_run_command(command_name: str):
return False return False
try: try:
can_run = await command.can_run( can_run = await command.can_run(ctx, check_all_parents=True, change_permission_state=False)
ctx, check_all_parents=True, change_permission_state=False
)
except commands.CommandError: except commands.CommandError:
can_run = False can_run = False

View file

@ -49,9 +49,7 @@ class Schedule:
command = None command = None
parser = NoExitParser(description="Scheduler event parsing", add_help=False) parser = NoExitParser(description="Scheduler event parsing", add_help=False)
parser.add_argument( parser.add_argument("-q", "--quiet", action="store_true", dest="quiet", default=False)
"-q", "--quiet", action="store_true", dest="quiet", default=False
)
parser.add_argument("--every", nargs="*", dest="every", default=[]) parser.add_argument("--every", nargs="*", dest="every", default=[])
if not command: if not command:
parser.add_argument("command", nargs="*") parser.add_argument("command", nargs="*")
@ -84,8 +82,7 @@ class Schedule:
recur = parsed recur = parsed
if recur.total_seconds() < 60: if recur.total_seconds() < 60:
raise BadArgument( raise BadArgument(
"You can't schedule something to happen that frequently, " "You can't schedule something to happen that frequently, " "I'll get ratelimited."
"I'll get ratelimited."
) )
if vals["at"]: if vals["at"]:

View file

@ -30,9 +30,7 @@ def neuter_coroutines(klass):
async def replacement_delete_messages(self, messages): async def replacement_delete_messages(self, messages):
message_ids = list( message_ids = list({m.id for m in messages if m.__class__.__name__ != "SchedulerMessage"})
{m.id for m in messages if m.__class__.__name__ != "SchedulerMessage"}
)
if not message_ids: if not message_ids:
return return
@ -42,9 +40,7 @@ async def replacement_delete_messages(self, messages):
return return
if len(message_ids) > 100: if len(message_ids) > 100:
raise discord.ClientException( raise discord.ClientException("Can only bulk delete messages up to 100 messages")
"Can only bulk delete messages up to 100 messages"
)
await self._state.http.delete_messages(self.id, message_ids) await self._state.http.delete_messages(self.id, message_ids)
@ -61,9 +57,7 @@ class SchedulerMessage(discord.Message):
Be careful when using this in other use cases. Be careful when using this in other use cases.
""" """
def __init__( def __init__(self, *, content: str, author: discord.Member, channel: discord.TextChannel) -> None:
self, *, content: str, author: discord.Member, channel: discord.TextChannel
) -> None:
# auto current time # auto current time
self.id = discord.utils.time_snowflake(datetime.utcnow()) self.id = discord.utils.time_snowflake(datetime.utcnow())
# important properties for even being processed # important properties for even being processed
@ -81,9 +75,9 @@ class SchedulerMessage(discord.Message):
# suport for attachments somehow later maybe? # suport for attachments somehow later maybe?
self.attachments: List[discord.Attachment] = [] self.attachments: List[discord.Attachment] = []
# mentions # mentions
self.mention_everyone = self.channel.permissions_for( self.mention_everyone = self.channel.permissions_for(self.author).mention_everyone and bool(
self.author EVERYONE_REGEX.match(self.content)
).mention_everyone and bool(EVERYONE_REGEX.match(self.content)) )
# pylint: disable=E1133 # pylint: disable=E1133
# pylint improperly detects the inherited properties here as not being iterable # pylint improperly detects the inherited properties here as not being iterable
# This should be fixed with typehint support added to upstream lib later # This should be fixed with typehint support added to upstream lib later

View file

@ -100,9 +100,7 @@ class Scheduler(commands.Cog):
# explain: mypy assumes this is always true, but other CCs using this API may not be using mypy. # explain: mypy assumes this is always true, but other CCs using this API may not be using mypy.
if not (isinstance(author, discord.Member) and isinstance(channel, discord.TextChannel)): # type: ignore if not (isinstance(author, discord.Member) and isinstance(channel, discord.TextChannel)): # type: ignore
raise TypeError( raise TypeError("Must provide guild specific discord.py models for both author and channel")
"Must provide guild specific discord.py models for both author and channel"
)
if recur is not None and recur.total_seconds() < 60: if recur is not None and recur.total_seconds() < 60:
raise ValueError("Recuring events must be at least a minute apart.") raise ValueError("Recuring events must be at least a minute apart.")
@ -149,9 +147,7 @@ class Scheduler(commands.Cog):
A string which is needed to unschedule the task A string which is needed to unschedule the task
""" """
tasks = await self.fetch_task_by_attrs_exact( tasks = await self.fetch_task_by_attrs_exact(extern_cog=calling_cog.qualified_name, uid=uid)
extern_cog=calling_cog.qualified_name, uid=uid
)
if tasks: if tasks:
await self._remove_tasks(*tasks) await self._remove_tasks(*tasks)
@ -161,15 +157,11 @@ class Scheduler(commands.Cog):
def __init__(self, bot, *args, **kwargs): def __init__(self, bot, *args, **kwargs):
self.bot = bot self.bot = bot
self.config = Config.get_conf( self.config = Config.get_conf(self, identifier=78631113035100160, force_registration=True)
self, identifier=78631113035100160, force_registration=True
)
self.config.register_channel(tasks={}) # Serialized Tasks go in here. self.config.register_channel(tasks={}) # Serialized Tasks go in here.
self.log = logging.getLogger("red.sinbadcogs.scheduler") self.log = logging.getLogger("red.sinbadcogs.scheduler")
self.bg_loop_task: Optional[asyncio.Task] = None self.bg_loop_task: Optional[asyncio.Task] = None
self.scheduled: Dict[ self.scheduled: Dict[str, asyncio.Task] = {} # Might change this to a list later.
str, asyncio.Task
] = {} # Might change this to a list later.
self.tasks: List[Task] = [] self.tasks: List[Task] = []
self._iter_lock = asyncio.Lock() self._iter_lock = asyncio.Lock()
@ -183,10 +175,7 @@ class Scheduler(commands.Cog):
task.cancel() task.cancel()
async def red_delete_data_for_user( async def red_delete_data_for_user(
self, self, *, requester: Literal["discord_deleted_user", "owner", "user", "user_strict"], user_id: int,
*,
requester: Literal["discord_deleted_user", "owner", "user", "user_strict"],
user_id: int,
): ):
loaded_tasks = await self.fetch_task_by_attrs_exact(author=user_id) loaded_tasks = await self.fetch_task_by_attrs_exact(author=user_id)
if loaded_tasks: if loaded_tasks:
@ -218,10 +207,7 @@ class Scheduler(commands.Cog):
chan_dict = await self.config.all_channels() chan_dict = await self.config.all_channels()
for channel_id, channel_data in chan_dict.items(): for channel_id, channel_data in chan_dict.items():
channel = self.bot.get_channel(channel_id) channel = self.bot.get_channel(channel_id)
if ( if not channel or not channel.permissions_for(channel.guild.me).read_messages:
not channel
or not channel.permissions_for(channel.guild.me).read_messages
):
continue continue
tasks_dict = channel_data.get("tasks", {}) tasks_dict = channel_data.get("tasks", {})
for t in Task.bulk_from_config(bot=self.bot, **tasks_dict): for t in Task.bulk_from_config(bot=self.bot, **tasks_dict):
@ -236,9 +222,7 @@ class Scheduler(commands.Cog):
async def bg_loop(self): async def bg_loop(self):
await self.bot.wait_until_ready() await self.bot.wait_until_ready()
await asyncio.sleep(2) await asyncio.sleep(2)
_guilds = [ _guilds = [g for g in self.bot.guilds if g.large and not (g.chunked or g.unavailable)]
g for g in self.bot.guilds if g.large and not (g.chunked or g.unavailable)
]
await self.bot.request_offline_members(*_guilds) await self.bot.request_offline_members(*_guilds)
async with self._iter_lock: async with self._iter_lock:
@ -256,11 +240,7 @@ class Scheduler(commands.Cog):
message = await task.get_message(self.bot) message = await task.get_message(self.bot)
context = await self.bot.get_context(message) context = await self.bot.get_context(message)
context.assume_yes = True context.assume_yes = True
if ( if context.invoked_with and context.command and context.command.qualified_name in SUSPICIOUS_COMMANDS:
context.invoked_with
and context.command
and context.command.qualified_name in SUSPICIOUS_COMMANDS
):
self.log.warning( self.log.warning(
f"Handling scheduled {context.command.qualified_name} " f"Handling scheduled {context.command.qualified_name} "
"if you are using this to avoid an issue with another cog, " "if you are using this to avoid an issue with another cog, "
@ -305,9 +285,7 @@ class Scheduler(commands.Cog):
for task in self.tasks: for task in self.tasks:
delay = task.next_call_delay delay = task.next_call_delay
if delay < 30 and task.uid not in self.scheduled: if delay < 30 and task.uid not in self.scheduled:
self.scheduled[task.uid] = asyncio.create_task( self.scheduled[task.uid] = asyncio.create_task(self.delayed_wrap_and_invoke(task, delay))
self.delayed_wrap_and_invoke(task, delay)
)
if not task.recur: if not task.recur:
to_remove.append(task) to_remove.append(task)
@ -317,9 +295,7 @@ class Scheduler(commands.Cog):
# explain: mypy assumes this is always true, but other CCs using this API may not be using mypy. # explain: mypy assumes this is always true, but other CCs using this API may not be using mypy.
if not (isinstance(author, discord.Member) and isinstance(channel, discord.TextChannel)): # type: ignore if not (isinstance(author, discord.Member) and isinstance(channel, discord.TextChannel)): # type: ignore
raise TypeError( raise TypeError("Must provide guild specific discord.py models for both author and channel")
"Must provide guild specific discord.py models for both author and channel"
)
async def fetch_task_by_attrs_exact(self, **kwargs) -> List[Task]: async def fetch_task_by_attrs_exact(self, **kwargs) -> List[Task]:
def pred(item): def pred(item):
@ -331,9 +307,7 @@ class Scheduler(commands.Cog):
async with self._iter_lock: async with self._iter_lock:
return [t for t in self.tasks if pred(t)] return [t for t in self.tasks if pred(t)]
async def fetch_task_by_attrs_lax( async def fetch_task_by_attrs_lax(self, lax: Optional[dict] = None, strict: Optional[dict] = None) -> List[Task]:
self, lax: Optional[dict] = None, strict: Optional[dict] = None
) -> List[Task]:
def pred(item): def pred(item):
try: try:
if strict and not all(getattr(item, k) == v for k, v in strict.items()): if strict and not all(getattr(item, k) == v for k, v in strict.items()):
@ -358,9 +332,7 @@ class Scheduler(commands.Cog):
@checks.mod_or_permissions(manage_guild=True) @checks.mod_or_permissions(manage_guild=True)
@commands.guild_only() @commands.guild_only()
@commands.command(usage="<eventname> <command> <args>") @commands.command(usage="<eventname> <command> <args>")
async def schedule( async def schedule(self, ctx: commands.GuildContext, event_name: NonNumeric, *, schedule: Schedule):
self, ctx: commands.GuildContext, event_name: NonNumeric, *, schedule: Schedule
):
""" """
Schedule something Schedule something
@ -419,16 +391,12 @@ class Scheduler(commands.Cog):
quiet: bool = schedule.quiet quiet: bool = schedule.quiet
if await self.fetch_task_by_attrs_exact( if await self.fetch_task_by_attrs_exact(author=ctx.author, channel=ctx.channel, nicename=event_name.parsed):
author=ctx.author, channel=ctx.channel, nicename=event_name.parsed
):
if not quiet: if not quiet:
return await ctx.send("You already have an event by that name here.") return await ctx.send("You already have an event by that name here.")
async with self._iter_lock: async with self._iter_lock:
async with self.config.channel(ctx.channel).tasks( async with self.config.channel(ctx.channel).tasks(acquire_lock=False) as tsks:
acquire_lock=False
) as tsks:
tsks.update(t.to_config()) tsks.update(t.to_config())
self.tasks.append(t) self.tasks.append(t)
@ -460,23 +428,15 @@ class Scheduler(commands.Cog):
""" """
tasks = await self.fetch_task_by_attrs_lax( tasks = await self.fetch_task_by_attrs_lax(
lax={"uid": info, "nicename": info}, lax={"uid": info, "nicename": info}, strict={"author": ctx.author, "channel": ctx.channel},
strict={"author": ctx.author, "channel": ctx.channel},
) )
if not tasks: if not tasks:
await ctx.send( await ctx.send(f"Hmm, I couldn't find that task. (try `{ctx.clean_prefix}showscheduled`)")
f"Hmm, I couldn't find that task. (try `{ctx.clean_prefix}showscheduled`)"
)
elif len(tasks) > 1: elif len(tasks) > 1:
self.log.warning( self.log.warning(f"Mutiple tasks where should be unique. Task data: {tasks}")
f"Mutiple tasks where should be unique. Task data: {tasks}" await ctx.send("There seems to have been breakage here. " "Cleaning up and logging incident.")
)
await ctx.send(
"There seems to have been breakage here. "
"Cleaning up and logging incident."
)
return return
else: else:
@ -486,9 +446,7 @@ class Scheduler(commands.Cog):
@checks.bot_has_permissions(add_reactions=True, embed_links=True) @checks.bot_has_permissions(add_reactions=True, embed_links=True)
@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def showscheduled( async def showscheduled(self, ctx: commands.GuildContext, all_channels: bool = False):
self, ctx: commands.GuildContext, all_channels: bool = False
):
""" """
Shows your scheduled tasks in this, or all channels. Shows your scheduled tasks in this, or all channels.
""" """
@ -497,9 +455,7 @@ class Scheduler(commands.Cog):
tasks = await self.fetch_tasks_by_guild(ctx.guild) tasks = await self.fetch_tasks_by_guild(ctx.guild)
tasks = [t for t in tasks if t.author == ctx.author] tasks = [t for t in tasks if t.author == ctx.author]
else: else:
tasks = await self.fetch_task_by_attrs_exact( tasks = await self.fetch_task_by_attrs_exact(author=ctx.author, channel=ctx.channel)
author=ctx.author, channel=ctx.channel
)
if not tasks: if not tasks:
return await ctx.send("No scheduled tasks") return await ctx.send("No scheduled tasks")
@ -507,10 +463,7 @@ class Scheduler(commands.Cog):
await self.task_menu(ctx, tasks) await self.task_menu(ctx, tasks)
async def task_menu( async def task_menu(
self, self, ctx: commands.GuildContext, tasks: List[Task], message: Optional[discord.Message] = None,
ctx: commands.GuildContext,
tasks: List[Task],
message: Optional[discord.Message] = None,
): ):
color = await ctx.embed_color() color = await ctx.embed_color()
@ -539,10 +492,7 @@ class Scheduler(commands.Cog):
await message.delete() await message.delete()
count = len(tasks) count = len(tasks)
embeds = [ embeds = [t.to_embed(index=i, page_count=count, color=color) for i, t in enumerate(tasks, 1)]
t.to_embed(index=i, page_count=count, color=color)
for i, t in enumerate(tasks, 1)
]
controls = DEFAULT_CONTROLS.copy() controls = DEFAULT_CONTROLS.copy()
page_mapping = {i: t for i, t in enumerate(tasks)} page_mapping = {i: t for i, t in enumerate(tasks)}
@ -604,9 +554,7 @@ class Scheduler(commands.Cog):
) )
async with self._iter_lock: async with self._iter_lock:
async with self.config.channel(ctx.channel).tasks( async with self.config.channel(ctx.channel).tasks(acquire_lock=False) as tsks:
acquire_lock=False
) as tsks:
tsks.update(t.to_config()) tsks.update(t.to_config())
self.tasks.append(t) self.tasks.append(t)
@ -672,17 +620,11 @@ class Scheduler(commands.Cog):
tasks = await self.fetch_task_by_attrs_exact(uid=task_id) tasks = await self.fetch_task_by_attrs_exact(uid=task_id)
if not tasks: if not tasks:
await ctx.send( await ctx.send(f"Hmm, I couldn't find that task. (try `{ctx.clean_prefix}showscheduled`)")
f"Hmm, I couldn't find that task. (try `{ctx.clean_prefix}showscheduled`)"
)
elif len(tasks) > 1: elif len(tasks) > 1:
self.log.warning( self.log.warning(f"Mutiple tasks where should be unique. Task data: {tasks}")
f"Mutiple tasks where should be unique. Task data: {tasks}" return await ctx.send("There seems to have been breakage here. Cleaning up and logging incident.")
)
return await ctx.send(
"There seems to have been breakage here. Cleaning up and logging incident."
)
else: else:
await self._remove_tasks(*tasks) await self._remove_tasks(*tasks)
@ -772,13 +714,9 @@ class Scheduler(commands.Cog):
) )
async with self._iter_lock: async with self._iter_lock:
self.scheduled[mute_task.uid] = asyncio.create_task( self.scheduled[mute_task.uid] = asyncio.create_task(self.delayed_wrap_and_invoke(mute_task, 0))
self.delayed_wrap_and_invoke(mute_task, 0)
)
async with self.config.channel(ctx.channel).tasks( async with self.config.channel(ctx.channel).tasks(acquire_lock=False) as tsks:
acquire_lock=False
) as tsks:
tsks.update(unmute_task.to_config()) tsks.update(unmute_task.to_config())
self.tasks.append(unmute_task) self.tasks.append(unmute_task)
@ -835,12 +773,8 @@ class Scheduler(commands.Cog):
) )
async with self._iter_lock: async with self._iter_lock:
self.scheduled[mute_task.uid] = asyncio.create_task( self.scheduled[mute_task.uid] = asyncio.create_task(self.delayed_wrap_and_invoke(mute_task, 0))
self.delayed_wrap_and_invoke(mute_task, 0)
)
async with self.config.channel(ctx.channel).tasks( async with self.config.channel(ctx.channel).tasks(acquire_lock=False) as tsks:
acquire_lock=False
) as tsks:
tsks.update(unmute_task.to_config()) tsks.update(unmute_task.to_config())
self.tasks.append(unmute_task) self.tasks.append(unmute_task)

View file

@ -33,9 +33,7 @@ class Task:
pfx = (await bot.get_prefix(self.channel))[0] pfx = (await bot.get_prefix(self.channel))[0]
content = f"{pfx}{self.content}" content = f"{pfx}{self.content}"
return SchedulerMessage( return SchedulerMessage(content=content, author=self.author, channel=self.channel)
content=content, author=self.author, channel=self.channel
)
def to_config(self): def to_config(self):
@ -72,12 +70,7 @@ class Task:
with contextlib.suppress(AttributeError, ValueError): with contextlib.suppress(AttributeError, ValueError):
yield cls( yield cls(
initial=initial, initial=initial, recur=recur, channel=channel, author=author, uid=uid, **data,
recur=recur,
channel=channel,
author=author,
uid=uid,
**data,
) )
@property @property

View file

@ -264,7 +264,7 @@ class SFX(commands.Cog):
await ctx.send(error("Please reload the cog after the Audio cog has been loaded!")) await ctx.send(error("Please reload the cog after the Audio cog has been loaded!"))
return return
inject_path = str(code_path(cog_instance=self) / "injection.py") inject_path = str(code_path(cog_instance=self) / "injection.txt")
with open(inject_path, "r") as f: with open(inject_path, "r") as f:
injection = f.read() injection = f.read()