Removed remind_id from pause and resume command
This commit is contained in:
287
main.py
287
main.py
@ -8,11 +8,11 @@ import pytz
|
|||||||
from apscheduler.jobstores.base import JobLookupError
|
from apscheduler.jobstores.base import JobLookupError
|
||||||
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
|
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
|
||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
from apscheduler.triggers.cron import CronTrigger
|
|
||||||
from apscheduler.triggers.date import DateTrigger
|
from apscheduler.triggers.date import DateTrigger
|
||||||
from apscheduler.triggers.interval import IntervalTrigger
|
from discord.errors import NotFound
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord_slash import SlashCommand, SlashContext
|
from discord_slash import SlashCommand, SlashContext
|
||||||
|
from discord_slash.error import IncorrectFormat, RequestFailure
|
||||||
from discord_slash.model import SlashCommandOptionType
|
from discord_slash.model import SlashCommandOptionType
|
||||||
from discord_slash.utils.manage_commands import create_option
|
from discord_slash.utils.manage_commands import create_option
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@ -30,14 +30,14 @@ def calc_countdown(remind_id: str) -> str:
|
|||||||
job = scheduler.get_job(remind_id)
|
job = scheduler.get_job(remind_id)
|
||||||
|
|
||||||
# Get_job() returns None when it can't find a job with that id.
|
# Get_job() returns None when it can't find a job with that id.
|
||||||
if job is None:
|
|
||||||
print(f"No reminder with that ID ({remind_id}).")
|
|
||||||
return "0 days, 0 hours, 0 minutes"
|
|
||||||
if type(job.trigger) is DateTrigger:
|
if type(job.trigger) is DateTrigger:
|
||||||
trigger_time = job.trigger.run_date
|
trigger_time = job.trigger.run_date
|
||||||
if type(job.trigger) is IntervalTrigger or CronTrigger:
|
else:
|
||||||
trigger_time = job.next_run_time
|
trigger_time = job.next_run_time
|
||||||
|
|
||||||
|
if trigger_time is None:
|
||||||
|
return "Failed to calculate time"
|
||||||
|
|
||||||
# Get time and date the job will run and calculate how many days, hours and seconds.
|
# Get time and date the job will run and calculate how many days, hours and seconds.
|
||||||
countdown = trigger_time - datetime.datetime.now(tz=pytz.timezone(config_timezone))
|
countdown = trigger_time - datetime.datetime.now(tz=pytz.timezone(config_timezone))
|
||||||
|
|
||||||
@ -58,21 +58,27 @@ def calc_countdown(remind_id: str) -> str:
|
|||||||
return the_final_countdown
|
return the_final_countdown
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_error(event, *args, **kwargs):
|
|
||||||
logging.error(f"{event}")
|
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_slash_command_error(ctx, ex):
|
async def on_slash_command_error(ctx, ex):
|
||||||
logging.error(f"{ex}")
|
logging.error(
|
||||||
|
f'Error occurred during the execution of "/{ctx.name} {ctx.subcommand_name}" by {ctx.author}: {ex}'
|
||||||
|
)
|
||||||
|
if ex == RequestFailure:
|
||||||
|
message = (f"Request to Discord API failed: {ex}",)
|
||||||
|
elif ex == IncorrectFormat:
|
||||||
|
message = (f"Incorrect format: {ex}",)
|
||||||
|
elif ex == NotFound:
|
||||||
|
message = (
|
||||||
|
f"404 Not Found - I couldn't find the interaction or it took me longer than 3 seconds to respond: {ex}",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
message = f"Error occurred during the execution of '/{ctx.name} {ctx.subcommand_name}': {ex}"
|
||||||
|
|
||||||
|
await ctx.send(
|
||||||
@bot.event
|
message + "\nIf this persists, please make an issue on "
|
||||||
async def on_command_error(ctx, error):
|
"[the GitHub repo](https://github.com/TheLovinator1/discord-reminder-bot/issues) or contact TheLovinator#9276",
|
||||||
if isinstance(error, commands.CommandNotFound):
|
hidden=True,
|
||||||
return
|
)
|
||||||
await ctx.send(error)
|
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
@ -175,7 +181,7 @@ async def remind_remove(ctx: SlashContext):
|
|||||||
else:
|
else:
|
||||||
await ctx.send(embed=list_embed)
|
await ctx.send(embed=list_embed)
|
||||||
await ctx.channel.send(
|
await ctx.channel.send(
|
||||||
"Type the corresponding number to the reminder you wish to remove."
|
"Type the corresponding number to the reminder you wish to remove. Type Exit to exit."
|
||||||
)
|
)
|
||||||
|
|
||||||
def check(m):
|
def check(m):
|
||||||
@ -184,7 +190,9 @@ async def remind_remove(ctx: SlashContext):
|
|||||||
try:
|
try:
|
||||||
response_message = await bot.wait_for("message", check=check, timeout=60)
|
response_message = await bot.wait_for("message", check=check, timeout=60)
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
return await ctx.send("Timed out, try again.")
|
return await ctx.channel.send("Timed out, try again.")
|
||||||
|
if response_message.clean_content == "Exit":
|
||||||
|
return await ctx.channel.send("Exited.")
|
||||||
|
|
||||||
for num, job_from_dict in jobs_dict.items():
|
for num, job_from_dict in jobs_dict.items():
|
||||||
if int(response_message.clean_content) == num:
|
if int(response_message.clean_content) == num:
|
||||||
@ -199,26 +207,22 @@ async def remind_remove(ctx: SlashContext):
|
|||||||
channel_name = bot.get_channel(int(channel_id))
|
channel_name = bot.get_channel(int(channel_id))
|
||||||
message = job.kwargs.get("message")
|
message = job.kwargs.get("message")
|
||||||
|
|
||||||
try:
|
# Only normal reminders have trigger.run_date, cron and interval has next_run_time
|
||||||
|
if type(job.trigger) is DateTrigger:
|
||||||
trigger_time = job.trigger.run_date
|
trigger_time = job.trigger.run_date
|
||||||
msg = (
|
else:
|
||||||
f"**Removed** {job_from_dict}.\n"
|
trigger_time = job.next_run_time
|
||||||
f"**Time**: {trigger_time.strftime('%Y-%m-%d %H:%M')} (in {calc_countdown(job_from_dict)})\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
|
||||||
f"**Message**: {message}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: Add countdown
|
# Paused reminders returns None
|
||||||
except AttributeError:
|
if trigger_time is None:
|
||||||
next_run = job.next_run_time
|
trigger_value = "Paused - can be resumed with '/remind resume'"
|
||||||
msg = (
|
else:
|
||||||
f"**Removed** {job_from_dict}.\n"
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job.id)})'
|
||||||
f"**Next run**: {next_run.strftime('%Y-%m-%d %H:%M')}\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
msg = (
|
||||||
f"**Message**: {message}"
|
f"**Removed** {message} in #{channel_name}.\n"
|
||||||
)
|
f"**Time**: {trigger_value}"
|
||||||
except Exception as e:
|
)
|
||||||
await ctx.channel.send(e)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
scheduler.remove_job(job_from_dict)
|
scheduler.remove_job(job_from_dict)
|
||||||
@ -228,7 +232,7 @@ async def remind_remove(ctx: SlashContext):
|
|||||||
await ctx.channel.send(msg)
|
await ctx.channel.send(msg)
|
||||||
|
|
||||||
|
|
||||||
def make_list(ctx):
|
def make_list(ctx, skip_datetriggers=False):
|
||||||
jobs_dict = {}
|
jobs_dict = {}
|
||||||
job_number = 0
|
job_number = 0
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@ -247,21 +251,26 @@ def make_list(ctx):
|
|||||||
job_number += 1
|
job_number += 1
|
||||||
jobs_dict[job_number] = job.id
|
jobs_dict[job_number] = job.id
|
||||||
message = job.kwargs.get("message")
|
message = job.kwargs.get("message")
|
||||||
|
|
||||||
|
# Only normal reminders have trigger.run_date, cron and interval has next_run_time
|
||||||
if type(job.trigger) is DateTrigger:
|
if type(job.trigger) is DateTrigger:
|
||||||
trigger_time = job.trigger.run_date
|
trigger_time = job.trigger.run_date
|
||||||
embed.add_field(
|
if skip_datetriggers:
|
||||||
name=f"{job_number}) {message} in #{channel_name}",
|
continue
|
||||||
value=f"{trigger_time.strftime('%Y-%m-%d %H:%M')} (in {calc_countdown(job.id)})",
|
else:
|
||||||
inline=False,
|
trigger_time = job.next_run_time
|
||||||
)
|
|
||||||
if type(job.trigger) is IntervalTrigger or CronTrigger:
|
# Paused reminders returns None
|
||||||
next_run = job.next_run_time
|
if trigger_time is None:
|
||||||
embed.add_field(
|
trigger_value = "Paused - can be resumed with '/remind resume'"
|
||||||
name=f"{job_number}) {message} in #{channel_name}",
|
else:
|
||||||
# TODO: Fix countdown
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job.id)})'
|
||||||
value=f"{next_run.strftime('%Y-%m-%d %H:%M')} (in {calc_countdown(job.id)})",
|
|
||||||
inline=False,
|
embed.add_field(
|
||||||
)
|
name=f"{job_number}) {message} in #{channel_name}",
|
||||||
|
value=f"{trigger_value}",
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
return embed, jobs_dict
|
return embed, jobs_dict
|
||||||
|
|
||||||
|
|
||||||
@ -285,39 +294,61 @@ async def remind_list(ctx: SlashContext):
|
|||||||
name="pause",
|
name="pause",
|
||||||
description="Pause reminder. For cron or interval.",
|
description="Pause reminder. For cron or interval.",
|
||||||
)
|
)
|
||||||
async def remind_pause(ctx: SlashContext, remind_id: str):
|
async def remind_pause(ctx: SlashContext):
|
||||||
job = scheduler.get_job(remind_id)
|
list_embed, jobs_dict = make_list(ctx, skip_datetriggers=True)
|
||||||
if job is None:
|
|
||||||
await ctx.send(f"No reminder with that ID ({remind_id}).")
|
|
||||||
return
|
|
||||||
|
|
||||||
channel_id = job.kwargs.get("channel_id")
|
# The empty embed has 76 characters
|
||||||
channel_name = bot.get_channel(int(channel_id))
|
if len(list_embed) <= 76:
|
||||||
message = job.kwargs.get("message")
|
await ctx.send(f"{ctx.guild.name} has no reminders.")
|
||||||
|
else:
|
||||||
try:
|
await ctx.send(embed=list_embed)
|
||||||
scheduler.pause_job(remind_id)
|
await ctx.channel.send(
|
||||||
except Exception as e:
|
"Type the corresponding number to the reminder you wish to pause. Type Exit to exit."
|
||||||
await ctx.send(e)
|
|
||||||
try:
|
|
||||||
trigger_time = job.trigger.run_date
|
|
||||||
msg = (
|
|
||||||
f"**Paused** {remind_id}.\n"
|
|
||||||
f"**Time**: {trigger_time.strftime('%Y-%m-%d %H:%M')} (in {calc_countdown(remind_id)})\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
|
||||||
f"**Message**: {message}"
|
|
||||||
)
|
)
|
||||||
except AttributeError:
|
|
||||||
msg = (
|
|
||||||
f"**Paused** {remind_id}.\n"
|
|
||||||
f"**Time**: Cronjob\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
|
||||||
f"**Message**: {message}"
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
await ctx.send(e)
|
|
||||||
|
|
||||||
await ctx.send(msg)
|
def check(m):
|
||||||
|
return m.author == ctx.author and m.channel == ctx.channel
|
||||||
|
|
||||||
|
try:
|
||||||
|
response_message = await bot.wait_for("message", check=check, timeout=60)
|
||||||
|
except TimeoutError:
|
||||||
|
return await ctx.channel.send("Timed out, try again.")
|
||||||
|
if response_message.clean_content == "Exit":
|
||||||
|
return await ctx.channel.send("Exited.")
|
||||||
|
|
||||||
|
for num, job_from_dict in jobs_dict.items():
|
||||||
|
if int(response_message.clean_content) == num:
|
||||||
|
job = scheduler.get_job(job_from_dict)
|
||||||
|
channel_id = job.kwargs.get("channel_id")
|
||||||
|
channel_name = bot.get_channel(int(channel_id))
|
||||||
|
message = job.kwargs.get("message")
|
||||||
|
|
||||||
|
# Only normal reminders have trigger.run_date, cron and interval has next_run_time
|
||||||
|
if type(job.trigger) is DateTrigger:
|
||||||
|
trigger_time = job.trigger.run_date
|
||||||
|
else:
|
||||||
|
trigger_time = job.next_run_time
|
||||||
|
|
||||||
|
# Paused reminders returns None
|
||||||
|
if trigger_time is None:
|
||||||
|
return await ctx.channel.send(
|
||||||
|
f"{response_message.clean_content} | {message} in #{channel_name} is already paused."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job.id)})'
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
f"**Paused** {message} in #{channel_name}.\n"
|
||||||
|
f"**Time**: {trigger_value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("Paused")
|
||||||
|
scheduler.pause_job(job_from_dict)
|
||||||
|
except Exception as e:
|
||||||
|
await ctx.channel.send(e)
|
||||||
|
|
||||||
|
await ctx.channel.send(msg)
|
||||||
|
|
||||||
|
|
||||||
@slash.subcommand(
|
@slash.subcommand(
|
||||||
@ -325,39 +356,62 @@ async def remind_pause(ctx: SlashContext, remind_id: str):
|
|||||||
name="resume",
|
name="resume",
|
||||||
description="Resume paused reminder. For cron or interval.",
|
description="Resume paused reminder. For cron or interval.",
|
||||||
)
|
)
|
||||||
async def remind_resume(ctx: SlashContext, remind_id: str):
|
async def remind_resume(ctx: SlashContext):
|
||||||
job = scheduler.get_job(remind_id)
|
list_embed, jobs_dict = make_list(ctx, skip_datetriggers=True)
|
||||||
if job is None:
|
|
||||||
await ctx.send(f"No reminder with that ID ({remind_id}).")
|
|
||||||
return
|
|
||||||
|
|
||||||
channel_id = job.kwargs.get("channel_id")
|
# The empty embed has 76 characters
|
||||||
channel_name = bot.get_channel(int(channel_id))
|
if len(list_embed) <= 76:
|
||||||
message = job.kwargs.get("message")
|
await ctx.send(f"{ctx.guild.name} has no reminders.")
|
||||||
|
else:
|
||||||
try:
|
await ctx.send(embed=list_embed)
|
||||||
scheduler.resume_job(remind_id)
|
await ctx.channel.send(
|
||||||
except Exception as e:
|
"Type the corresponding number to the reminder you wish to pause. Type Exit to exit."
|
||||||
await ctx.send(e)
|
|
||||||
try:
|
|
||||||
trigger_time = job.trigger.run_date
|
|
||||||
msg = (
|
|
||||||
f"**Resumed** {remind_id}.\n"
|
|
||||||
f"**Time**: {trigger_time.strftime('%Y-%m-%d %H:%M')} (in {calc_countdown(remind_id)})\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
|
||||||
f"**Message**: {message}"
|
|
||||||
)
|
)
|
||||||
except AttributeError:
|
|
||||||
msg = (
|
|
||||||
f"**Resumed** {remind_id}.\n"
|
|
||||||
f"**Time**: Cronjob\n"
|
|
||||||
f"**Channel**: #{channel_name}\n"
|
|
||||||
f"**Message**: {message}"
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
await ctx.send(e)
|
|
||||||
|
|
||||||
await ctx.send(msg)
|
def check(m):
|
||||||
|
return m.author == ctx.author and m.channel == ctx.channel
|
||||||
|
|
||||||
|
try:
|
||||||
|
response_message = await bot.wait_for("message", check=check, timeout=60)
|
||||||
|
except TimeoutError:
|
||||||
|
return await ctx.channel.send("Timed out, try again.")
|
||||||
|
if response_message == "Exit":
|
||||||
|
return await ctx.channel.send("Exited.")
|
||||||
|
|
||||||
|
for num, job_from_dict in jobs_dict.items():
|
||||||
|
if int(response_message.clean_content) == num:
|
||||||
|
job = scheduler.get_job(job_from_dict)
|
||||||
|
if job is None:
|
||||||
|
await ctx.send(f"No reminder with that ID ({job_from_dict}).")
|
||||||
|
return
|
||||||
|
|
||||||
|
channel_id = job.kwargs.get("channel_id")
|
||||||
|
channel_name = bot.get_channel(int(channel_id))
|
||||||
|
message = job.kwargs.get("message")
|
||||||
|
|
||||||
|
try:
|
||||||
|
scheduler.resume_job(job_from_dict)
|
||||||
|
except Exception as e:
|
||||||
|
await ctx.send(e)
|
||||||
|
|
||||||
|
# Only normal reminders have trigger.run_date, cron and interval has next_run_time
|
||||||
|
if type(job.trigger) is DateTrigger:
|
||||||
|
trigger_time = job.trigger.run_date
|
||||||
|
else:
|
||||||
|
trigger_time = job.next_run_time
|
||||||
|
|
||||||
|
# Paused reminders returns None
|
||||||
|
if trigger_time is None:
|
||||||
|
trigger_value = "Paused - can be resumed with '/remind resume'"
|
||||||
|
else:
|
||||||
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job.id)})'
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
f"**Resumed** {message} in #{channel_name}.\n"
|
||||||
|
f"**Time**: {trigger_value}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
await ctx.send(msg)
|
||||||
|
|
||||||
|
|
||||||
@slash.subcommand(
|
@slash.subcommand(
|
||||||
@ -510,7 +564,7 @@ async def remind_cron(
|
|||||||
timezone=None,
|
timezone=None,
|
||||||
jitter=None,
|
jitter=None,
|
||||||
):
|
):
|
||||||
scheduler.add_job(
|
job = scheduler.add_job(
|
||||||
send_to_discord,
|
send_to_discord,
|
||||||
"cron",
|
"cron",
|
||||||
year=year,
|
year=year,
|
||||||
@ -533,9 +587,8 @@ async def remind_cron(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Add arguments
|
# TODO: Add arguments
|
||||||
# TODO: Fix countdown
|
|
||||||
message = (
|
message = (
|
||||||
f"Hello {ctx.author.display_name}, first run in [TODO: Fix this]\n"
|
f"Hello {ctx.author.display_name}, first run in {calc_countdown(job.id)}\n"
|
||||||
f"With the message:\n**{message_reason}**."
|
f"With the message:\n**{message_reason}**."
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -622,7 +675,7 @@ async def remind_interval(
|
|||||||
timezone=None,
|
timezone=None,
|
||||||
jitter=None,
|
jitter=None,
|
||||||
):
|
):
|
||||||
scheduler.add_job(
|
job = scheduler.add_job(
|
||||||
send_to_discord,
|
send_to_discord,
|
||||||
"interval",
|
"interval",
|
||||||
weeks=weeks,
|
weeks=weeks,
|
||||||
@ -643,7 +696,7 @@ async def remind_interval(
|
|||||||
|
|
||||||
# TODO: Add arguments
|
# TODO: Add arguments
|
||||||
message = (
|
message = (
|
||||||
f"Hello {ctx.author.display_name}, first run in [TODO: Fix this]\n"
|
f"Hello {ctx.author.display_name}, first run in {calc_countdown(job.id)})\n"
|
||||||
f"With the message:\n**{message_reason}**."
|
f"With the message:\n**{message_reason}**."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user