diff --git a/README.md b/README.md index 268f367..b88b451 100755 --- a/README.md +++ b/README.md @@ -81,12 +81,10 @@ Secondary goal is adding new features: - [ ] Purge: On purge, send logs in form of txt file to server logs - [ ] New verification feature: Using log module from akbbot for logging attempts and removing old attempts -- [ ] New moderation feature: watch-unwatch (using log module from akbbot) - [ ] New feature: Modmail - [ ] New feature: Submiterr (relies on modmail) - [ ] New feature: Highlights (problematic words automatically get posted to modmail channel, relies on modmail) - [ ] Feature creep: Shortlink completion (gl/ao/etc) -- [ ] Feature creep: Pleroma embedding - [ ] New moderation feature: timelock (channel lockdown with time, relies on robocronp)
@@ -104,8 +102,10 @@ Secondary goal is adding new features: - [x] New moderation feature: User notes - [x] New moderation feature: Reaction removing features (thanks misson20000!) - [x] New moderation feature: User nickname change +- [x] New moderation feature: watch-unwatch +- [x] New moderation feature: tracking suspicious keywords +- [x] New moderation feature: tracking invites posted - [x] New self-moderation feature: .mywarns -- [x] Remove sh, remove risky stuff from eval

diff --git a/Robocop.py b/Robocop.py index c2b69ca..df21832 100755 --- a/Robocop.py +++ b/Robocop.py @@ -50,6 +50,7 @@ initial_extensions = ['cogs.common', 'cogs.mod_reacts', 'cogs.mod_userlog', 'cogs.mod_timed', + 'cogs.mod_watch', 'cogs.basic', 'cogs.logs', 'cogs.err', diff --git a/cogs/logs.py b/cogs/logs.py index 60f56f1..f85cb02 100644 --- a/cogs/logs.py +++ b/cogs/logs.py @@ -17,7 +17,7 @@ class Logs(Cog): self.name_re = re.compile(r"[a-zA-Z0-9].*") self.clean_re = re.compile(r'[\W_]+', re.UNICODE) # All lower case, no spaces, nothing non-alphanumeric - self.susp_words = ["sx", "tx", "reinx", "tinfoil", "dz", "goldleaf", + self.susp_words = ["sx", "tx", "rei", "tinfoil", "dz", "goldleaf", "nsp", "xci", "nut", "doge", "cdnsp", "lithium"] self.ok_words = ["nspwn", "hblnsp", "exefs"] @@ -80,6 +80,9 @@ class Logs(Cog): await log_channel.send(msg) async def do_spy(self, message): + if message.author.bot: + return + alert = False cleancont = self.clean_re.sub('', message.content).lower() msg = f"🚨 Suspicious message by {message.author.mention} "\ diff --git a/cogs/mod_watch.py b/cogs/mod_watch.py new file mode 100644 index 0000000..eb783e2 --- /dev/null +++ b/cogs/mod_watch.py @@ -0,0 +1,46 @@ +import discord +from discord.ext import commands +from discord.ext.commands import Cog +from helpers.checks import check_if_staff +from helpers.userlogs import setwatch + + +class ModWatch(Cog): + def __init__(self, bot): + self.bot = bot + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def watch(self, ctx, target: discord.Member, *, note: str = ""): + """Puts a user under watch, staff only.""" + setwatch(target.id, ctx.author, True, target.name) + await ctx.send(f"{ctx.author.mention}: user is now on watch.") + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def watchid(self, ctx, target: int, *, note: str = ""): + """Puts a user under watch by userid, staff only.""" + setwatch(target, ctx.author, True, target.name) + await ctx.send(f"{target.mention}: user is now on watch.") + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def unwatch(self, ctx, target: discord.Member, *, note: str = ""): + """Removes a user from watch, staff only.""" + setwatch(target.id, ctx.author, False, target.name) + await ctx.send(f"{ctx.author.mention}: user is now not on watch.") + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def unwatchid(self, ctx, target: int, *, note: str = ""): + """Removes a user from watch by userid, staff only.""" + setwatch(target, ctx.author, False, target.name) + await ctx.send(f"{target.mention}: user is now not on watch.") + + +def setup(bot): + bot.add_cog(ModWatch(bot)) diff --git a/cogs/pin.py b/cogs/pin.py index 7fecbf0..4f169e4 100644 --- a/cogs/pin.py +++ b/cogs/pin.py @@ -1,15 +1,18 @@ import config -import pprint +from discord.ext.commands import Cog from discord.enums import MessageType -class Pin: + +class Pin(Cog): """ Allow users to pin things """ + def __init__(self, bot): self.bot = bot # Use raw_reaction to allow pinning old messages. + @Cog.listener() async def on_raw_reaction_add(self, payload): # TODO: handle more than 50 pinned message # BODY: If there are more than 50 pinned messages, @@ -57,8 +60,6 @@ class Pin: # Add a Pin reaction so we remember that the message is pinned await target_msg.add_reaction("📌") - # Send custom pinned message - await target_chan.send("Pinned!") def check(msg): return msg.type is MessageType.pins_add diff --git a/helpers/userlogs.py b/helpers/userlogs.py index a7cc88c..679a4de 100644 --- a/helpers/userlogs.py +++ b/helpers/userlogs.py @@ -19,25 +19,45 @@ def set_userlog(contents): def userlog(uid, issuer, reason, event_type, uname: str = ""): - userlogs = get_userlog() - uid = str(uid) - if uid not in userlogs: - userlogs[uid] = {"warns": [], - "mutes": [], - "kicks": [], - "bans": [], - "notes": [], - "watch": False, - "name": "n/a"} - if uname: - userlogs[uid]["name"] = uname - timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) - log_data = {"issuer_id": issuer.id, - "issuer_name": f"{issuer}", - "reason": reason, - "timestamp": timestamp} - if event_type not in userlogs[uid]: - userlogs[uid][event_type] = [] - userlogs[uid][event_type].append(log_data) - set_userlog(json.dumps(userlogs)) - return len(userlogs[uid][event_type]) + userlogs = get_userlog() + uid = str(uid) + if uid not in userlogs: + userlogs[uid] = {"warns": [], + "mutes": [], + "kicks": [], + "bans": [], + "notes": [], + "watch": False, + "name": "n/a"} + if uname: + userlogs[uid]["name"] = uname + timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + log_data = {"issuer_id": issuer.id, + "issuer_name": f"{issuer}", + "reason": reason, + "timestamp": timestamp} + if event_type not in userlogs[uid]: + userlogs[uid][event_type] = [] + userlogs[uid][event_type].append(log_data) + set_userlog(json.dumps(userlogs)) + return len(userlogs[uid][event_type]) + + +def setwatch(uid, issuer, watch_state, uname: str = ""): + userlogs = get_userlog() + uid = str(uid) + # Can we reduce code repetition here? + if uid not in userlogs: + userlogs[uid] = {"warns": [], + "mutes": [], + "kicks": [], + "bans": [], + "notes": [], + "watch": False, + "name": "n/a"} + if uname: + userlogs[uid]["name"] = uname + + userlogs[uid]["watch"] = watch_state + set_userlog(json.dumps(userlogs)) + return