mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-09-30 17:17:35 +13:00
135 lines
4.5 KiB
Python
135 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import dataclasses
|
|
from datetime import datetime, timedelta, timezone
|
|
from typing import NamedTuple, Optional, Tuple
|
|
|
|
from redbot.core.commands import BadArgument, Context
|
|
|
|
from .time_utils import parse_time, parse_timedelta
|
|
|
|
|
|
class NonNumeric(NamedTuple):
|
|
parsed: str
|
|
|
|
@classmethod
|
|
async def convert(cls, context: Context, argument: str):
|
|
if argument.isdigit():
|
|
raise BadArgument("Event names must contain at least 1 non-numeric value")
|
|
return cls(argument)
|
|
|
|
|
|
class NoExitParser(argparse.ArgumentParser):
|
|
def error(self, message):
|
|
raise BadArgument()
|
|
|
|
|
|
@dataclasses.dataclass()
|
|
class Schedule:
|
|
start: datetime
|
|
command: str
|
|
recur: Optional[timedelta] = None
|
|
quiet: bool = False
|
|
|
|
def to_tuple(self) -> Tuple[str, datetime, Optional[timedelta]]:
|
|
return self.command, self.start, self.recur
|
|
|
|
@classmethod
|
|
async def convert(cls, ctx: Context, argument: str):
|
|
|
|
start: datetime
|
|
command: Optional[str] = None
|
|
recur: Optional[timedelta] = None
|
|
|
|
command, *arguments = argument.split(" -- ")
|
|
if arguments:
|
|
argument = " -- ".join(arguments)
|
|
else:
|
|
command = None
|
|
|
|
parser = NoExitParser(description="Scheduler event parsing", add_help=False)
|
|
parser.add_argument("-q", "--quiet", action="store_true", dest="quiet", default=False)
|
|
parser.add_argument("--every", nargs="*", dest="every", default=[])
|
|
if not command:
|
|
parser.add_argument("command", nargs="*")
|
|
at_or_in = parser.add_mutually_exclusive_group()
|
|
at_or_in.add_argument("--start-at", nargs="*", dest="at", default=[])
|
|
at_or_in.add_argument("--start-in", nargs="*", dest="in", default=[])
|
|
|
|
try:
|
|
vals = vars(parser.parse_args(argument.split(" ")))
|
|
except Exception as exc:
|
|
raise BadArgument() from exc
|
|
|
|
if not (vals["at"] or vals["in"]):
|
|
raise BadArgument("You must provide one of `--start-in` or `--start-at`")
|
|
|
|
if not command and not vals["command"]:
|
|
raise BadArgument("You have to provide a command to run")
|
|
|
|
command = command or " ".join(vals["command"])
|
|
|
|
for delta in ("in", "every"):
|
|
if vals[delta]:
|
|
parsed = parse_timedelta(" ".join(vals[delta]))
|
|
if not parsed:
|
|
raise BadArgument("I couldn't understand that time interval")
|
|
|
|
if delta == "in":
|
|
start = datetime.now(timezone.utc) + parsed
|
|
else:
|
|
recur = parsed
|
|
if recur.total_seconds() < 60:
|
|
raise BadArgument(
|
|
"You can't schedule something to happen that frequently, " "I'll get ratelimited."
|
|
)
|
|
|
|
if vals["at"]:
|
|
try:
|
|
start = parse_time(" ".join(vals["at"]))
|
|
except Exception:
|
|
raise BadArgument("I couldn't understand that starting time.") from None
|
|
|
|
return cls(command=command, start=start, recur=recur, quiet=vals["quiet"])
|
|
|
|
|
|
class TempMute(NamedTuple):
|
|
reason: Optional[str]
|
|
start: datetime
|
|
|
|
@classmethod
|
|
async def convert(cls, ctx: Context, argument: str):
|
|
|
|
start: datetime
|
|
reason: str
|
|
|
|
parser = NoExitParser(description="Scheduler event parsing", add_help=False)
|
|
parser.add_argument("reason", nargs="*")
|
|
at_or_in = parser.add_mutually_exclusive_group()
|
|
at_or_in.add_argument("--until", nargs="*", dest="until", default=[])
|
|
at_or_in.add_argument("--for", nargs="*", dest="for", default=[])
|
|
|
|
try:
|
|
vals = vars(parser.parse_args(argument.split()))
|
|
except Exception as exc:
|
|
raise BadArgument() from exc
|
|
|
|
if not (vals["until"] or vals["for"]):
|
|
raise BadArgument("You must provide one of `--until` or `--for`")
|
|
|
|
reason = " ".join(vals["reason"])
|
|
|
|
if vals["for"]:
|
|
parsed = parse_timedelta(" ".join(vals["for"]))
|
|
if not parsed:
|
|
raise BadArgument("I couldn't understand that time interval")
|
|
start = datetime.now(timezone.utc) + parsed
|
|
|
|
if vals["until"]:
|
|
try:
|
|
start = parse_time(" ".join(vals["at"]))
|
|
except Exception:
|
|
raise BadArgument("I couldn't understand that unmute time.") from None
|
|
|
|
return cls(reason, start)
|