Files
payphone/payphone/core/converters.py
T

80 lines
2.4 KiB
Python

from datetime import timedelta
from discord.ext import commands
from discord.ext.commands import converter
from tortoise import expressions
from payphone.db import models
from payphone.core import exceptions
class Timedelta(converter.Converter):
"""Converts a string like "1d 2h" to a `datetime.timedelta` object."""
async def convert(self, _ctx: commands.Context, argument: str) -> timedelta:
multipliers = {
"s": 1,
"m": 60,
"h": 60 * 60,
"d": 60 * 60 * 24,
"w": 60 * 60 * 24 * 7,
"M": 60 * 60 * 24 * 30,
"y": 60 * 60 * 24 * 365,
}
if argument[-1] in multipliers:
try:
unit = multipliers[argument[-1]]
quantity = float(argument[:-1])
return timedelta(seconds=unit * quantity)
except Exception as e:
raise exceptions.InvalidTimedeltaError(
f'"{argument}" is not a valid time delta.'
) from e
raise exceptions.InvalidTimedeltaError(
f'"{argument}" is not a valid time delta.'
)
class DiscordUserID(converter.Converter):
"""Converts a URL, ID, or reply into a Discord User ID."""
async def convert(self, ctx: commands.Context, argument: str) -> int:
if len(argument) > 17 and argument[:2] == "<@" and argument[-1] == ">":
return int(argument[2:-1])
if argument.isdecimal() and len(argument) in range(17, 19):
return int(argument)
if argument.startswith("https://discord.com/users/") or argument.startswith(
"discord://-/users/"
):
return int(argument.split("?", 1)[0].rsplit("/", 1)[1])
if argument.lower() in ["reply", "."]:
if ctx.message.reference is not None:
ref = ctx.message.reference
msg = ref.cached_message or await ctx.channel().fetch_message(
ref.message_id
)
if msg.author.bot:
row = await models.Message.get_or_none(
expressions.Q(id=msg.id, propagation_id=msg.id, join_type="OR")
)
if row is not None:
return row.user_id
raise converter.BadArgument()
else:
return msg.author.id
raise converter.BadArgument()