Fix multi-triggers, add `checktask` to see more scheduled executions

pull/156/head
bobloy 4 years ago
parent 477364f9bf
commit fc0870af68

@ -1,5 +1,6 @@
import itertools
import logging import logging
from datetime import datetime, timedelta, tzinfo from datetime import datetime, timedelta, tzinfo, MAXYEAR
from typing import Optional, Union from typing import Optional, Union
import discord import discord
@ -10,7 +11,7 @@ from apscheduler.schedulers.base import STATE_PAUSED, STATE_RUNNING
from redbot.core import Config, checks, commands from redbot.core import Config, checks, commands
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core.commands import TimedeltaConverter from redbot.core.commands import TimedeltaConverter
from redbot.core.utils.chat_formatting import pagify from redbot.core.utils.chat_formatting import humanize_list, humanize_timedelta, pagify
from .datetime_cron_converters import CronConverter, DatetimeConverter, TimezoneConverter from .datetime_cron_converters import CronConverter, DatetimeConverter, TimezoneConverter
from .task import Task from .task import Task
@ -37,6 +38,27 @@ def _disassemble_job_id(job_id: str):
return job_id.split("_") return job_id.split("_")
def _get_run_times(job: Job, now: datetime = None):
"""
Computes the scheduled run times between ``next_run_time`` and ``now`` (inclusive).
Modified to be asynchronous and yielding instead of all-or-nothing
"""
if not job.next_run_time:
raise StopIteration()
if now is None:
now = datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=job.next_run_time.tzinfo)
yield from _get_run_times(job, now)
raise StopIteration()
next_run_time = job.next_run_time
while next_run_time and next_run_time <= now:
yield next_run_time
next_run_time = job.trigger.get_next_fire_time(next_run_time, now)
class FIFO(commands.Cog): class FIFO(commands.Cog):
""" """
Simple Scheduling Cog Simple Scheduling Cog
@ -173,6 +195,30 @@ class FIFO(commands.Cog):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
pass pass
@fifo.command(name="checktask", aliases=["checkjob", "check"])
async def fifo_checktask(self, ctx: commands.Context, task_name: str):
"""Returns the next 10 scheduled executions of the task"""
task = Task(task_name, ctx.guild.id, self.config, bot=self.bot)
await task.load_from_config()
if task.data is None:
await ctx.maybe_send_embed(
f"Task by the name of {task_name} is not found in this guild"
)
return
job = await self._get_job(task)
if job is None:
await ctx.maybe_send_embed("No job scheduled for this task")
return
now = datetime.now(job.next_run_time.tzinfo)
times = [
humanize_timedelta(timedelta=x - now)
for x in itertools.islice(_get_run_times(job), 10)
]
await ctx.maybe_send_embed("\n\n".join(times))
@fifo.command(name="set") @fifo.command(name="set")
async def fifo_set( async def fifo_set(
self, self,
@ -326,6 +372,8 @@ class FIFO(commands.Cog):
for task_name, task_data in all_tasks.items(): for task_name, task_data in all_tasks.items():
out += f"{task_name}: {task_data}\n" out += f"{task_name}: {task_data}\n"
out = humanize_list(out)
if out: if out:
if len(out) > 2000: if len(out) > 2000:
for page in pagify(out): for page in pagify(out):
@ -394,6 +442,7 @@ class FIFO(commands.Cog):
return return
await task.clear_triggers() await task.clear_triggers()
await self._remove_job(task)
await ctx.tick() await ctx.tick()
@fifo.group(name="addtrigger", aliases=["trigger"]) @fifo.group(name="addtrigger", aliases=["trigger"])

@ -39,7 +39,7 @@ def parse_triggers(data: Union[Dict, None]):
return None return None
if len(data["triggers"]) > 1: # Multiple triggers if len(data["triggers"]) > 1: # Multiple triggers
return OrTrigger(get_trigger(t_data) for t_data in data["triggers"]) return OrTrigger([get_trigger(t_data) for t_data in data["triggers"]])
return get_trigger(data["triggers"][0]) return get_trigger(data["triggers"][0])
@ -108,20 +108,6 @@ class Task:
"tzinfo": getattr(t["tzinfo"], "zone", None), "tzinfo": getattr(t["tzinfo"], "zone", None),
} }
) )
# triggers.append(
# {
# "type": t["type"],
# "time_data": {
# "year": dt.year,
# "month": dt.month,
# "day": dt.day,
# "hour": dt.hour,
# "minute": dt.minute,
# "second": dt.second,
# "tzinfo": dt.tzinfo,
# },
# }
# )
continue continue
if t["type"] == "cron": if t["type"] == "cron":

Loading…
Cancel
Save