mirror of
https://github.com/allthingslinux/tux.git
synced 2024-10-02 16:43:12 +00:00
Merge pull request #567 from allthingslinux/565-add-poll-ban
565 add poll ban
This commit is contained in:
commit
e2b4fc835d
6 changed files with 249 additions and 1 deletions
|
@ -170,4 +170,6 @@ enum CaseType {
|
|||
UNJAIL
|
||||
SNIPPETUNBAN
|
||||
UNTEMPBAN
|
||||
POLLBAN
|
||||
POLLUNBAN
|
||||
}
|
||||
|
|
|
@ -250,3 +250,31 @@ class ModerationCogBase(commands.Cog):
|
|||
|
||||
await self.send_embed(ctx, embed, log_type="mod")
|
||||
await ctx.send(embed=embed, delete_after=30, ephemeral=True)
|
||||
|
||||
async def is_pollbanned(self, guild_id: int, user_id: int) -> bool:
|
||||
"""
|
||||
Check if a user is poll banned.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
guild_id : int
|
||||
The ID of the guild to check in.
|
||||
user_id : int
|
||||
The ID of the user to check.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if the user is poll banned, False otherwise.
|
||||
"""
|
||||
|
||||
# ban_cases = await self.case_controller.get_all_cases_by_type(guild_id, CaseType.POLLBAN)
|
||||
# unban_cases = await self.case_controller.get_all_cases_by_type(guild_id, CaseType.POLLUNBAN)
|
||||
|
||||
ban_cases = await self.db.case.get_all_cases_by_type(guild_id, CaseType.POLLBAN)
|
||||
unban_cases = await self.db.case.get_all_cases_by_type(guild_id, CaseType.POLLUNBAN)
|
||||
|
||||
ban_count = sum(case.case_user_id == user_id for case in ban_cases)
|
||||
unban_count = sum(case.case_user_id == user_id for case in unban_cases)
|
||||
|
||||
return ban_count > unban_count
|
||||
|
|
71
tux/cogs/moderation/pollban.py
Normal file
71
tux/cogs/moderation/pollban.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from tux.bot import Tux
|
||||
from tux.database.controllers.case import CaseController
|
||||
from tux.utils import checks
|
||||
from tux.utils.flags import PollBanFlags, generate_usage
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
||||
|
||||
class PollBan(ModerationCogBase):
|
||||
def __init__(self, bot: Tux) -> None:
|
||||
super().__init__(bot)
|
||||
self.case_controller = CaseController()
|
||||
self.poll_ban.usage = generate_usage(self.poll_ban, PollBanFlags)
|
||||
|
||||
@commands.hybrid_command(
|
||||
name="pollban",
|
||||
aliases=["pb"],
|
||||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(3)
|
||||
async def poll_ban(
|
||||
self,
|
||||
ctx: commands.Context[Tux],
|
||||
member: discord.Member,
|
||||
*,
|
||||
flags: PollBanFlags,
|
||||
) -> None:
|
||||
"""
|
||||
Ban a user from creating polls using tux.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[Tux]
|
||||
The context object.
|
||||
member : discord.Member
|
||||
The member to poll ban.
|
||||
flags : PollBanFlags
|
||||
The flags for the command. (reason: str, silent: bool)
|
||||
"""
|
||||
|
||||
assert ctx.guild
|
||||
|
||||
if await self.is_pollbanned(ctx.guild.id, member.id):
|
||||
await ctx.send("User is already poll banned.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
try:
|
||||
case = await self.db.case.insert_case(
|
||||
case_user_id=member.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.POLLBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to ban {member}. {e}")
|
||||
await ctx.send(f"Failed to ban {member}. {e}", delete_after=30)
|
||||
return
|
||||
|
||||
dm_sent = await self.send_dm(ctx, flags.silent, member, flags.reason, "poll banned")
|
||||
await self.handle_case_response(ctx, CaseType.POLLBAN, case.case_number, flags.reason, member, dm_sent)
|
||||
|
||||
|
||||
async def setup(bot: Tux) -> None:
|
||||
await bot.add_cog(PollBan(bot))
|
71
tux/cogs/moderation/pollunban.py
Normal file
71
tux/cogs/moderation/pollunban.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from tux.bot import Tux
|
||||
from tux.database.controllers.case import CaseController
|
||||
from tux.utils import checks
|
||||
from tux.utils.flags import PollUnbanFlags, generate_usage
|
||||
|
||||
from . import ModerationCogBase
|
||||
|
||||
|
||||
class PollUnban(ModerationCogBase):
|
||||
def __init__(self, bot: Tux) -> None:
|
||||
super().__init__(bot)
|
||||
self.case_controller = CaseController()
|
||||
self.poll_unban.usage = generate_usage(self.poll_unban, PollUnbanFlags)
|
||||
|
||||
@commands.hybrid_command(
|
||||
name="pollunban",
|
||||
aliases=["pub"],
|
||||
)
|
||||
@commands.guild_only()
|
||||
@checks.has_pl(3)
|
||||
async def poll_unban(
|
||||
self,
|
||||
ctx: commands.Context[Tux],
|
||||
member: discord.Member,
|
||||
*,
|
||||
flags: PollUnbanFlags,
|
||||
):
|
||||
"""
|
||||
Unban a user from creating snippets.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[Tux]
|
||||
The context object.
|
||||
member : discord.Member
|
||||
The member to snippet unban.
|
||||
flags : PollUnbanFlags
|
||||
The flags for the command. (reason: str, silent: bool)
|
||||
"""
|
||||
|
||||
assert ctx.guild
|
||||
|
||||
if not await self.is_pollbanned(ctx.guild.id, member.id):
|
||||
await ctx.send("User is not poll banned.", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
try:
|
||||
case = await self.db.case.insert_case(
|
||||
case_user_id=member.id,
|
||||
case_moderator_id=ctx.author.id,
|
||||
case_type=CaseType.POLLUNBAN,
|
||||
case_reason=flags.reason,
|
||||
guild_id=ctx.guild.id,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to poll unban {member}. {e}")
|
||||
await ctx.send(f"Failed to poll unban {member}. {e}", delete_after=30, ephemeral=True)
|
||||
return
|
||||
|
||||
dm_sent = await self.send_dm(ctx, flags.silent, member, flags.reason, "poll unbanned")
|
||||
await self.handle_case_response(ctx, CaseType.POLLUNBAN, case.case_number, flags.reason, member, dm_sent)
|
||||
|
||||
|
||||
async def setup(bot: Tux) -> None:
|
||||
await bot.add_cog(PollUnban(bot))
|
|
@ -3,7 +3,9 @@ from discord import app_commands
|
|||
from discord.ext import commands
|
||||
from loguru import logger
|
||||
|
||||
from prisma.enums import CaseType
|
||||
from tux.bot import Tux
|
||||
from tux.database.controllers import CaseController
|
||||
from tux.ui.embeds import EmbedCreator
|
||||
|
||||
# TODO: Create option inputs for the poll command instead of using a comma separated string
|
||||
|
@ -12,6 +14,35 @@ from tux.ui.embeds import EmbedCreator
|
|||
class Poll(commands.Cog):
|
||||
def __init__(self, bot: Tux) -> None:
|
||||
self.bot = bot
|
||||
self.case_controller = CaseController()
|
||||
|
||||
# TODO: for the moment this is duplicated code from ModerationCogBase in a attempt to get the code out sooner
|
||||
async def is_pollbanned(self, guild_id: int, user_id: int) -> bool:
|
||||
"""
|
||||
Check if a user is poll banned.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
guild_id : int
|
||||
The ID of the guild to check in.
|
||||
user_id : int
|
||||
The ID of the user to check.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if the user is poll banned, False otherwise.
|
||||
"""
|
||||
|
||||
ban_cases = await self.case_controller.get_all_cases_by_type(guild_id, CaseType.POLLBAN)
|
||||
unban_cases = await self.case_controller.get_all_cases_by_type(guild_id, CaseType.POLLUNBAN)
|
||||
|
||||
ban_count = sum(case.case_user_id == user_id for case in ban_cases)
|
||||
unban_count = sum(case.case_user_id == user_id for case in unban_cases)
|
||||
|
||||
return (
|
||||
ban_count > unban_count
|
||||
) # TODO: this implementation is flawed, if someone bans and unbans the same user multiple times, this will not work as expected
|
||||
|
||||
@commands.Cog.listener() # listen for messages
|
||||
async def on_message(self, message: discord.Message) -> None:
|
||||
|
@ -40,7 +71,6 @@ class Poll(commands.Cog):
|
|||
@commands.Cog.listener()
|
||||
async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User) -> None:
|
||||
# Block any reactions that are not numbers for the poll
|
||||
|
||||
if reaction.message.embeds:
|
||||
embed = reaction.message.embeds[0]
|
||||
if (
|
||||
|
@ -64,7 +94,12 @@ class Poll(commands.Cog):
|
|||
The title of the poll.
|
||||
options : str
|
||||
The options for the poll, separated by commas.
|
||||
|
||||
|
||||
"""
|
||||
if interaction.guild_id is None:
|
||||
await interaction.response.send_message("This command can only be used in a server.", ephemeral=True)
|
||||
return
|
||||
|
||||
# Split the options by comma
|
||||
options_list = options.split(",")
|
||||
|
@ -72,6 +107,17 @@ class Poll(commands.Cog):
|
|||
# Remove any leading or trailing whitespaces from the options
|
||||
options_list = [option.strip() for option in options_list]
|
||||
|
||||
if await self.is_pollbanned(interaction.guild_id, interaction.user.id):
|
||||
embed = EmbedCreator.create_embed(
|
||||
bot=self.bot,
|
||||
embed_type=EmbedCreator.ERROR,
|
||||
user_name=interaction.user.name,
|
||||
user_display_avatar=interaction.user.display_avatar.url,
|
||||
title="Poll Banned",
|
||||
description="You are poll banned and cannot create a poll.",
|
||||
)
|
||||
await interaction.response.send_message(embed=embed, ephemeral=True)
|
||||
return
|
||||
# Check if the options count is between 2-9
|
||||
if len(options_list) < 2 or len(options_list) > 9:
|
||||
embed = EmbedCreator.create_embed(
|
||||
|
|
|
@ -309,3 +309,33 @@ class SnippetUnbanFlags(commands.FlagConverter, case_insensitive=True, delimiter
|
|||
aliases=["s", "quiet"],
|
||||
default=False,
|
||||
)
|
||||
|
||||
|
||||
class PollBanFlags(commands.FlagConverter, case_insensitive=True, delimiter=" ", prefix="-"):
|
||||
reason: str = commands.flag(
|
||||
name="reason",
|
||||
description="Reason for the poll ban.",
|
||||
aliases=["r"],
|
||||
default=MISSING,
|
||||
)
|
||||
silent: bool = commands.flag(
|
||||
name="silent",
|
||||
description="Do not send a DM to the target.",
|
||||
aliases=["s", "quiet"],
|
||||
default=False,
|
||||
)
|
||||
|
||||
|
||||
class PollUnbanFlags(commands.FlagConverter, case_insensitive=True, delimiter=" ", prefix="-"):
|
||||
reason: str = commands.flag(
|
||||
name="reason",
|
||||
description="Reason for the poll unban",
|
||||
aliases=["r"],
|
||||
default=MISSING,
|
||||
)
|
||||
silent: bool = commands.flag(
|
||||
name="silent",
|
||||
description="Do not send a DM to the target.",
|
||||
aliases=["s", "quiet"],
|
||||
default=False,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue