-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.py
246 lines (207 loc) · 9.91 KB
/
filter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
import discord
from discord import app_commands
from data.model import FilterWord
from data.services import guild_service, user_service
from discord.ext import commands
from utils import GIRContext, cfg, transform_context
from utils.framework import (admin_and_up, always_whisper, gatekeeper,
mod_and_up)
from utils.views import Menu, filterwords_autocomplete
def format_filter_page(_, entries, current_page, all_pages):
"""Formats the page for the filtered words embed
Parameters
----------
entry : dict
"The dictionary for the entry"
all_pages : list
"All entries that we will eventually iterate through"
current_page : number
"The number of the page that we are currently on"
Returns
-------
discord.Embed
"The embed that we will send"
"""
embed = discord.Embed(
title=f'Filtered words', color=discord.Color.blurple())
for word in entries:
notify_flag = ""
piracy_flag = ""
flags_check = ""
if word.notify is True:
notify_flag = "🔔"
if word.piracy:
piracy_flag = " 🏴☠️"
if word.notify is False and not word.piracy:
flags_check = "None"
embed.add_field(
name=word.word, value=f"Bypassed by: {gatekeeper.level_info(word.bypass)}\nFlags: {flags_check}{notify_flag}{piracy_flag}")
embed.set_footer(
text=f"Page {current_page} of {len(all_pages)}")
return embed
class Filters(commands.Cog):
def __init__(self, bot):
self.bot = bot
@mod_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Toggles bot pinging for reports when offline.")
@app_commands.describe(val="True for ping, false for not")
@transform_context
@always_whisper
async def offlineping(self, ctx: GIRContext, val: bool = None):
cur = user_service.get_user(ctx.author.id)
if val is None:
val = not cur.offline_report_ping
cur.offline_report_ping = val
cur.save()
if val:
await ctx.send_success("You will now be pinged for reports when offline")
else:
await ctx.send_warning("You will no longer be pinged for reports when offline")
_filter = app_commands.Group(name="filter", description="Interact with filter", guild_ids=[cfg.guild_id])
@mod_and_up()
@_filter.command(description="Add a word to filter")
@app_commands.describe(notify="Whether to generate a report or not when this word is filtered")
@app_commands.describe(bypass="The level of bypass for this word")
@app_commands.choices(bypass=[app_commands.Choice(name=name, value=key) for key, name in gatekeeper._permission_names.items()])
@app_commands.describe(phrase="The word to filter")
@transform_context
async def add(self, ctx: GIRContext, notify: bool, bypass: int, phrase: str) -> None:
fw = FilterWord()
fw.bypass = bypass
fw.notify = notify
fw.word = phrase
if not guild_service.add_filtered_word(fw):
raise commands.BadArgument("That word is already filtered!")
phrase = discord.utils.escape_markdown(phrase)
phrase = discord.utils.escape_mentions(phrase)
await ctx.send_success(title="Added new word to filter!", description=f"This filter {'will' if notify else 'will not'} ping for reports, level {bypass} can bypass it, and the phrase is `{phrase}`")
@mod_and_up()
@_filter.command(description="List filtered words", name="list")
@transform_context
async def _list(self, ctx: GIRContext):
filters = guild_service.get_guild().filter_words
if len(filters) == 0:
raise commands.BadArgument(
"The filterlist is currently empty. Please add a word using `/filter`.")
filters = sorted(filters, key=lambda word: word.word.lower())
menu = Menu(ctx, filters, per_page=12,
page_formatter=format_filter_page, whisper=False)
await menu.start()
@mod_and_up()
@app_commands.describe(word="The word to mark as piracy")
@app_commands.autocomplete(word=filterwords_autocomplete)
@transform_context
async def piracy(self, ctx: GIRContext, word: str):
word = word.lower()
words = guild_service.get_guild().filter_words
words = list(filter(lambda w: w.word.lower() == word.lower(), words))
if len(words) > 0:
words[0].piracy = not words[0].piracy
guild_service.update_filtered_word(words[0])
await ctx.send_success("Marked as a piracy word!" if words[0].piracy else "Removed as a piracy word!")
else:
await ctx.send_warning("You must filter that word before it can be marked as piracy.", delete_after=5)
@mod_and_up()
@_filter.command(description="Remove word from filter")
@app_commands.describe(word="The word to remove")
@app_commands.autocomplete(word=filterwords_autocomplete)
@transform_context
async def remove(self, ctx: GIRContext, word: str):
word = word.lower()
words = guild_service.get_guild().filter_words
words = list(filter(lambda w: w.word.lower() == word.lower(), words))
if len(words) > 0:
guild_service.remove_filtered_word(words[0].word)
await ctx.send_success("Deleted!")
else:
await ctx.send_warning("That word is not filtered.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Whitelist a guild from invite filter")
@app_commands.describe(guild_id="The guild to whitelist")
@transform_context
async def whitelist(self, ctx: GIRContext, guild_id: str):
try:
guild_id = int(guild_id)
except ValueError:
raise commands.BadArgument("Invalid ID!")
if guild_service.add_whitelisted_guild(guild_id):
await ctx.send_success("Whitelisted.")
else:
await ctx.send_warning("That server is already whitelisted.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Add a guild back to invite filter")
@app_commands.describe(guild_id="The guild to blacklist")
@transform_context
async def blacklist(self, ctx: GIRContext, guild_id: str):
try:
guild_id = int(guild_id)
except ValueError:
raise commands.BadArgument("Invalid ID!")
if guild_service.remove_whitelisted_guild(guild_id):
await ctx.send_success("Blacklisted.")
else:
await ctx.send_warning("That server is already blacklisted.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Ignore channel in filter")
@app_commands.describe(channel="Channel to ignore")
@transform_context
async def ignorechannel(self, ctx: GIRContext, channel: discord.TextChannel) -> None:
if guild_service.add_ignored_channel(channel.id):
await ctx.send_success(f"The filter will no longer run in {channel.mention}.")
else:
await ctx.send_warning("That channel is already ignored.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Ungnore channel in filter")
@app_commands.describe(channel="Channel to unignore")
@transform_context
async def unignorechannel(self, ctx: GIRContext, channel: discord.TextChannel) -> None:
if guild_service.remove_ignored_channel(channel.id):
await ctx.send_success(f"Resumed filtering in {channel.mention}.")
else:
await ctx.send_warning("That channel is not already ignored.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Ignore channel in logs")
@app_commands.describe(channel="Channel to ignore")
@transform_context
async def ignorechannellogs(self, ctx: GIRContext, channel: discord.TextChannel) -> None:
if guild_service.add_ignored_channel_logging(channel.id):
await ctx.send_success(f"{channel.mention} will no longer be logged.")
else:
await ctx.send_warning("That channel is already ignored.", delete_after=5)
@admin_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Ungnore channel in logs")
@app_commands.describe(channel="Channel to unignore")
@transform_context
async def unignorechannellogs(self, ctx: GIRContext, channel: discord.TextChannel) -> None:
if guild_service.remove_ignored_channel_logging(channel.id):
await ctx.send_success(f"Resumed logging in {channel.mention}.")
else:
await ctx.send_warning("That channel is not already ignored.", delete_after=5)
@mod_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Disable enhanced filter checks on a word")
@app_commands.describe(word="The word to disable")
@app_commands.autocomplete(word=filterwords_autocomplete)
@transform_context
async def falsepositive(self, ctx: GIRContext, *, word: str):
word = word.lower()
words = guild_service.get_guild().filter_words
words = list(filter(lambda w: w.word.lower() == word.lower(), words))
if len(words) > 0:
words[0].false_positive = not words[0].false_positive
if guild_service.update_filtered_word(words[0]):
await ctx.send_success("Marked as potential false positive, we won't perform the enhanced checks on it!" if words[0].false_positive else "Removed as potential false positive.")
else:
raise commands.BadArgument(
"Unexpected error occured trying to mark as false positive!")
else:
await ctx.send_warning("That word is not filtered.", delete_after=5)
async def setup(bot):
await bot.add_cog(Filters(bot))