feat(shard): ✨ Add p.bans command for moderators to see a user's bans.
This commit is contained in:
+5
-2
@@ -21,8 +21,6 @@ class Payphone(commands.AutoShardedBot):
|
||||
host=constants.REDIS_HOST, port=constants.REDIS_PORT, decode_responses=True
|
||||
)
|
||||
|
||||
owner_id = 657091104877051907
|
||||
|
||||
def __init__(self):
|
||||
intents = discord.Intents.default()
|
||||
intents.guilds = True
|
||||
@@ -49,6 +47,11 @@ class Payphone(commands.AutoShardedBot):
|
||||
|
||||
self.call_handler = calls.CallHandler(self)
|
||||
|
||||
self.owner_ids = [
|
||||
657091104877051907, # Anastasia
|
||||
1338608911208419471, # Rafael
|
||||
]
|
||||
|
||||
async def on_ready(self) -> None:
|
||||
"""Runs when the bot has finished initializing."""
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from discord.ext import commands, pages
|
||||
|
||||
from payphone.db import models
|
||||
from payphone.bot import Payphone
|
||||
from payphone.cogs import base
|
||||
from payphone.cogs.admin import embeds, views
|
||||
from payphone.core import checks
|
||||
from payphone.core import checks, constants, formatting
|
||||
|
||||
|
||||
class Admin(base.Cog):
|
||||
@@ -147,6 +147,82 @@ class Admin(base.Cog):
|
||||
embed=embeds.report_embed(report), view=views.ReportView(self.bot, report)
|
||||
)
|
||||
|
||||
@commands.command()
|
||||
@checks.is_moderator()
|
||||
async def bans(self, ctx: commands.Context, user: discord.User | int) -> None:
|
||||
"""Shows all bans of a specific user.
|
||||
|
||||
Options:
|
||||
- `<user>`: The user to show the bans of.
|
||||
|
||||
Permissions:
|
||||
- Bot Moderator
|
||||
"""
|
||||
|
||||
user_id = user if isinstance(user, int) else user.id
|
||||
|
||||
bans = (
|
||||
await models.Ban.filter(user_id=user_id)
|
||||
.prefetch_related("report", "created_by")
|
||||
.order_by("-created_at")
|
||||
)
|
||||
|
||||
if not bans:
|
||||
await ctx.send(f"<@!{user_id}> has no bans.")
|
||||
return
|
||||
|
||||
await pages.Paginator(
|
||||
[
|
||||
(
|
||||
discord.Embed(
|
||||
color=constants.PRIMARY_COLOR,
|
||||
title=f"Ban #{ban.id}",
|
||||
description=formatting.trim(ban.report.message_content, 500),
|
||||
author=discord.EmbedAuthor(
|
||||
name=ban.report.user_name,
|
||||
icon_url=ban.report.user_avatar_url,
|
||||
),
|
||||
fields=[
|
||||
discord.EmbedField(
|
||||
name="Banned Until",
|
||||
value=(
|
||||
f"<t:{int(ban.expires_at.timestamp())}> (<t:{int(ban.expires_at.timestamp())}:R>)"
|
||||
if ban.expires_at
|
||||
else "Forever"
|
||||
),
|
||||
),
|
||||
discord.EmbedField(
|
||||
name="User Avatar",
|
||||
value=f"[Click to open avatar URL](<{ban.report.user_avatar_url}>)",
|
||||
),
|
||||
]
|
||||
+ (
|
||||
[
|
||||
discord.EmbedField(
|
||||
name="Replying To",
|
||||
value=f'"{formatting.trim(ban.report.reply_message_content)}" by {ban.report.reply_user_name}',
|
||||
)
|
||||
]
|
||||
if ban.report.reply_message_content
|
||||
else []
|
||||
),
|
||||
thumbnail=ban.report.user_avatar_url,
|
||||
footer=discord.EmbedFooter(
|
||||
text=f"Banned by {(await self.bot.get_or_fetch_user(ban.created_by.id)).display_name}"
|
||||
),
|
||||
)
|
||||
if ban.report
|
||||
else discord.Embed(
|
||||
color=constants.PRIMARY_COLOR,
|
||||
title=f"Ban #{ban.id}",
|
||||
description=f"The user was banned manually by <@!{ban.created_by.id}> <t:{int(ban.created_at.timestamp())}:R>.",
|
||||
)
|
||||
)
|
||||
for ban in bans
|
||||
],
|
||||
author_check=True,
|
||||
).send(ctx)
|
||||
|
||||
|
||||
def setup(bot: Payphone) -> None:
|
||||
"""Loads the Admin cog into the bot.
|
||||
|
||||
@@ -88,11 +88,8 @@ class ReportView(discord.ui.View):
|
||||
name="User Name",
|
||||
value=self.report.user_name,
|
||||
),
|
||||
discord.EmbedField(
|
||||
name="User Avatar",
|
||||
value=f"[Click to open your avatar URL](<{self.report.user_avatar_url}>)",
|
||||
),
|
||||
],
|
||||
thumbnail=self.report.user_avatar_url,
|
||||
footer=discord.EmbedFooter(
|
||||
text="⚠️ Repeating this action will result in a ban."
|
||||
),
|
||||
@@ -142,10 +139,6 @@ class ReportView(discord.ui.View):
|
||||
name="User Name",
|
||||
value=self.report.user_name,
|
||||
),
|
||||
discord.EmbedField(
|
||||
name="User Avatar",
|
||||
value=f"[Click to open your avatar URL](<{self.report.user_avatar_url}>)",
|
||||
),
|
||||
discord.EmbedField(
|
||||
name="Expires At",
|
||||
value=(
|
||||
@@ -156,6 +149,7 @@ class ReportView(discord.ui.View):
|
||||
),
|
||||
),
|
||||
],
|
||||
thumbnail=self.report.user_avatar_url,
|
||||
footer=discord.EmbedFooter(
|
||||
text=(
|
||||
"⚠️ In case you get banned again, your ban will last longer. Multiple bans will result in a permanent ban."
|
||||
|
||||
@@ -496,6 +496,20 @@ class Calls(base.Cog):
|
||||
|
||||
await ctx.send_response("✅ The message has been reported.", ephemeral=True)
|
||||
|
||||
replying_to = (
|
||||
await self.bot.get_partial_messageable(
|
||||
message.reference.channel_id
|
||||
).fetch_message(message.reference.message_id)
|
||||
if message.reference and not message.reference.cached_message
|
||||
else (
|
||||
message.reference.cached_message
|
||||
if message.reference and message.reference.cached_message
|
||||
else None
|
||||
)
|
||||
)
|
||||
|
||||
self.bot.log.info(replying_to)
|
||||
|
||||
await models.Report.update_or_create(
|
||||
message_id=message_id,
|
||||
defaults={
|
||||
@@ -504,6 +518,16 @@ class Calls(base.Cog):
|
||||
"user_name": message.author.display_name,
|
||||
"user_avatar_url": message.author.display_avatar.url,
|
||||
"message_content": message.content,
|
||||
"reply_message_content": (
|
||||
replying_to.clean_content if replying_to else None
|
||||
),
|
||||
"reply_user_id": (replying_to.author.id if replying_to else None),
|
||||
"reply_user_name": (
|
||||
replying_to.author.display_name if replying_to else None
|
||||
),
|
||||
"reply_user_avatar_url": (
|
||||
replying_to.author.display_avatar.url if replying_to else None
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX "idx_channel_server__d940e4";
|
||||
DROP INDEX "idx_ban_user_id_37a9cf";
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE BIGINT USING "report_id"::BIGINT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE BIGINT USING "report_id"::BIGINT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE BIGINT USING "report_id"::BIGINT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE BIGINT USING "report_id"::BIGINT;
|
||||
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
|
||||
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX "idx_channel_server__d940e4";
|
||||
DROP INDEX "idx_ban_user_id_37a9cf";
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE INT USING "report_id"::INT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE INT USING "report_id"::INT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE INT USING "report_id"::INT;
|
||||
ALTER TABLE "ban" ALTER COLUMN "report_id" TYPE INT USING "report_id"::INT;
|
||||
CREATE INDEX "idx_ban_user_id_37a9cf" ON "ban" ("user_id", "expires_at");;
|
||||
CREATE INDEX "idx_channel_server__d940e4" ON "channel" ("server_id", "is_enabled");;"""
|
||||
@@ -0,0 +1,15 @@
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "report" ADD "reply_user_name" TEXT;
|
||||
ALTER TABLE "report" ADD "reply_message_content" TEXT;
|
||||
ALTER TABLE "report" ADD "reply_user_avatar_url" TEXT;"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "report" DROP COLUMN "reply_user_name";
|
||||
ALTER TABLE "report" DROP COLUMN "reply_message_content";
|
||||
ALTER TABLE "report" DROP COLUMN "reply_user_avatar_url";"""
|
||||
@@ -0,0 +1,11 @@
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "report" ADD "reply_user_id" BIGINT;"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "report" DROP COLUMN "reply_user_id";"""
|
||||
@@ -14,12 +14,18 @@ class Report(models.Model):
|
||||
A report of a message.
|
||||
"""
|
||||
|
||||
id = fields.BigIntField(pk=True)
|
||||
|
||||
message_id = fields.BigIntField(unique=True)
|
||||
message_content = fields.TextField()
|
||||
channel_id = fields.BigIntField()
|
||||
user_id = fields.BigIntField()
|
||||
user_name = fields.TextField()
|
||||
user_avatar_url = fields.TextField()
|
||||
reply_message_content = fields.TextField(null=True, default=None)
|
||||
reply_user_id = fields.BigIntField(null=True)
|
||||
reply_user_name = fields.TextField(null=True, default=None)
|
||||
reply_user_avatar_url = fields.TextField(null=True, default=None)
|
||||
created_at = fields.DatetimeField(auto_now_add=True)
|
||||
resolved = fields.BooleanField(default=False, index=True)
|
||||
resolved_at = fields.DatetimeField(null=True)
|
||||
|
||||
Reference in New Issue
Block a user