feat(aurora): migrated to Red's builtin timedelta/relativedelta parsing
All checks were successful
Actions / Lint Code (Ruff & Pylint) (push) Successful in 26s
Actions / Build Documentation (MkDocs) (push) Successful in 20s

This commit is contained in:
Seaswimmer 2024-03-08 14:19:48 -05:00
parent 6035aea5c6
commit f4efcb8ea5
Signed by: cswimr
GPG key ID: B8953EC01E5C4063
5 changed files with 50 additions and 62 deletions

View file

@ -15,12 +15,11 @@ from math import ceil
import discord
import humanize
from discord.ext import tasks
from pytimeparse2 import disable_dateutil, parse
from redbot.core import app_commands, commands, data_manager
from redbot.core.app_commands import Choice
from redbot.core.bot import Red
from redbot.core.utils.chat_formatting import (box, error, humanize_list,
warning)
from redbot.core.commands.converter import parse_relativedelta, parse_timedelta
from redbot.core.utils.chat_formatting import box, error, humanize_list, warning
from aurora.importers.aurora import ImportAuroraView
from aurora.importers.galacticbot import ImportGalacticBotView
@ -29,17 +28,10 @@ from aurora.menus.guild import Guild
from aurora.menus.immune import Immune
from aurora.menus.overrides import Overrides
from aurora.utilities.config import config, register_config
from aurora.utilities.database import (connect, create_guild_table, fetch_case,
mysql_log)
from aurora.utilities.factory import (addrole_embed, case_factory,
changes_factory, evidenceformat_factory,
guild_embed, immune_embed,
message_factory, overrides_embed)
from aurora.utilities.database import connect, create_guild_table, fetch_case, mysql_log
from aurora.utilities.factory import addrole_embed, case_factory, changes_factory, evidenceformat_factory, guild_embed, immune_embed, message_factory, overrides_embed
from aurora.utilities.logger import logger
from aurora.utilities.utils import (check_moddable, check_permissions,
convert_timedelta_to_str,
fetch_channel_dict, fetch_user_dict,
generate_dict, log, send_evidenceformat)
from aurora.utilities.utils import check_moddable, check_permissions, convert_timedelta_to_str, fetch_channel_dict, fetch_user_dict, generate_dict, log, send_evidenceformat, timedelta_from_relativedelta
class Aurora(commands.Cog):
@ -84,7 +76,6 @@ class Aurora(commands.Cog):
super().__init__()
self.bot = bot
register_config(config)
disable_dateutil()
self.handle_expiry.start()
def format_help_for_context(self, ctx: commands.Context) -> str:
@ -332,13 +323,10 @@ class Aurora(commands.Cog):
return
if duration is not None:
try:
parsed_time = parse(
sval=duration, as_timedelta=True, raise_exception=True
)
except ValueError:
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"), ephemeral=True
)
return
else:
@ -440,16 +428,15 @@ class Aurora(commands.Cog):
return
try:
parsed_time = parse(sval=duration, as_timedelta=True, raise_exception=True)
except ValueError:
parsed_time = parse_timedelta(duration, maximum=timedelta(days=28))
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
)
return
if parsed_time.total_seconds() / 1000 > 2419200000:
except commands.BadArgument:
await interaction.response.send_message(
error("Please provide a duration that is less than 28 days.")
error("Please provide a duration that is less than 28 days."), ephemeral=True
)
return
@ -684,15 +671,13 @@ class Aurora(commands.Cog):
pass
if duration:
try:
parsed_time = parse(
sval=duration, as_timedelta=True, raise_exception=True
)
except ValueError:
parsed_time = parse_relativedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"), ephemeral=True
)
return
parsed_time = timedelta_from_relativedelta(parsed_time)
await interaction.response.send_message(
content=f"{target.mention} has been banned for {humanize.precisedelta(parsed_time)}!\n**Reason** - `{reason}`"
@ -1380,11 +1365,8 @@ class Aurora(commands.Cog):
case_dict = await fetch_case(case, interaction.guild.id)
if case_dict:
if duration:
try:
parsed_time = parse(
sval=duration, as_timedelta=True, raise_exception=True
)
except ValueError:
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
)
@ -1700,15 +1682,28 @@ class Aurora(commands.Cog):
)
@aurora.command(aliases=["tdc", "td", "timedeltaconvert"])
async def timedelta(self, ctx: commands.Context, *, duration: str):
async def timedelta(self, ctx: commands.Context, *, duration: str) -> None:
"""This command converts a duration to a [`timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta) Python object.
You cannot convert years or months as they are not fixed units. Use `[p]aurora relativedelta` for that.
**Example usage**
`[p]aurora timedelta 1 day 15hr 82 minutes 52s`
**Output**
`1 day, 16:22:52`"""
try:
parsed_time = parse(duration, as_timedelta=True, raise_exception=True)
await ctx.send(f"`{str(parsed_time)}`")
except ValueError:
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await ctx.send(error("Please provide a convertible value!"))
await ctx.send(f"`{parsed_time}`")
@aurora.command(aliases=["rdc", "rd", "relativedeltaconvert"])
async def relativedelta(self, ctx: commands.Context, *, duration: str) -> None:
"""This command converts a duration to a [`relativedelta`](https://dateutil.readthedocs.io/en/stable/relativedelta.html) Python object.
**Example usage**
`[p]aurora relativedelta 3 years 1 day 15hr 82 minutes 52s`
**Output**
`relativedelta(years=+3, days=+1, hours=+15, minutes=+82, seconds=+52)`"""
parsed_time = parse_relativedelta(duration)
if parsed_time is None:
await ctx.send(error("Please provide a convertible value!"))
await ctx.send(f"`{parsed_time}`")

