Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Gatekeep] A variety of quality of life improvements #668

Open
wants to merge 7 commits into
base: V3/testing
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cogs/gatekeep/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
KEY_ACTIVE = "active"
KEY_WORD_DICT = "wordDict"
KEY_WATCH_LIST = "watchList"
KEY_BAN_COUNT = "banCount"

BASE_GUILD = {
KEY_LOG_CHANNEL: None,
Expand All @@ -12,4 +13,5 @@
KEY_ACTIVE: False,
KEY_WORD_DICT: {},
KEY_WATCH_LIST: [],
KEY_BAN_COUNT: 0,
}
105 changes: 99 additions & 6 deletions cogs/gatekeep/gatekeep.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@ async def status(self, ctx: Context):
active = await self.config.guild(ctx.guild).get_attr(KEY_ACTIVE)()
threshold = await self.config.guild(ctx.guild).get_attr(KEY_THRESHOLD)()
nDays = await self.config.guild(ctx.guild).get_attr(KEY_NEW_USER_DAYS)()
banCount = await self.config.guild(ctx.guild).get_attr(KEY_BAN_COUNT)()
await ctx.send(
":information_source: Current Status :information_source:\n"
f"- Log Channel: <#{log}>\n- Gatekeeping: {active}\n"
f"- Threshold: {threshold}\n- Days to watch: {nDays}"
f"- Threshold: {threshold}\n- Days to watch: {nDays}\n"
f"- Total Users Banned: {banCount}"
)

@_gatekeep.command(name="test", aliases=["eval", "score"])
Expand Down Expand Up @@ -312,8 +314,8 @@ async def removeWord(self, ctx: Context, word: str):
await ctx.send(f"`{w}` is not in the list.")

else:
# Invalid string passed
await ctx.send("The word should be a non-empty string!")
# Invalid string passed (ie: "" or "a b")
await ctx.send("The word is invalid!")

@word.command(name="list", aliases=["ls", "words"])
@commands.guild_only()
Expand All @@ -323,11 +325,11 @@ async def listWords(self, ctx: Context):

display = [] # List of text for paginator to use. Will be constructed from KEY_WORD_DICT.

# Loop through the word dictionary object
# Loop through the word dictionary object in alphabetical order
wordDict = await self.config.guild(ctx.guild).get_attr(KEY_WORD_DICT)()
for word, weight in wordDict.items():
for word in sorted(wordDict):
# Construct the display list
text = f"{word}: {weight}"
text = f"{word}: {wordDict[word]}"
display.append(text)

# Check if the display list is empty
Expand All @@ -348,6 +350,50 @@ async def listWords(self, ctx: Context):
pageList.append(embed)
await menu(ctx, pageList, DEFAULT_CONTROLS)

@word.command(name="clear", aliases=["reset"])
@commands.guild_only()
@checks.mod_or_permissions(administrator=True)
async def clearWords(self, ctx: Context):
"""Clears the entire word list for the server."""

async with self.config.guild(ctx.guild).get_attr(KEY_WORD_DICT)() as wordDict:

def check(msg: discord.Message):
return msg.author == ctx.author and msg.channel == ctx.channel

numWords = len(wordDict)

if not numWords:
await ctx.send("The word list is empty.")
return
else:
# Get confirmation before clearing the word list
await ctx.send(
warning(f"This will remove {numWords} word(s). Type 'yes' to confirm.")
)
try:
response = await self.bot.wait_for("message", timeout=30.0, check=check)
except asyncio.TimeoutError:
await ctx.send(
"No response after 30 seconds, this operation will not be executed."
)
return

if response.content.lower() != "yes":
await ctx.send("This operation will not be executed.")
return

# Confirmed, clear the word list
await self.config.guild(ctx.guild).get_attr(KEY_WORD_DICT).set({})
await ctx.send(":white_check_mark: Cleared the word list.")
self.logger.info(
"%s#%s (%s) cleared the word list for %s.",
ctx.author.name,
ctx.author.discriminator,
ctx.author.id,
ctx.guild.name,
)

@user.command(name="initialize", aliases=["init"])
@commands.guild_only()
@checks.mod_or_permissions(administrator=True)
Expand Down Expand Up @@ -491,6 +537,50 @@ async def listWatch(self, ctx: Context):
pageList.append(embed)
await menu(ctx, pageList, DEFAULT_CONTROLS)

@user.command(name="clear", aliases=["reset"])
@commands.guild_only()
@checks.mod_or_permissions(administrator=True)
async def clearUsers(self, ctx: Context):
"""Clears the entire user list for the server."""

async with self.config.guild(ctx.guild).get_attr(KEY_WATCH_LIST)() as watchList:

def check(msg: discord.Message):
return msg.author == ctx.author and msg.channel == ctx.channel

numUsers = len(watchList)

if not numUsers:
await ctx.send("The watch list is empty.")
return
else:
# Get confirmation before clearing the watch list
await ctx.send(
warning(f"This will remove {numUsers} user(s). Type 'yes' to confirm.")
)
try:
response = await self.bot.wait_for("message", timeout=30.0, check=check)
except asyncio.TimeoutError:
await ctx.send(
"No response after 30 seconds, this operation will not be executed."
)
return

if response.content.lower() != "yes":
await ctx.send("This operation will not be executed.")
return

# Confirmed, clear the watch list
await self.config.guild(ctx.guild).get_attr(KEY_WATCH_LIST).set([])
await ctx.send(":white_check_mark: Cleared the watch list.")
self.logger.info(
"%s#%s (%s) cleared the watch list for %s.",
ctx.author.name,
ctx.author.discriminator,
ctx.author.id,
ctx.guild.name,
)

async def watchlistLoop(self):
"""Daily update loop to keep the watchlist small."""
self.logger.info("Waiting for bot to be ready")
Expand Down Expand Up @@ -627,6 +717,9 @@ async def on_message(self, message: discord.Message):
str(th),
)

banCount = await self.config.guild(message.guild).get_attr(KEY_BAN_COUNT)()
await self.config.guild(message.guild).get_attr(KEY_BAN_COUNT).set(banCount + 1)

# Remove the author from the watch list. Ban = gone from server, no ban = they're probably not a bot
watchList.remove(int(author.id))
self.logger.info(
Expand Down