Skip to content

Commit ccc5d77

Browse files
authored
Merge pull request #30 from matthewflegg/feature-clear_blacklist_dropdown
Added a dropdown for ~blrem
2 parents 3dd4426 + 09d5b37 commit ccc5d77

File tree

4 files changed

+200
-13
lines changed

4 files changed

+200
-13
lines changed

cogs/admin/admin_cog.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import discord
88
from discord.ext import commands
9-
from utils.buttons import BlacklistClearButton, ClearMessagesView, DropdownView
9+
from utils.buttons import BlacklistClearButton, BlacklistRemoveView, ClearMessagesView, DropdownView
1010
from utils.functions import lift_ban, sanction
1111

1212
FILEPATH = "files/blacklist.json"
@@ -107,7 +107,7 @@ async def unban(self, ctx: commands.Context, user: discord.User):
107107
@commands.command(aliases=["bladd"])
108108
@commands.has_permissions(manage_messages=True)
109109
@commands.cooldown(1, 2, commands.BucketType.user)
110-
async def blacklist(self, ctx: commands.Context, *, words: str = None):
110+
async def blacklist(self, ctx: commands.Context, *, words: str=None):
111111
"""
112112
⚙️ Bans words from being used.
113113
@@ -123,6 +123,7 @@ async def blacklist(self, ctx: commands.Context, *, words: str = None):
123123
)
124124
view.message = await ctx.send(embed=embed, view=view)
125125
return
126+
126127
id = str(ctx.guild.id)
127128
words = [word.lower() for word in words.split(" ")]
128129

@@ -212,7 +213,7 @@ async def showblacklist(self, ctx: commands.Context):
212213

213214
@commands.command(aliases=["blrem"])
214215
@commands.has_permissions(manage_messages=True)
215-
async def blacklistremove(self, ctx: commands.Context, *, words: str):
216+
async def blacklistremove(self, ctx: commands.Context, *, words: str=None):
216217
"""
217218
⚙️ Removes a word from the list of banned words.
218219
@@ -221,6 +222,15 @@ async def blacklistremove(self, ctx: commands.Context, *, words: str):
221222
~blacklistremove | ~blrem <...words>
222223
```
223224
"""
225+
if not words:
226+
view = BlacklistRemoveView(ctx)
227+
embed = discord.Embed(
228+
title="🛠️ Please enter one or more words to remove from the blacklist."
229+
)
230+
231+
view.message = await ctx.send(embed=embed, view=view)
232+
return
233+
224234
id = str(ctx.guild.id)
225235
words = {word.lower() for word in words.split(" ")}
226236

files/blacklist.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
{
22
"953054451999072276": [
3-
"prick",
4-
"poop",
5-
"cunt",
6-
"retard",
7-
"asshole"
3+
"asshole",
4+
"arse"
85
]
96
}

handlers/event_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,14 @@ async def on_member_remove(self, member: discord.Member):
7171
if channel is not None:
7272
await channel.send(f"👋🏻 Goodbye, **{member.name}**.")
7373

74-
@commands.Cog.listener()
74+
@commands.Cog.listener() # This throws an AttributeError but it isn't really an issue
7575
async def on_message(self, message: discord.Message):
7676
"""
7777
Called when a message is sent.
7878
"""
79+
if not message.guild:
80+
return
81+
7982
blacklist = self.client.cache.blacklist
8083

8184
if (

utils/buttons.py

Lines changed: 181 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from typing import Optional
2-
1+
import black
32
import discord
3+
4+
from typing import Optional
45
from discord.ext import commands
56

67
FILEPATH = "files/blacklist.json"
@@ -130,7 +131,7 @@ def __init__(
130131
view: discord.ui.View,
131132
drop: discord.ui.Select,
132133
*,
133-
title: str = "🔑 Enter a word to blacklist:",
134+
title: str = "🔒 Add a Word to the Blacklist",
134135
) -> None:
135136
super().__init__(title=title)
136137
self.view = view
@@ -234,7 +235,7 @@ async def send_modal(
234235
)
235236
async def submit(self, interaction: discord.Interaction, button: discord.Button):
236237
await interaction.response.defer()
237-
values = self.drop.words
238+
values = [value.lower() for value in self.drop.words]
238239
id = str(interaction.guild_id)
239240
if not values:
240241
print(values)
@@ -267,3 +268,179 @@ async def abort(self, interaction: discord.Interaction, button: discord.Button):
267268
f"❌ {interaction.user.mention}: Aborting command!", ephemeral=True
268269
)
269270
await self.disable_all_buttons(interaction)
271+
272+
273+
class BlacklistRemoveModal(discord.ui.Modal):
274+
def __init__(
275+
self,
276+
view: discord.ui.View,
277+
drop: discord.ui.Select,
278+
*,
279+
title: str="🔒 Remove a Word From the Blacklist"
280+
) -> None:
281+
super().__init__(title=title)
282+
283+
self.view = view
284+
self.drop = drop
285+
self.text = discord.ui.TextInput(
286+
label="Word", placeholder="🔑 Enter a word to remove from the blacklist:", max_length=100
287+
)
288+
289+
self.add_item(self.text)
290+
291+
async def on_submit(self, interaction: discord.Interaction) -> None:
292+
await interaction.response.defer()
293+
text_value = self.text.value
294+
295+
if not text_value:
296+
return
297+
298+
if self.drop.options[0].label == "\u200b":
299+
self.drop.options.pop(0)
300+
301+
option = discord.SelectOption(label=text_value, default=True)
302+
303+
self.drop.append_option(option)
304+
self.drop.max_values = len(self.drop.options)
305+
self.drop.words.append(text_value)
306+
307+
await interaction.message.edit(view=self.view)
308+
return await super().on_submit(interaction=interaction)
309+
310+
311+
class BlacklistRemoveDropdown(discord.ui.Select):
312+
def __init__(self, ctx: commands.Context):
313+
self.ctx = ctx
314+
315+
options = [discord.SelectOption(label="\u200b", default=False)]
316+
self.words = []
317+
318+
super().__init__(
319+
placeholder="📃 Choose words to remove from the blacklist...",
320+
min_values=1,
321+
max_values=len(options),
322+
options=options
323+
)
324+
325+
async def interaction_check(self, interaction: discord.Interaction) -> bool:
326+
"""
327+
Prevents users who weren't the command sender from using buttons.
328+
"""
329+
if interaction.user.id == self.ctx.author.id:
330+
return True
331+
else:
332+
await interaction.response.send_message(
333+
f"❌ {interaction.user.mention}: This isn't your interaction!",
334+
ephemeral=True,
335+
)
336+
return False
337+
338+
async def callback(self, interaction: discord.Interaction):
339+
await interaction.response.defer()
340+
341+
if not self.values:
342+
return await interaction.followup.send(
343+
f"❌ {interaction.user.mention}: You need to select one or more than one words to remove from the blacklist!",
344+
ephemeral=True,
345+
)
346+
347+
self.words = self.values
348+
return
349+
350+
351+
class BlacklistRemoveView(discord.ui.View):
352+
def __init__(self, ctx: commands.Context, *, timeout: Optional[float] = 180):
353+
super().__init__()
354+
self.ctx = ctx
355+
self.drop = BlacklistRemoveDropdown(ctx)
356+
self.add_item(self.drop)
357+
358+
async def interaction_check(self, interaction: discord.Interaction) -> bool:
359+
"""
360+
Prevents users who weren't the command sender from using buttons.
361+
"""
362+
if interaction.user.id == self.ctx.author.id:
363+
return True
364+
else:
365+
await interaction.response.send_message(
366+
f"❌ {interaction.user.mention}: This isn't your interaction!",
367+
ephemeral=True,
368+
)
369+
return False
370+
371+
async def disable_all_buttons(self, interaction: discord.Interaction = None):
372+
"""
373+
Disables all buttons.
374+
"""
375+
interaction = interaction or self
376+
self.drop.disabled = True
377+
for child in self.children:
378+
child.disabled = True
379+
await interaction.message.edit(view=self)
380+
self.stop()
381+
382+
@discord.ui.button(
383+
label="Enter a New Word", style=discord.ButtonStyle.blurple, emoji="💬"
384+
)
385+
async def send_modal(
386+
self, interaction: discord.Interaction, button: discord.Button
387+
):
388+
modal = BlacklistRemoveModal(self, self.drop)
389+
await interaction.response.send_modal(modal)
390+
391+
@discord.ui.button(
392+
label="Submit Words", style=discord.ButtonStyle.green, emoji="👍🏻"
393+
)
394+
async def submit(self, interaction: discord.Interaction, button: discord.Button):
395+
await interaction.response.defer()
396+
397+
values = [value.lower() for value in self.drop.words]
398+
id = str(interaction.guild.id)
399+
400+
if not values:
401+
print(values)
402+
403+
return await interaction.followup.send(
404+
f"❌ {interaction.user.mention}: You need to have at least one word selected!",
405+
ephemeral=True,
406+
)
407+
408+
blacklist = interaction.client.cache.blacklist
409+
410+
if id not in blacklist.keys():
411+
return await interaction.followup.send(
412+
f"❌ {interaction.user.mention}: This server does not have any words blacklisted.",
413+
ephemeral=True
414+
)
415+
416+
print(values)
417+
words = set(values) & set(blacklist[id])
418+
print(values, words)
419+
420+
if not words:
421+
return await interaction.followup.send(
422+
f"❌ {interaction.user.mention}: Sorry. Those words are not in the blacklist.",
423+
ephemeral=True,
424+
)
425+
426+
for word in words:
427+
blacklist[id].remove(word)
428+
429+
interaction.client.update_json(FILEPATH, blacklist)
430+
431+
embed = discord.Embed(
432+
title=f"🛠️ Words successfully removed.",
433+
description=" ".join(f"`{word}`" for word in words),
434+
)
435+
436+
if len(values) > len(words):
437+
embed.set_footer(text="⚠️ Some words were duplicates and were not added.")
438+
439+
await interaction.followup.send(embed=embed)
440+
441+
@discord.ui.button(label="Abort", style=discord.ButtonStyle.red, emoji="👎🏻")
442+
async def abort(self, interaction: discord.Interaction, button: discord.Button):
443+
await interaction.response.send_message(
444+
f"❌ {interaction.user.mention}: Aborting command!", ephemeral=True
445+
)
446+
await self.disable_all_buttons(interaction)

0 commit comments

Comments
 (0)