Move calc_counddown() to own file
This commit is contained in:
54
discord_reminder_bot/countdown.py
Normal file
54
discord_reminder_bot/countdown.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
import pytz
|
||||||
|
from apscheduler.job import Job
|
||||||
|
from apscheduler.triggers.date import DateTrigger
|
||||||
|
|
||||||
|
from discord_reminder_bot.settings import config_timezone
|
||||||
|
|
||||||
|
|
||||||
|
def calculate(job: Job) -> str:
|
||||||
|
"""Get trigger time from a reminder and calculate how many days,
|
||||||
|
hours and minutes till trigger.
|
||||||
|
|
||||||
|
Days/Minutes will not be included if 0.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
job: The job. Can be cron, interval or normal.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Returns days, hours and minutes till reminder. Returns "Failed to calculate time" if no job is found.
|
||||||
|
"""
|
||||||
|
# TODO: This "breaks" when only seconds are left.
|
||||||
|
# If we use (in {calc_countdown(job)}) it will show (in )
|
||||||
|
|
||||||
|
if type(job.trigger) is DateTrigger:
|
||||||
|
trigger_time = job.trigger.run_date
|
||||||
|
else:
|
||||||
|
trigger_time = job.next_run_time
|
||||||
|
|
||||||
|
# Get_job() returns None when it can't find a job with that id.
|
||||||
|
if trigger_time is None:
|
||||||
|
# TODO: Change this to None and send this text where needed.
|
||||||
|
return "Failed to calculate time"
|
||||||
|
|
||||||
|
# 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))
|
||||||
|
|
||||||
|
days, hours, minutes = (
|
||||||
|
countdown.days,
|
||||||
|
countdown.seconds // 3600,
|
||||||
|
countdown.seconds // 60 % 60,
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: Explain this.
|
||||||
|
return ", ".join(
|
||||||
|
f"{x} {y}{'s' * (x != 1)}"
|
||||||
|
for x, y in (
|
||||||
|
(days, "day"),
|
||||||
|
(hours, "hour"),
|
||||||
|
(minutes, "minute"),
|
||||||
|
)
|
||||||
|
if x
|
||||||
|
)
|
@ -1,9 +1,7 @@
|
|||||||
import datetime
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import dateparser
|
import dateparser
|
||||||
import discord
|
import discord
|
||||||
import pytz
|
|
||||||
from apscheduler.triggers.date import DateTrigger
|
from apscheduler.triggers.date import DateTrigger
|
||||||
from discord.errors import NotFound
|
from discord.errors import NotFound
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
@ -12,6 +10,7 @@ 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_choice, create_option
|
from discord_slash.utils.manage_commands import create_choice, create_option
|
||||||
|
|
||||||
|
from discord_reminder_bot.countdown import calculate
|
||||||
from discord_reminder_bot.settings import bot_token, config_timezone, log_level, scheduler, sqlite_location
|
from discord_reminder_bot.settings import bot_token, config_timezone, log_level, scheduler, sqlite_location
|
||||||
|
|
||||||
bot = commands.Bot(
|
bot = commands.Bot(
|
||||||
@ -21,54 +20,6 @@ bot = commands.Bot(
|
|||||||
slash = SlashCommand(bot, sync_commands=True)
|
slash = SlashCommand(bot, sync_commands=True)
|
||||||
|
|
||||||
|
|
||||||
def calc_countdown(job) -> str:
|
|
||||||
"""Get trigger time from a reminder and calculate how many days,
|
|
||||||
hours and minutes till trigger.
|
|
||||||
|
|
||||||
Days/Minutes will not be included if 0.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
job: The job. Can be cron, interval or normal.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Returns days, hours and minutes till reminder. Returns
|
|
||||||
"Failed to calculate time" if no job is found.
|
|
||||||
"""
|
|
||||||
# TODO: This "breaks" when only seconds are left.
|
|
||||||
# If we use (in {calc_countdown(job)}) it will show (in )
|
|
||||||
|
|
||||||
if type(job.trigger) is DateTrigger:
|
|
||||||
trigger_time = job.trigger.run_date
|
|
||||||
else:
|
|
||||||
trigger_time = job.next_run_time
|
|
||||||
|
|
||||||
# Get_job() returns None when it can't find a job with that id.
|
|
||||||
if trigger_time is None:
|
|
||||||
# TODO: Change this to None and send this text where needed.
|
|
||||||
return "Failed to calculate time"
|
|
||||||
|
|
||||||
# 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))
|
|
||||||
|
|
||||||
days, hours, minutes = (
|
|
||||||
countdown.days,
|
|
||||||
countdown.seconds // 3600,
|
|
||||||
countdown.seconds // 60 % 60,
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: Explain this.
|
|
||||||
return ", ".join(
|
|
||||||
f"{x} {y}{'s' * (x != 1)}"
|
|
||||||
for x, y in (
|
|
||||||
(days, "day"),
|
|
||||||
(hours, "hour"),
|
|
||||||
(minutes, "minute"),
|
|
||||||
)
|
|
||||||
if x
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_slash_command_error(ctx: SlashContext, ex: Exception):
|
async def on_slash_command_error(ctx: SlashContext, ex: Exception):
|
||||||
logging.error(f"Error occurred during the execution of '/{ctx.name} {ctx.subcommand_name}' by {ctx.author}: {ex}")
|
logging.error(f"Error occurred during the execution of '/{ctx.name} {ctx.subcommand_name}' by {ctx.author}: {ex}")
|
||||||
@ -152,7 +103,7 @@ async def command_modify(ctx: SlashContext, time_or_message: str):
|
|||||||
return
|
return
|
||||||
|
|
||||||
message = job.kwargs.get("message")
|
message = job.kwargs.get("message")
|
||||||
old_time = calc_countdown(job)
|
old_time = calculate(job)
|
||||||
|
|
||||||
channel_name = bot.get_channel(int(job.kwargs.get("channel_id")))
|
channel_name = bot.get_channel(int(job.kwargs.get("channel_id")))
|
||||||
msg = f"**Modified** {job_from_dict} in #{channel_name}\n"
|
msg = f"**Modified** {job_from_dict} in #{channel_name}\n"
|
||||||
@ -195,7 +146,7 @@ async def command_modify(ctx: SlashContext, time_or_message: str):
|
|||||||
job = scheduler.reschedule_job(job_from_dict, run_date=date_new)
|
job = scheduler.reschedule_job(job_from_dict, run_date=date_new)
|
||||||
|
|
||||||
date_old = job.trigger.run_date.strftime("%Y-%m-%d %H:%M")
|
date_old = job.trigger.run_date.strftime("%Y-%m-%d %H:%M")
|
||||||
new_time = calc_countdown(job_from_dict)
|
new_time = calculate(job_from_dict)
|
||||||
msg += f"**Old date**: {date_old} (in {old_time})\n**New date**: {date_new} (in {new_time})"
|
msg += f"**Old date**: {date_old} (in {old_time})\n**New date**: {date_new} (in {new_time})"
|
||||||
|
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
@ -245,7 +196,7 @@ async def remind_remove(ctx: SlashContext):
|
|||||||
if trigger_time is None:
|
if trigger_time is None:
|
||||||
trigger_value = "Paused - can be resumed with '/remind resume'"
|
trigger_value = "Paused - can be resumed with '/remind resume'"
|
||||||
else:
|
else:
|
||||||
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job)})'
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calculate(job)})'
|
||||||
|
|
||||||
msg = f"**Removed** {message} in #{channel_name}.\n**Time**: {trigger_value}"
|
msg = f"**Removed** {message} in #{channel_name}.\n**Time**: {trigger_value}"
|
||||||
|
|
||||||
@ -305,7 +256,7 @@ async def send_list(ctx, skip_datetriggers=False, skip_cron_or_interval=False):
|
|||||||
if trigger_time is None:
|
if trigger_time is None:
|
||||||
trigger_value = "Paused"
|
trigger_value = "Paused"
|
||||||
else:
|
else:
|
||||||
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job)})'
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calculate(job)})'
|
||||||
|
|
||||||
job_number += 1
|
job_number += 1
|
||||||
jobs_dict[job_number] = job.id
|
jobs_dict[job_number] = job.id
|
||||||
@ -376,7 +327,7 @@ async def remind_pause(ctx: SlashContext):
|
|||||||
if trigger_time is None:
|
if trigger_time is None:
|
||||||
return await ctx.channel.send(f"{message} in #{channel_name} is already paused.")
|
return await ctx.channel.send(f"{message} in #{channel_name} is already paused.")
|
||||||
|
|
||||||
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job)})'
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calculate(job)})'
|
||||||
|
|
||||||
msg = f"**Paused** {message} in #{channel_name}.\n**Time**: {trigger_value}"
|
msg = f"**Paused** {message} in #{channel_name}.\n**Time**: {trigger_value}"
|
||||||
|
|
||||||
@ -433,7 +384,7 @@ async def remind_resume(ctx: SlashContext):
|
|||||||
if trigger_time is None:
|
if trigger_time is None:
|
||||||
trigger_value = "Paused - can be resumed with '/remind resume'"
|
trigger_value = "Paused - can be resumed with '/remind resume'"
|
||||||
else:
|
else:
|
||||||
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calc_countdown(job)})'
|
trigger_value = f'{trigger_time.strftime("%Y-%m-%d %H:%M")} (in {calculate(job)})'
|
||||||
|
|
||||||
msg = f"**Resumed** {message} in #{channel_name}.\n**Time**: {trigger_value}\n"
|
msg = f"**Resumed** {message} in #{channel_name}.\n**Time**: {trigger_value}\n"
|
||||||
|
|
||||||
@ -506,7 +457,7 @@ async def remind_add(
|
|||||||
message = (
|
message = (
|
||||||
f"Hello {ctx.author.display_name},"
|
f"Hello {ctx.author.display_name},"
|
||||||
f" I will notify you in <#{channel_id}> at:\n"
|
f" I will notify you in <#{channel_id}> at:\n"
|
||||||
f"**{run_date}** (in {calc_countdown(reminder)})\n"
|
f"**{run_date}** (in {calculate(reminder)})\n"
|
||||||
f"With the message:\n**{message_reason}**."
|
f"With the message:\n**{message_reason}**."
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -675,7 +626,7 @@ async def remind_cron(
|
|||||||
message = (
|
message = (
|
||||||
f"Hello {ctx.author.display_name},"
|
f"Hello {ctx.author.display_name},"
|
||||||
f" I will send messages to <#{channel_id}>.\n"
|
f" I will send messages to <#{channel_id}>.\n"
|
||||||
f"First run in {calc_countdown(job)} with the message:\n"
|
f"First run in {calculate(job)} with the message:\n"
|
||||||
f"**{message_reason}**."
|
f"**{message_reason}**."
|
||||||
)
|
)
|
||||||
await ctx.send(message)
|
await ctx.send(message)
|
||||||
@ -807,7 +758,7 @@ async def remind_interval(
|
|||||||
# TODO: Add what arguments we used in the job to the message
|
# TODO: Add what arguments we used in the job to the message
|
||||||
message = (
|
message = (
|
||||||
f"Hello {ctx.author.display_name}, I will send messages to <#{channel_id}>.\n"
|
f"Hello {ctx.author.display_name}, I will send messages to <#{channel_id}>.\n"
|
||||||
f"First run in {calc_countdown(job)} with the message:\n"
|
f"First run in {calculate(job)} with the message:\n"
|
||||||
f"**{message_reason}**."
|
f"**{message_reason}**."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
|
|||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
|
|
||||||
from discord_reminder_bot import __version__
|
from discord_reminder_bot import __version__
|
||||||
from discord_reminder_bot.main import calc_countdown, send_to_discord
|
from discord_reminder_bot.main import send_to_discord
|
||||||
|
from discord_reminder_bot.countdown import calculate
|
||||||
|
|
||||||
|
|
||||||
def test_version():
|
def test_version():
|
||||||
@ -56,5 +57,5 @@ class TestClass:
|
|||||||
"""Check if calc_countdown returns days, hours and minutes."""
|
"""Check if calc_countdown returns days, hours and minutes."""
|
||||||
# FIXME: This will break when there is 0 seconds/hours/days left
|
# FIXME: This will break when there is 0 seconds/hours/days left
|
||||||
pattern = re.compile(r"\d* (day|days), \d* (hour|hours). \d* (minute|minutes)")
|
pattern = re.compile(r"\d* (day|days), \d* (hour|hours). \d* (minute|minutes)")
|
||||||
countdown = calc_countdown(self.job)
|
countdown = calculate(self.job)
|
||||||
assert pattern.match(countdown)
|
assert pattern.match(countdown)
|
||||||
|
Reference in New Issue
Block a user