aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jesopo2019-08-14 14:38:47 +0100
committerGravatar jesopo2019-08-14 14:38:47 +0100
commitfa279aab93c80b50c24d700c8d9d959399897371 (patch)
tree12a449b394d921d157f70fdd6ad16b82502123a3
parentalias !remindme to !in (diff)
signature
refactor/rewrite channel_op.py, split highlight spam protection out
-rw-r--r--modules/channel_op.py379
-rw-r--r--modules/highlight_spam.py31
2 files changed, 140 insertions, 270 deletions
diff --git a/modules/channel_op.py b/modules/channel_op.py
index 151dc12a..719b0f50 100644
--- a/modules/channel_op.py
+++ b/modules/channel_op.py
@@ -5,17 +5,8 @@
from src import ModuleManager, utils
-class UserNotFoundException(Exception):
- pass
-class InvalidTimeoutException(Exception):
- pass
+KICK_REASON = "your behavior is not conducive to the desired environment"
-@utils.export("channelset", utils.IntSetting("highlight-spam-threshold",
- "Set the number of nicknames in a message that qualifies as spam"))
-@utils.export("channelset", utils.BoolSetting("highlight-spam-protection",
- "Enable/Disable highlight spam protection"))
-@utils.export("channelset", utils.BoolSetting("highlight-spam-ban",
- "Enable/Disable banning highlight spammers instead of just kicking"))
@utils.export("channelset", utils.Setting("ban-format",
"Set ban format ($n = nick, $u = username, $h = hostname)",
example="*!$u@$h"))
@@ -23,293 +14,141 @@ class InvalidTimeoutException(Exception):
["qmode", "insp", "unreal", "none"],
"Set this server's method of muting users"))
class Module(ModuleManager.BaseModule):
- _name = "ChanOp"
+ def _parse_time(self, args, min_args):
+ if args[0][0] == "+":
+ if len(args[1:]) < min_args:
+ raise utils.EventError("Not enough arguments")
+ time = utils.from_pretty_time(args[0][1:])
+ if time == None:
+ raise utils.EventError("Invalid timeframe")
+ return time, args[1:]
+ return None, args
- @utils.hook("timer.unban")
- def _timer_unban(self, event):
- server = self.bot.get_server_by_id(event["server_id"])
- if server and event["channel_name"] in server.channels:
- channel = server.channels.get(event["channel_name"])
- channel.send_unban(event["hostmask"])
-
- def _kick(self, server, channel, nickname, reason):
- target_user = server.get_user(nickname)
- if channel.has_user(target_user):
- channel.send_kick(nickname, reason)
+ def _kick(self, server, channel, target_nickname, reason):
+ target_user = server.get_user(target_nickname, create=False)
+ if target_user and channel.has_user(target_user):
+ reason = " ".join(reason) or KICK_REASON
+ channel.send_kick(target_user.nickname, reason)
else:
- raise UserNotFoundException("That user is not in this channel")
- def _kick_command(self, event, channel, args_split):
- target = args_split[0]
- reason = " ".join(args_split[1:]) or None
-
- try:
- self._kick(event["server"], channel, target, reason)
- except UserNotFoundException as e:
- event["stderr"].write(str(e))
-
- @utils.hook("received.command.kick", private_only=True, min_args=2)
- def private_kick(self, event):
- """
- :help: Kick a user from the current channel
- :usage: <nickname> [reason]
- :prefix: Kick
- """
- channel = event["server"].channels.get(event["args_split"][0])
-
- event["check_assert"](utils.Check("channel-access", channel, "kick"))
-
- self._kick_command(event, channel, event["args_split"][1:])
+ raise utils.EventError("No such user")
- @utils.hook("received.command.k", alias_of="kick")
- @utils.hook("received.command.kick", channel_only=True, min_args=1)
+ @utils.hook("received.command.kick")
+ @utils.hook("received.command.k", alias_of="k")
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "kick")
+ @utils.kwarg("usage", "<nickname> [reason]")
def kick(self, event):
- """
- :help: Kick a user from the current channel
- :usage: <nickname> [reason]
- :require_mode: o
- :require_access: kick
- :prefix: Kick
- """
- self._kick_command(event, event["target"], event["args_split"])
+ self._kick(event["server"], event["target"], event["args_split"][0],
+ event["args_split"][1:])
- def _ban_format(self, user, s):
+ def _format_hostmask(self, user, s):
return s.replace("$n", user.nickname).replace("$u", user.username
).replace("$h", user.hostname)
- def _ban_user(self, channel, ban, user):
- if channel.has_user(user):
- format = channel.get_setting("ban-format", "*!$u@$h")
- hostmask_split = format.split("$$")
- hostmask_split = [self._ban_format(user, s) for s in hostmask_split]
- hostmask = "".join(hostmask_split)
- if ban:
- channel.send_ban(hostmask)
- else:
- channel.send_unban(hostmask)
- return hostmask
- else:
- raise UserNotFoundException("That user is not in this channel")
+ def _get_hostmask(self, channel, user):
+ format = channel.get_setting("ban-format", "*!$u@$h")
+ hostmask_split = [
+ self._format_hostmask(user, s) for s in format.split("$$")]
+ return "$".join(hostmask_split)
- def _ban(self, server, channel, ban, target):
- target_user = server.get_user(target)
- if channel.has_user(target_user):
- return self._ban_user(channel, ban, target_user)
+ def _ban(self, server, channel, target, allow_hostmask, time, add):
+ hostmask = None
+ target_user = server.get_user(target, create=False)
+ if target_user and channel.has_user(target_user):
+ hostmask = self._get_hostmask(channel, target_user)
else:
- if ban:
- channel.send_ban(target)
- else:
- channel.send_unban(target)
- return target
-
- @utils.hook("received.command.ban", private_only=True, min_args=2)
- def private_ban(self, event):
- """
- :help: Ban a user/hostmask from the current channel
- :usage: <channel> <nickname/hostmask>
- """
- channel = event["server"].channels.get(event["args_split"][0])
-
- event["check_assert"](utils.Check("channel-access", channel, "ban"))
-
- self._ban(event["server"], channel, True, event["args_split"][1])
- @utils.hook("received.command.ban", channel_only=True, min_args=1)
- def ban(self, event):
- """
- :help: Ban a user/hostmask from the current channel
- :usage: <nickname/hostmask>
- :require_mode: o
- :require_access: ban
- """
- self._ban(event["server"], event["target"], True,
- event["args_split"][0])
-
- def _temp_ban(self, event, accept_hostmask):
- timeout = utils.from_pretty_time(event["args_split"][1])
- if not timeout:
- raise InvalidTimeoutException(
- "Please provided a valid time above 0 seconds")
-
- if accept_hostmask:
- hostmask = self._ban(event["server"], event["target"], True,
- event["args_split"][0])
+ if not allow_hostmask:
+ raise utils.EventError("No such user")
+ hostmask = target
+ if not add:
+ channel.send_unban(hostmask)
else:
- hostmask = self._ban_user(event["target"], True,
- event["server"].get_user(event["args_split"][0]))
-
- self.timers.add_persistent("unban", timeout,
- server_id=event["server"].id,
- channel_name=event["target"].name, hostmask=hostmask)
-
- @utils.hook("received.command.tb", alias_of="tempban")
- @utils.hook("received.command.tempban", channel_only=True, min_args=2)
- def temp_ban(self, event):
- """
- :help: Temporarily ban someone from the current channel
- :usage: <nickname/hostmask> <time> [reason]
- :require_mode: o
- :require_access: ban
- :prefix: Tempban
- """
- try:
- self._temp_ban(event, True)
- except InvalidTimeoutException as e:
- event["stderr"].write(str(e))
+ channel.send_ban(hostmask)
- @utils.hook("received.command.tkb", alias_of="tempkickban")
- @utils.hook("received.command.tempkickban", channel_only=True,
- min_args=2)
- def temp_kick_ban(self, event):
- """
- :help: Temporarily kick and ban someone from the current channel
- :usage: <nickname> <time> [reason]
- :require_mode: o
- :require_access: kickban
- :prefix: TKB
- """
- reason = " ".join(event["args_split"][2:]) or None
- try:
- self._temp_ban(event, False)
- self._kick(event["server"], event["target"], event["args_split"][0],
- reason)
- except InvalidTimeoutException as e:
- event["stderr"].write(str(e))
- except UserNotFoundException as e:
- event["stderr"].write(str(e))
+ if not time == None:
+ self.timers.add_persistent("unban", time, server_id=server.id,
+ channel_name=channel.name, hostmask=hostmask)
- @utils.hook("received.command.unban", private_only=True, min_args=2)
- def private_unban(self, event):
- """
- :help: Unban a user/hostmask from the current channel
- :usage: <channel> <nickname/hostmask>
- """
- channel = event["server"].channels.get(event["args_split"][0])
-
- event["check_assert"](utils.Check("channel-access", channel, "ban"))
+ @utils.hook("timer.unban")
+ def _timer_unban(self, event):
+ server = self.bot.get_server_by_id(event["server_id"])
+ if server and event["channel_name"] in server.channels:
+ channel = server.channels.get(event["channel_name"])
+ channel.send_unban(event["hostmask"])
- self._ban(event["server"], channel, False, event["args_split"][1])
+ @utils.hook("received.command.ban")
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "ban")
+ @utils.kwarg("usage", "[+time] <target>")
+ def ban(self, event):
+ time, args = self._parse_time(event["args_split"], 1)
+ self._ban(event["server"], event["target"], args[0], True, time, True)
- @utils.hook("received.command.unban", channel_only=True, min_args=1)
+ @utils.hook("received.command.unban")
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "ban")
+ @utils.kwarg("usage", "<target>")
def unban(self, event):
- """
- :help: Unban a user/hostmask from the current channel
- :usage: <nickname/hostmask>
- :require_mode: o
- :require_access: ban
- """
- self._ban(event["server"], event["target"], False,
- event["args_split"][0])
+ self._ban(event["server"], event["target"], event["args_split"][0],
+ True, None, False)
+ @utils.hook("received.command.kickban")
@utils.hook("received.command.kb", alias_of="kickban")
- @utils.hook("received.command.kickban", channel_only=True, min_args=1)
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "kickban")
+ @utils.kwarg("usage", "[+time] <nickname> [reason]")
def kickban(self, event):
- """
- :help: Kick and ban a user from the current channel
- :usage: <nickname> [reason]
- :require_mode: o
- :require_access: kickban
- :prefix: Kickban
- """
- target = event["args_split"][0]
- reason = " ".join(event["args_split"][1:]) or None
- try:
- self._ban(event["server"], event["target"], True, target)
- self._kick(event["server"], event["target"], target, reason)
- except UserNotFoundException as e:
- event["stderr"].write(str(e))
+ time, args = self._parse_time(event["args_split"], 1)
+ self._ban(event["server"], event["target"], args[0], False, time)
+ self._kick(event["server"], event["target"], args[0], args[1:])
- @utils.hook("received.command.op", channel_only=True)
+ @utils.hook("received.command.op")
+ @utils.hook("received.command.deop")
+ @utils.kwarg("channel_only", True)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "op")
+ @utils.kwarg("usage", "[nickname]")
def op(self, event):
- """
- :help: Op a user in the current channel
- :usage: [nickname]
- :require_mode: o
- :require_access: op
- """
- target = event["user"].nickname if not event["args_split"] else event[
- "args_split"][0]
- event["target"].send_mode("+o", [target])
- @utils.hook("received.command.deop", channel_only=True)
- def deop(self, event):
- """
- :help: Remove op from a user in the current channel
- :usage: [nickname]
- :require_mode: o
- :require_access: op
- """
- target = event["user"].nickname if not event["args_split"] else event[
- "args_split"][0]
- event["target"].send_mode("-o", [target])
+ add = event.name == "received.command.op"
+ target = event["args_split"][0] if event["args"] else event[
+ "user"].nickname
+ event["target"].send_mode("+o" if add else "-o", target)
- @utils.hook("received.command.voice", channel_only=True)
- def voice(self, event):
- """
- :help: Voice a user in the current channel
- :usage: [nickname]
- :require_mode: o
- :require_access: voice
- """
- target = event["user"].nickname if not event["args_split"] else event[
- "args_split"][0]
- event["target"].send_mode("+v", [target])
- @utils.hook("received.command.devoice", channel_only=True)
- def devoice(self, event):
- """
- :help: Remove voice from a user in the current channel
- :usage: [nickname]
- :require_mode: o
- :require_access: voice
- """
- target = event["user"].nickname if not event["args_split"] else event[
- "args_split"][0]
- event["target"].send_mode("-v", [target])
+ @utils.hook("received.command.voice")
+ @utils.hook("received.command.devoice")
+ @utils.kwarg("channel_only", True)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "voice")
+ @utils.kwarg("usage", "[nickname]")
+ def op(self, event):
+ add = event.name == "received.command.voice"
+ target = event["args_split"][0] if event["args"] else event[
+ "user"].nickname
+ event["target"].send_mode("+v" if add else "-v", target)
- @utils.hook("received.command.topic", min_args=1, channel_only=True,
- remove_empty=False)
+ @utils.hook("received.command.topic")
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("channel_only", True)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "topic")
+ @utils.kwarg("remove_empty", False)
+ @utils.kwarg("usage", "<topic>")
def topic(self, event):
- """
- :help: Set the topic in the current channel
- :usage: <topic>
- :require_mode: o
- :require_access: topic
- """
event["target"].send_topic(event["args"])
- @utils.hook("received.command.tappend", min_args=1, channel_only=True,
- remove_empty=False)
+
+ @utils.hook("received.command.tappend")
+ @utils.kwarg("min_args", 1)
+ @utils.kwarg("channel_only", True)
+ @utils.kwarg("require_mode", "o")
+ @utils.kwarg("require_access", "topic")
+ @utils.kwarg("remove_empty", False)
+ @utils.kwarg("usage", "<topic>")
def tappend(self, event):
- """
- :help: Append to the topic in the current channel
- :usage: <topic>
- :require_mode: o
- :require_access: topic
- """
event["target"].send_topic(event["target"].topic + event["args"])
- @utils.hook("received.message.channel")
- def highlight_spam(self, event):
- if event["channel"].get_setting("highlight-spam-protection", False):
- nicknames = list(map(lambda user: user.nickname,
- event["channel"].users)) + [event["server"].nickname]
-
- highlights = set(nicknames) & set(event["message_split"])
- if len(highlights) > 1 and len(highlights) >= event["channel"
- ].get_setting("highlight-spam-threshold", 10):
- has_mode = event["channel"].mode_or_above(event["user"], "v")
- should_ban = event["channel"].get_setting("highlight-spam-ban",
- False)
- if not has_mode:
- if should_ban:
- event["channel"].send_ban("*!%s@%s" % (
- event["user"].username, event["user"].hostname))
- event["channel"].send_kick(event["user"].nickname,
- "highlight spam detected")
-
- @utils.hook("received.command.leave", channel_only=True)
- def leave(self, event):
- """
- :help: Part me from the current channel
- :require_mode: o
- """
- event["target"].send_part()
-
def _mute_method(self, server, user):
mask = "*!*@%s" % user.hostname
mute_method = server.get_setting("mute-method", "qmode").lower()
diff --git a/modules/highlight_spam.py b/modules/highlight_spam.py
new file mode 100644
index 00000000..8d02ee87
--- /dev/null
+++ b/modules/highlight_spam.py
@@ -0,0 +1,31 @@
+#--depends-on config
+
+from src import ModuleManager, utils
+
+@utils.export("channelset", utils.IntSetting("highlight-spam-threshold",
+ "Set the number of nicknames in a message that qualifies as spam"))
+@utils.export("channelset", utils.BoolSetting("highlight-spam-protection",
+ "Enable/Disable highlight spam protection"))
+@utils.export("channelset", utils.BoolSetting("highlight-spam-ban",
+ "Enable/Disable banning highlight spammers instead of just kicking"))
+class Module(ModuleManager.BaseModule):
+ @utils.hook("received.message.channel")
+ def highlight_spam(self, event):
+ if event["channel"].get_setting("highlight-spam-protection", False):
+ nicknames = list(map(lambda user: user.nickname,
+ event["channel"].users))
+
+ highlights = set(nicknames) & set(event["message_split"])
+ print(highlights)
+ if len(highlights) > 1 and len(highlights) >= event["channel"
+ ].get_setting("highlight-spam-threshold", 10):
+ has_mode = event["channel"].mode_or_above(event["user"], "v")
+ should_ban = event["channel"].get_setting("highlight-spam-ban",
+ False)
+ if not has_mode:
+ if should_ban:
+ event["channel"].send_ban("*!%s@%s" % (
+ event["user"].username, event["user"].hostname))
+ event["channel"].send_kick(event["user"].nickname,
+ "highlight spam detected")
+