feat(shard): ✨ Add duration and reason arguments to p.ban.
This commit is contained in:
+4
-2
@@ -287,6 +287,7 @@ class Payphone(commands.AutoShardedBot):
|
|||||||
report: models.Report | None,
|
report: models.Report | None,
|
||||||
expires_at: datetime | None,
|
expires_at: datetime | None,
|
||||||
created_by_id: int | None,
|
created_by_id: int | None,
|
||||||
|
reason: str | None = None,
|
||||||
) -> models.Ban:
|
) -> models.Ban:
|
||||||
"""Bans a user.
|
"""Bans a user.
|
||||||
|
|
||||||
@@ -295,7 +296,8 @@ class Payphone(commands.AutoShardedBot):
|
|||||||
report (Report | None): The report that caused the ban.
|
report (Report | None): The report that caused the ban.
|
||||||
expires_at (datetime | None): When the ban expires.
|
expires_at (datetime | None): When the ban expires.
|
||||||
created_by_id (int | None): The ID of the user who created the ban.
|
created_by_id (int | None): The ID of the user who created the ban.
|
||||||
|
reason (str | None): The reason for the ban.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(Ban): The ban.
|
(Ban): The ban.
|
||||||
"""
|
"""
|
||||||
@@ -305,6 +307,7 @@ class Payphone(commands.AutoShardedBot):
|
|||||||
report=report,
|
report=report,
|
||||||
expires_at=expires_at,
|
expires_at=expires_at,
|
||||||
created_by_id=created_by_id,
|
created_by_id=created_by_id,
|
||||||
|
reason=reason,
|
||||||
)
|
)
|
||||||
|
|
||||||
await ban.save()
|
await ban.save()
|
||||||
@@ -456,7 +459,6 @@ def run():
|
|||||||
sentry_sdk.init(
|
sentry_sdk.init(
|
||||||
constants.SENTRY_DSN,
|
constants.SENTRY_DSN,
|
||||||
environment="development" if constants.IS_DEBUG else "production",
|
environment="development" if constants.IS_DEBUG else "production",
|
||||||
debug=constants.IS_DEBUG,
|
|
||||||
server_name=f"Shard #{constants.SHARD_ID + 1}",
|
server_name=f"Shard #{constants.SHARD_ID + 1}",
|
||||||
attach_stacktrace=True,
|
attach_stacktrace=True,
|
||||||
send_default_pii=True,
|
send_default_pii=True,
|
||||||
|
|||||||
@@ -51,12 +51,19 @@ class Admin(base.Cog):
|
|||||||
@commands.command(aliases=["b"])
|
@commands.command(aliases=["b"])
|
||||||
@checks.is_moderator()
|
@checks.is_moderator()
|
||||||
async def ban(
|
async def ban(
|
||||||
self, ctx: commands.Context, user: discord.User | int | None = None
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
user: discord.User | int | None = None,
|
||||||
|
duration: str | None = None,
|
||||||
|
*,
|
||||||
|
reason: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Bans the user from the bot.
|
"""Bans the user from the bot.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
- `[user]`: The user to ban or their ID. If none is provided, the author will be banned.
|
- `[user]`: The user to ban or their ID. If none is provided, the author will be banned.
|
||||||
|
- `[duration]`: The duration of the ban (e.g 5d, 4h, 1M). If none is provided, the ban will be permanent.
|
||||||
|
- `[reason]`: The reason for the ban.
|
||||||
|
|
||||||
Permissions:
|
Permissions:
|
||||||
- Bot Moderator
|
- Bot Moderator
|
||||||
@@ -64,7 +71,21 @@ class Admin(base.Cog):
|
|||||||
|
|
||||||
user_id = user if isinstance(user, int) else user.id if user else ctx.author.id
|
user_id = user if isinstance(user, int) else user.id if user else ctx.author.id
|
||||||
|
|
||||||
await self.bot.ban(user_id, None, None, ctx.author.id)
|
if duration:
|
||||||
|
try:
|
||||||
|
duration = formatting.parse_timedelta(duration)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
reason = f"{duration} {reason}" if reason else duration
|
||||||
|
duration = None
|
||||||
|
|
||||||
|
await self.bot.ban(
|
||||||
|
user_id,
|
||||||
|
None,
|
||||||
|
datetime.now(timezone.utc) + duration if duration else None,
|
||||||
|
ctx.author.id,
|
||||||
|
reason,
|
||||||
|
)
|
||||||
|
|
||||||
await ctx.send(f"<@!{user_id}> was banned from Payphone.")
|
await ctx.send(f"<@!{user_id}> was banned from Payphone.")
|
||||||
|
|
||||||
@@ -149,17 +170,19 @@ class Admin(base.Cog):
|
|||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@checks.is_moderator()
|
@checks.is_moderator()
|
||||||
async def bans(self, ctx: commands.Context, user: discord.User | int) -> None:
|
async def bans(
|
||||||
|
self, ctx: commands.Context, user: discord.User | int | None = None
|
||||||
|
) -> None:
|
||||||
"""Shows all bans of a specific user.
|
"""Shows all bans of a specific user.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
- `<user>`: The user to show the bans of.
|
- `[user]`: The user to show the bans of.
|
||||||
|
|
||||||
Permissions:
|
Permissions:
|
||||||
- Bot Moderator
|
- Bot Moderator
|
||||||
"""
|
"""
|
||||||
|
|
||||||
user_id = user if isinstance(user, int) else user.id
|
user_id = user if isinstance(user, int) else user.id if user else ctx.author.id
|
||||||
|
|
||||||
bans = (
|
bans = (
|
||||||
await models.Ban.filter(user_id=user_id)
|
await models.Ban.filter(user_id=user_id)
|
||||||
@@ -175,7 +198,7 @@ class Admin(base.Cog):
|
|||||||
[
|
[
|
||||||
(
|
(
|
||||||
discord.Embed(
|
discord.Embed(
|
||||||
color=constants.PRIMARY_COLOR,
|
color=constants.MODERATOR_COLOR,
|
||||||
title=f"Ban #{ban.id}",
|
title=f"Ban #{ban.id}",
|
||||||
description=formatting.trim(ban.report.message_content, 500),
|
description=formatting.trim(ban.report.message_content, 500),
|
||||||
author=discord.EmbedAuthor(
|
author=discord.EmbedAuthor(
|
||||||
@@ -218,9 +241,14 @@ class Admin(base.Cog):
|
|||||||
)
|
)
|
||||||
if ban.report
|
if ban.report
|
||||||
else discord.Embed(
|
else discord.Embed(
|
||||||
color=constants.PRIMARY_COLOR,
|
color=constants.MODERATOR_COLOR,
|
||||||
title=f"Ban #{ban.id}",
|
title=f"Ban #{ban.id}",
|
||||||
description=f"The user was banned manually by <@!{ban.created_by.id}> <t:{int(ban.created_at.timestamp())}:R>. It expires {f"<t:{int(ban.expires_at.timestamp())}:R>" if ban.expires_at else "never"}.",
|
description=f"The user was banned manually by <@!{ban.created_by.id}> <t:{int(ban.created_at.timestamp())}:R>. {(f"It expires <t:{int(ban.expires_at.timestamp())}:R>" if not ban.is_expired else f"It expired <t:{int(ban.expires_at.timestamp())}:R>") if ban.expires_at else "It doesn't expire"}.",
|
||||||
|
fields=[
|
||||||
|
discord.EmbedField(
|
||||||
|
name="Reason", value=ban.reason or "No reason provided."
|
||||||
|
)
|
||||||
|
],
|
||||||
footer=discord.EmbedFooter(
|
footer=discord.EmbedFooter(
|
||||||
text=f"Banned by {(await self.bot.get_or_fetch_user(ban.created_by.id)).display_name}"
|
text=f"Banned by {(await self.bot.get_or_fetch_user(ban.created_by.id)).display_name}"
|
||||||
+ (
|
+ (
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ def parse_timedelta(text: str) -> timedelta:
|
|||||||
)
|
)
|
||||||
matches = pattern.match(text.strip())
|
matches = pattern.match(text.strip())
|
||||||
|
|
||||||
if not matches:
|
if matches.span() == (0, 0):
|
||||||
raise ValueError("Invalid time string format")
|
raise ValueError("Invalid time string format")
|
||||||
|
|
||||||
years, months, weeks, days, hours, minutes, seconds = matches.groups()
|
years, months, weeks, days, hours, minutes, seconds = matches.groups()
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
from tortoise import BaseDBAsyncClient
|
||||||
|
|
||||||
|
|
||||||
|
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||||
|
return """
|
||||||
|
ALTER TABLE "ban" ADD "reason" TEXT;"""
|
||||||
|
|
||||||
|
|
||||||
|
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||||
|
return """
|
||||||
|
ALTER TABLE "ban" DROP COLUMN "reason";"""
|
||||||
@@ -146,11 +146,20 @@ class Ban(models.Model):
|
|||||||
|
|
||||||
user_id = fields.BigIntField()
|
user_id = fields.BigIntField()
|
||||||
report = fields.ForeignKeyField("models.Report", null=True)
|
report = fields.ForeignKeyField("models.Report", null=True)
|
||||||
|
reason = fields.TextField(null=True, default=None)
|
||||||
created_at = fields.DatetimeField(auto_now_add=True)
|
created_at = fields.DatetimeField(auto_now_add=True)
|
||||||
expires_at = fields.DatetimeField(null=True)
|
expires_at = fields.DatetimeField(null=True)
|
||||||
created_by = fields.ForeignKeyField("models.User", related_name="created_bans")
|
created_by = fields.ForeignKeyField("models.User", related_name="created_bans")
|
||||||
expired_by = fields.ForeignKeyField("models.User", related_name="expired_bans", null=True)
|
expired_by = fields.ForeignKeyField("models.User", related_name="expired_bans", null=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_expired(self) -> bool:
|
||||||
|
"""
|
||||||
|
Whether the ban is expired.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.expires_at is not None and self.expires_at < datetime.now(timezone.utc)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Meta information.
|
Meta information.
|
||||||
|
|||||||
Reference in New Issue
Block a user