feat(bot): ✨ Make ban durations stack.
This commit is contained in:
+20
-3
@@ -1,6 +1,6 @@
|
||||
from typing import Literal
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
import discord
|
||||
from discord import abc
|
||||
@@ -147,7 +147,7 @@ class Payphone(commands.AutoShardedBot):
|
||||
async def ban(
|
||||
self,
|
||||
user: discord.User | discord.Member | models.User | int,
|
||||
until: datetime | None,
|
||||
duration: timedelta | None,
|
||||
reason: str,
|
||||
moderator: discord.User | discord.Member | models.User | int | None = None,
|
||||
) -> models.Ban:
|
||||
@@ -155,7 +155,7 @@ class Payphone(commands.AutoShardedBot):
|
||||
|
||||
Args:
|
||||
user (discord.User | discord.Member | models.User | int): The user to ban or their ID.
|
||||
until (datetime | None): The expiry date, or None if it does not expire.
|
||||
duration (timedelta | None): The expiry date, or None if it does not expire.
|
||||
reason (str): The reason of the ban.
|
||||
moderator (discord.User | discord.Member | models.User | int | None, optional): The
|
||||
moderator who performed the action.
|
||||
@@ -173,6 +173,23 @@ class Payphone(commands.AutoShardedBot):
|
||||
else moderator
|
||||
)
|
||||
|
||||
until = datetime.now(timezone.utc) + duration if duration is not None else None
|
||||
|
||||
if duration is not None:
|
||||
last_ban = (
|
||||
await models.Ban.filter(user_id=user_id)
|
||||
.order_by("-created_at")
|
||||
.limit(1)
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_ban is not None:
|
||||
until = (
|
||||
duration + last_ban.expires_at
|
||||
if last_ban.expires_at is not None
|
||||
else None
|
||||
)
|
||||
|
||||
row = await models.Ban.create(
|
||||
user_id=user_id,
|
||||
reason=reason,
|
||||
|
||||
@@ -31,7 +31,7 @@ class Mods(base.Cog):
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
user: converters.DiscordUserID,
|
||||
time: converters.Timedelta | None = None,
|
||||
duration: converters.Timedelta | None = None,
|
||||
*,
|
||||
reason: str | None = "",
|
||||
) -> None:
|
||||
@@ -40,7 +40,7 @@ class Mods(base.Cog):
|
||||
|
||||
Options:
|
||||
- `<user>`: The user to ban or their ID.
|
||||
- `[<time>]`: The amount of time to ban the user for. For example, `1d 5h`.
|
||||
- `[<duration>]`: The amount of time to ban the user for. For example, `1d 5h`.
|
||||
- `[<reason>]`: The reason of their ban.
|
||||
"""
|
||||
|
||||
@@ -50,7 +50,7 @@ class Mods(base.Cog):
|
||||
|
||||
row = await self.bot.ban(
|
||||
user_id,
|
||||
(datetime.now(timezone.utc) + time) if time is not None else None,
|
||||
duration,
|
||||
reason,
|
||||
ctx.author,
|
||||
)
|
||||
@@ -58,7 +58,10 @@ class Mods(base.Cog):
|
||||
message = f"✅ {f"**{profile.name}**" if profile is not None else f"`ID: {user_id}`"} was banned"
|
||||
|
||||
if row.expires_at:
|
||||
message += f" until <t:{int(row.expires_at.timestamp())}:F> (<t:{int(row.expires_at.timestamp())}:R>)"
|
||||
message += f"{f" for `{fmt.time_to_text(duration)}`" if duration is not None else ""} until <t:{int(row.expires_at.timestamp())}:F> (<t:{int(row.expires_at.timestamp())}:R>)"
|
||||
|
||||
else:
|
||||
message += " permanently"
|
||||
|
||||
message += "."
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ class BanUserModal(discord.ui.Modal):
|
||||
|
||||
ban = await self.bot.ban(
|
||||
self.profile.user_id,
|
||||
datetime.now(timezone.utc) + duration if duration is not None else None,
|
||||
duration,
|
||||
self.children[0].value,
|
||||
interaction.user.id,
|
||||
)
|
||||
@@ -120,7 +120,10 @@ class BanUserModal(discord.ui.Modal):
|
||||
message = f"✅ **{self.profile.name}** (User ID: {self.profile.user_id}) was banned by {interaction.user.mention}"
|
||||
|
||||
if ban.expires_at is not None:
|
||||
message += f" until <t:{int(ban.expires_at.timestamp())}:F> (<t:{int(ban.expires_at.timestamp())}:R>)"
|
||||
message += f"{f" for `{formatting.time_to_text(duration)}`" if duration is not None else ""} until <t:{int(ban.expires_at.timestamp())}:F> (<t:{int(ban.expires_at.timestamp())}:R>)"
|
||||
|
||||
else:
|
||||
message += " permanently"
|
||||
|
||||
message += "."
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
CREATE INDEX "idx_ban_created_490013" ON "ban" ("created_at");"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX "idx_ban_created_490013";"""
|
||||
@@ -346,7 +346,7 @@ class Ban(models.Model):
|
||||
banned_by: fields.ForeignKeyRelation["User"] = fields.ForeignKeyField(
|
||||
"models.User", related_name="bans_created", null=True
|
||||
)
|
||||
created_at: datetime = fields.DatetimeField(auto_now_add=True)
|
||||
created_at: datetime = fields.DatetimeField(auto_now_add=True, db_index=True)
|
||||
expires_at: datetime | None = fields.DatetimeField(null=True)
|
||||
|
||||
class Meta:
|
||||
|
||||
Reference in New Issue
Block a user