View file

@ -5,7 +5,7 @@
"short" : "A full replacement for Red's core Mod cogs.",
"description" : "Aurora is a fully-featured moderation system. It is heavily inspired by GalacticBot, and is designed to be a more user-friendly alternative to Red's core Mod cogs. This cog stores all of its data in an SQLite database.",
"end_user_data_statement" : "This cog stores the following information:\n- User IDs of accounts who moderate users or are moderated\n- Guild IDs of guilds with the cog enabled\n- Timestamps of moderations\n- Other information relating to moderations",
"requirements": ["humanize", "pytimeparse2"],
"requirements": ["humanize"],
"hidden": false,
"disabled": false,
"min_bot_version": "3.5.0",

View file

@ -1,8 +1,10 @@
# pylint: disable=cyclic-import
import json
from datetime import datetime
from datetime import timedelta as td
from typing import Union
from dateutil.relativedelta import relativedelta as rd
from discord import Guild, Interaction, Member, SelectOption, User
from discord.errors import Forbidden, NotFound
from redbot.core import commands
@ -283,3 +285,9 @@ def create_pagesize_options() -> list[SelectOption]:
)
)
return options
def timedelta_from_relativedelta(relativedelta: rd) -> td:
"""Converts a relativedelta object to a timedelta object."""
now = datetime.now()
then = now - relativedelta
return now - then

16
poetry.lock generated
View file

@ -1677,20 +1677,6 @@ files = [
[package.dependencies]
six = ">=1.5"
[[package]]
name = "pytimeparse2"
version = "1.7.1"
description = "Time expression parser."
optional = false
python-versions = ">=3.6"
files = [
{file = "pytimeparse2-1.7.1-py3-none-any.whl", hash = "sha256:a162ea6a7707fd0bb82dd99556efb783935f51885c8bdced0fce3fffe85ab002"},
{file = "pytimeparse2-1.7.1.tar.gz", hash = "sha256:98668cdcba4890e1789e432e8ea0059ccf72402f13f5d52be15bdfaeb3a8b253"},
]
[package.extras]
dateutil = ["python-dateutil (>=2.8.2,<2.9.0)"]
[[package]]
name = "pytz"
version = "2023.3.post1"
@ -2536,4 +2522,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = ">=3.11,<3.12"
content-hash = "a32cda21d6b46347f4432a29a4f4b7b030b36406e030c839a55112670fa335e5"
content-hash = "b10a8c8d11a74351402e4663ba61655905a1939aa72701f9905c8a63bfd8f1ed"

View file

@ -9,7 +9,6 @@ readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.11,<3.12"
Red-DiscordBot = "^3.5.5"
pytimeparse2 = "^1.7.1"
humanize = "^4.8.0"
py-dactyl = "^2.0.4"
websockets = "^12.0"