diff --git a/payphone/cogs/mods/cog.py b/payphone/cogs/mods/cog.py index 9ccb5c4..4104091 100644 --- a/payphone/cogs/mods/cog.py +++ b/payphone/cogs/mods/cog.py @@ -450,14 +450,21 @@ class Mods(base.Cog): profile: models.Profile | None = user.profiles[0] if user is not None else None bans = await models.Ban.filter( - expressions.Q( - expires_at=None, - expires_at__gt=datetime.now(timezone.utc), - join_type="OR", - ), user_id=user_id, ) + ongoing_bans = [ + ban + for ban in bans + if ban.expires_at is None or ban.expires_at > datetime.now(timezone.utc) + ] + expired_bans = [ + ban + for ban in bans + if ban.expires_at is not None + and ban.expires_at < datetime.now(timezone.utc) + ] + embed = discord.Embed( color=( (profile.color or constants.EMBED_COLOR) @@ -472,11 +479,21 @@ class Mods(base.Cog): value="\n".join( [ f"- `ID: {ban.id}`{f" (by <@{ban.banned_by_id}>)" if ban.banned_by_id else None}: {ban.reason if ban.reason else "*No reason*"}. Banned {f"until " if ban.expires_at is not None else "permanently"}." - for ban in bans + for ban in ongoing_bans ] ) or "*No ongoing bans.*", - ) + ), + discord.EmbedField( + name="Past Bans", + value="\n".join( + [ + f"- `ID: {ban.id}`{f" (by <@{ban.banned_by_id}>)" if ban.banned_by_id else None}: {ban.reason if ban.reason else "*No reason*"}. {"Expired" if ban.unbanned_by_id is None else f"Unbanned by <@{ban.unbanned_by_id}>"} ." + for ban in expired_bans + ] + ) + or "*No expired bans.*", + ), ], author=( profile.embed_author if profile is not None else self.bot.embed_author diff --git a/payphone/db/migrations/models/15_20241025225628_update.py b/payphone/db/migrations/models/15_20241025225628_update.py new file mode 100644 index 0000000..ce37ea4 --- /dev/null +++ b/payphone/db/migrations/models/15_20241025225628_update.py @@ -0,0 +1,19 @@ +from tortoise import BaseDBAsyncClient + + +async def upgrade(db: BaseDBAsyncClient) -> str: + return """ + DROP INDEX "idx_ban_user_id_37a9cf"; + ALTER TABLE "ban" ADD "unbanned_by_id" BIGINT; + CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");; + ALTER TABLE "ban" ADD CONSTRAINT "fk_ban_user_e41857cf" FOREIGN KEY ("unbanned_by_id") REFERENCES "user" ("id") ON DELETE CASCADE; + CREATE INDEX "idx_report_status_d6b157" ON "report" ("status", "priority");;""" + + +async def downgrade(db: BaseDBAsyncClient) -> str: + return """ + DROP INDEX "idx_report_status_d6b157"; + ALTER TABLE "ban" DROP CONSTRAINT "fk_ban_user_e41857cf"; + DROP INDEX "idx_ban_user_id_37a9cf"; + ALTER TABLE "ban" DROP COLUMN "unbanned_by_id"; + CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");""" diff --git a/payphone/db/models.py b/payphone/db/models.py index 399b326..60c8179 100644 --- a/payphone/db/models.py +++ b/payphone/db/models.py @@ -2,7 +2,7 @@ from datetime import datetime import enum -from tortoise import models, fields +from tortoise import models, fields, indexes import discord from discord import webhook @@ -375,6 +375,9 @@ class Report(models.Model): ) created_at: datetime = fields.DatetimeField(auto_now_add=True) + class Meta: + indexes = [indexes.Index(fields=("status", "priority"))] + class Ban(models.Model): user_id: int = fields.BigIntField() @@ -389,8 +392,11 @@ class Ban(models.Model): banned_by: fields.ForeignKeyRelation["User"] = fields.ForeignKeyField( "models.User", related_name="bans_created", null=True ) + unbanned_by: fields.ForeignKeyNullableRelation["User"] = fields.ForeignKeyField( + "models.User", related_name="bans_removed", null=True, default=None + ) created_at: datetime = fields.DatetimeField(auto_now_add=True, db_index=True) expires_at: datetime | None = fields.DatetimeField(null=True) class Meta: - indexes = [("user_id", "expires_at"), ("status", "priority")] + indexes = [indexes.Index(fields=("user_id", "expires_at"))]