aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jesopo2019-05-18 18:35:47 +0100
committerGravatar jesopo2019-05-18 18:35:47 +0100
commit4e0e63e7f8b518190c94b6374e01291e9eda9f69 (patch)
treec936e38c5d823508c9eb23ac8df1a0d23f063a3f
parentgive EventCallbacks their event name (diff)
signature
Hand over regex-based-command responsibilities to `commands` module
-rw-r--r--modules/commands/__init__.py187
-rw-r--r--modules/karma.py85
-rw-r--r--modules/sed.py25
-rw-r--r--modules/title.py53
-rw-r--r--modules/youtube.py21
5 files changed, 181 insertions, 190 deletions
diff --git a/modules/commands/__init__.py b/modules/commands/__init__.py
index 2b03dee1..78cad2e8 100644
--- a/modules/commands/__init__.py
+++ b/modules/commands/__init__.py
@@ -90,10 +90,9 @@ class Module(ModuleManager.BaseModule):
return True
return False
- def message(self, event, command, args_index=1):
- args_split = event["message_split"][args_index:]
+ def _find_command_hook(self, server, command, is_channel):
if not self.has_command(command):
- aliases = self._get_aliases(event["server"])
+ aliases = self._get_aliases(server)
if command.lower() in aliases:
command, _, new_args = aliases[command.lower()].partition(" ")
@@ -102,12 +101,8 @@ class Module(ModuleManager.BaseModule):
except IndexError:
return
+ hook = None
if self.has_command(command):
- if self._is_ignored(event["server"], event["user"], command):
- return
-
- hook = None
- target = None
for potential_hook in self.get_hooks(command):
alias_of = self._get_alias_of(potential_hook)
if alias_of:
@@ -118,97 +113,92 @@ class Module(ModuleManager.BaseModule):
"'%s' is an alias of unknown command '%s'"
% (command.lower(), alias_of.lower()))
- is_channel = "channel" in event
if not is_channel and potential_hook.kwargs.get("channel_only"):
continue
if is_channel and potential_hook.kwargs.get("private_only"):
continue
hook = potential_hook
- target = event["user"] if not is_channel else event["channel"]
break
- if not hook:
- return
+ return hook
- module_name = self._get_prefix(hook) or ""
- if not module_name and hasattr(hook.function, "__self__"):
- module_name = hook.function.__self__._name
+ def command(self, server, target, is_channel, user, command, args_split,
+ tags, statusmsg, hook, **kwargs):
+ if self._is_ignored(server, user, command):
+ return False
- msgid = MSGID_TAG.get_value(event["tags"])
- statusmsg = "".join(event.get("statusmsg", []))
- stdout = outs.StdOut(event["server"], module_name, target, msgid,
- statusmsg)
- stderr = outs.StdErr(event["server"], module_name, target, msgid,
- statusmsg)
- command_method = self._command_method(target, event["server"])
+ module_name = self._get_prefix(hook) or ""
+ if not module_name and hasattr(hook.function, "__self__"):
+ module_name = hook.function.__self__._name
- if hook.kwargs.get("remove_empty", True):
- args_split = list(filter(None, args_split))
+ msgid = MSGID_TAG.get_value(tags)
+ stdout = outs.StdOut(server, module_name, target, msgid, statusmsg)
+ stderr = outs.StdErr(server, module_name, target, msgid, statusmsg)
+ command_method = self._command_method(target, server)
- min_args = hook.kwargs.get("min_args")
- if min_args and len(args_split) < min_args:
- command_prefix = ""
- if is_channel:
- command_prefix = self._command_prefix(event["server"],
- target)
- usage = self._get_usage(hook, command, command_prefix)
- if usage:
- stderr.write("Not enough arguments, usage: %s" %
- usage).send(command_method)
- else:
- stderr.write("Not enough arguments (minimum: %d)" %
- min_args).send(command_method)
+ if hook.kwargs.get("remove_empty", True):
+ args_split = list(filter(None, args_split))
+
+ target.buffer.skip_next()
+
+ min_args = hook.kwargs.get("min_args")
+ if min_args and len(args_split) < min_args:
+ command_prefix = ""
+ if is_channel:
+ command_prefix = self._command_prefix(server, target)
+ usage = self._get_usage(hook, command, command_prefix)
+ if usage:
+ stderr.write("Not enough arguments, usage: %s" %
+ usage).send(command_method)
else:
- returns = self.events.on("preprocess.command").call_unsafe(
- hook=hook, user=event["user"], server=event["server"],
- target=target, is_channel=is_channel, tags=event["tags"],
- args_split=args_split)
+ stderr.write("Not enough arguments (minimum: %d)" %
+ min_args).send(command_method)
+ else:
+ returns = self.events.on("preprocess.command").call_unsafe(
+ hook=hook, user=user, server=server, target=target,
+ is_channel=is_channel, tags=tags, args_split=args_split,
+ command=command)
- hard_fail = False
- force_success = False
- error = None
- for returned in returns:
- if returned == utils.consts.PERMISSION_HARD_FAIL:
- hard_fail = True
- break
- elif returned == utils.consts.PERMISSION_FORCE_SUCCESS:
- force_success = True
- elif returned:
- error = returned
+ hard_fail = False
+ force_success = False
+ error = None
+ for returned in returns:
+ if returned == utils.consts.PERMISSION_HARD_FAIL:
+ hard_fail = True
+ break
+ elif returned == utils.consts.PERMISSION_FORCE_SUCCESS:
+ force_success = True
+ elif returned:
+ error = returned
- if hard_fail or (not force_success and error):
- if error:
- stderr.write(error).send(command_method)
- target.buffer.skip_next()
- return
+ if hard_fail or (not force_success and error):
+ if error:
+ stderr.write(error).send(command_method)
+ target.buffer.skip_next()
+ return True
- args = " ".join(args_split)
- server = event["server"]
- user = event["user"]
+ args = " ".join(args_split)
- new_event = self.events.on("received.command").on(command
- ).make_event(user=user, server=server, target=target,
- args=args, tags=event["tags"], args_split=args_split,
- stdout=stdout, stderr=stderr, command=command.lower(),
- is_channel=is_channel)
+ new_event = self.events.on(hook.event_name).make_event(user=user,
+ server=server, target=target, args=args, tags=tags,
+ args_split=args_split, stdout=stdout, stderr=stderr,
+ is_channel=is_channel, command=command, **kwargs)
- self.log.trace("calling command '%s': %s",
- [command, new_event.kwargs])
- try:
- hook.call(new_event)
- except utils.EventError as e:
- stderr.write(str(e))
+ self.log.trace("calling command '%s': %s",
+ [command, new_event.kwargs])
+ try:
+ hook.call(new_event)
+ except utils.EventError as e:
+ stderr.write(str(e))
- if not hook.kwargs.get("skip_out", False):
- command_method = self._command_method(
- target, event["server"])
- stdout.send(command_method)
- stderr.send(command_method)
- target.last_stdout = stdout
- target.last_stderr = stderr
- target.buffer.skip_next()
- event.eat()
+ if not hook.kwargs.get("skip_out", False):
+ command_method = self._command_method(target, server)
+ stdout.send(command_method)
+ stderr.send(command_method)
+ target.last_stdout = stdout
+ target.last_stderr = stderr
+ return new_event.eaten
def _command_prefix(self, server, channel):
return channel.get_setting("command-prefix",
@@ -225,22 +215,53 @@ class Module(ModuleManager.BaseModule):
prefixed_commands = event["channel"].get_setting("prefixed-commands", True)
command_prefix = self._command_prefix(event["server"], event["channel"])
+ command = None
+ args_split = None
if event["message_split"][0].startswith(command_prefix):
if not prefixed_commands:
return
command = event["message_split"][0].replace(
command_prefix, "", 1).lower()
- self.message(event, command)
+ args_split = event["message_split"][1:]
elif len(event["message_split"]) > 1 and self.is_highlight(
event["server"], event["message_split"][0]):
command = event["message_split"][1].lower()
- self.message(event, command, 2)
+ args_split = event["message_split"][2:]
+
+ if command:
+ hook = self._find_command_hook(event["server"], command, True)
+ if hook:
+ self.command(event["server"], event["channel"], True,
+ event["user"], command, args_split, event["tags"],
+ "".join(event["statusmsg"]), hook)
+ else:
+ regex_hook = self.events.on("command.regex").get_hooks()
+ for hook in regex_hook:
+ pattern = hook.get_kwarg("pattern", None)
+ if not pattern and hook.get_kwarg("pattern-url", None) == "1":
+ pattern = utils.http.REGEX_URL
+
+ if pattern:
+ match = re.match(pattern, event["message"])
+ if match:
+ command = hook.get_kwarg("command", "")
+ res = self.command(event["server"], event["channel"],
+ True, event["user"], command, "", event["tags"],
+ "".join(event["statusmsg"]), hook, match=match,
+ message=event["message"])
+
+ if res:
+ break
@utils.hook("received.message.private", priority=EventManager.PRIORITY_LOW)
def private_message(self, event):
if event["message_split"] and not event["action"]:
command = event["message_split"][0].lower()
- self.message(event, command)
+ hook = self._find_command_hook(event["server"], command, False)
+ if hook:
+ self.command(event["server"], event["user"], False,
+ event["user"], command, event["message_split"][1:],
+ event["tags"], "", hook)
def _get_help(self, hook):
return hook.get_kwarg("help", None) or hook.docstring.description
diff --git a/modules/karma.py b/modules/karma.py
index 2f631889..c9266ef8 100644
--- a/modules/karma.py
+++ b/modules/karma.py
@@ -20,68 +20,53 @@ class Module(ModuleManager.BaseModule):
return utils.irc.color(str(karma), utils.consts.LIGHTGREEN)
return str(karma)
-
@utils.hook("new.user")
def new_user(self, event):
event["user"].last_karma = None
- @utils.hook("received.message.channel")
+ @utils.hook("command.regex")
def channel_message(self, event):
- match = re.match(REGEX_KARMA, event["message"].strip())
- if match and not event["action"]:
- is_ignored_f = self.exports.get_one("is-ignored",
- lambda _1, _2: False)
- if is_ignored_f(event["server"], event["user"], "karma"):
- return
+ """
+ :command: karma
+ :pattern: ^(.*[^-+])[-+]*(\+{2,}|\-{2,})$
+ """
+ verbose = event["target"].get_setting("karma-verbose", False)
+ nickname_only = event["server"].get_setting("karma-nickname-only",
+ False)
- is_silenced_f = self.exports.get_one("is-silenced", lambda _: False)
- if is_silenced_f(event["channel"]):
+ if not event["user"].last_karma or (time.time()-event["user"
+ ].last_karma) >= KARMA_DELAY_SECONDS:
+ target = event["match"].group(1).strip().rstrip("".join(WORD_STOP))
+ if event["server"].irc_lower(target) == event["user"].name:
+ if verbose:
+ event["stdout"].write("You cannot change your own karma")
return
- verbose = event["channel"].get_setting("karma-verbose", False)
- nickname_only = event["server"].get_setting("karma-nickname-only",
- False)
-
- if not event["user"].last_karma or (time.time()-event["user"
- ].last_karma) >= KARMA_DELAY_SECONDS:
- target = match.group(1).strip().rstrip("".join(WORD_STOP))
- if event["server"].irc_lower(target) == event["user"].name:
- if verbose:
- self.events.on("send.stderr").call(
- module_name="Karma", target=event["channel"],
- message="You cannot change your own karma",
- server=event["server"])
+ setting = "karma-%s" % target
+ setting_target = event["server"]
+ if nickname_only:
+ user = event["server"].get_user(target)
+ setting = "karma"
+ setting_target = user
+ if not event["target"].has_user(user):
return
- setting = "karma-%s" % target
- setting_target = event["server"]
- if nickname_only:
- user = event["server"].get_user(target)
- setting = "karma"
- setting_target = user
- if not event["channel"].has_user(user):
- return
+ positive = event["match"].group(2)[0] == "+"
+ karma = setting_target.get_setting(setting, 0)
+ karma += 1 if positive else -1
- positive = match.group(2)[0] == "+"
- karma = setting_target.get_setting(setting, 0)
- karma += 1 if positive else -1
+ if not karma == 0:
+ setting_target.set_setting(setting, karma)
+ else:
+ setting_target.del_setting(setting)
- if not karma == 0:
- setting_target.set_setting(setting, karma)
- else:
- setting_target.del_setting(setting)
-
- karma_str = self._karma_str(karma)
- if verbose:
- self.events.on("send.stdout").call(
- module_name="Karma", target=event["channel"],
- message="%s now has %s karma" % (target, karma_str),
- server=event["server"])
- event["user"].last_karma = time.time()
- elif verbose:
- self.events.on("send.stderr").call(module_name="Karma",
- target=event["channel"], server=event["server"],
- message="Try again in a couple of seconds")
+ karma_str = self._karma_str(karma)
+ if verbose:
+ event["stdout"].write(
+ "%s now has %s karma" % (target, karma_str))
+ event["user"].last_karma = time.time()
+ elif verbose:
+ event["stderr"].write("Try again in a couple of seconds")
@utils.hook("received.command.karma")
def karma(self, event):
diff --git a/modules/sed.py b/modules/sed.py
index f6849810..69cbaca7 100644
--- a/modules/sed.py
+++ b/modules/sed.py
@@ -12,19 +12,18 @@ REGEX_SED = re.compile("^s/")
"validate": utils.bool_or_none})
class Module(ModuleManager.BaseModule):
def _closest_setting(self, event, setting, default):
- return event["channel"].get_setting(setting,
+ return event["target"].get_setting(setting,
event["server"].get_setting(setting, default))
- @utils.hook("received.message.channel")
+ @utils.hook("command.regex")
def channel_message(self, event):
+ """
+ :command: sed
+ :pattern: ^s/
+ """
sed_split = re.split(REGEX_SPLIT, event["message"], 3)
if event["message"].startswith("s/") and len(sed_split) > 2:
- if event["action"] or not self._closest_setting(event, "sed",
- False):
- return
- is_ignored_f = short_url = self.exports.get_one("is-ignored",
- lambda _1, _2: False)
- if is_ignored_f(event["server"], event["user"], "sed"):
+ if not self._closest_setting(event, "sed", False):
return
regex_flags = 0
@@ -50,15 +49,13 @@ class Module(ModuleManager.BaseModule):
pattern = re.compile(sed_split[1], regex_flags)
except:
traceback.print_exc()
- self.events.on("send.stderr").call(target=event["channel"],
- module_name="Sed", server=event["server"],
- message="Invalid regex in pattern")
+ event["stderr"].write("Invalid regex in pattern")
return
replace = utils.irc.bold(sed_split[2].replace("\\/", "/"))
for_user = event["user"].nickname if self._closest_setting(event,
"sed-sender-only", False) else None
- line = event["channel"].buffer.find(pattern, from_self=False,
+ line = event["target"].buffer.find(pattern, from_self=False,
for_user=for_user, not_pattern=REGEX_SED)
if line:
new_message = re.sub(pattern, replace, line.message, count)
@@ -66,6 +63,4 @@ class Module(ModuleManager.BaseModule):
prefix = "* %s" % line.sender
else:
prefix = "<%s>" % line.sender
- self.events.on("send.stdout").call(target=event[
- "channel"], module_name="Sed", server=event["server"],
- message="%s %s" % (prefix, new_message))
+ event["stdout"].write("%s %s" % (prefix, new_message))
diff --git a/modules/title.py b/modules/title.py
index ba2d946c..79a9e8ab 100644
--- a/modules/title.py
+++ b/modules/title.py
@@ -44,40 +44,33 @@ class Module(ModuleManager.BaseModule):
else:
return None
- @utils.hook("received.message.channel",
+ @utils.hook("command.regex",
priority=EventManager.PRIORITY_MONITOR)
def channel_message(self, event):
- match = re.search(utils.http.REGEX_URL, event["message"])
- if match and event["channel"].get_setting("auto-title", False):
- is_ignored_f = short_url = self.exports.get_one("is-ignored",
- lambda _1, _2: False)
- if is_ignored_f(event["server"], event["user"], "title"):
- return
-
- url = match.group(0)
- title = self._get_title(event["channel"], match.group(0))
-
- if title:
- message = title
- if event["channel"].get_setting("auto-title-first", False):
- setting = "url-last-%s" % self._url_hash(url)
- first_details = event["channel"].get_setting(setting, None)
-
- if first_details:
- first_nickname, first_timestamp, _ = first_details
- timestamp_parsed = utils.iso8601_parse(first_timestamp)
- timestamp_human = utils.datetime_human(timestamp_parsed)
- message = "%s (first posted by %s at %s)" % (title,
- first_nickname, timestamp_human)
- else:
- event["channel"].set_setting(setting,
- [event["user"].nickname, utils.iso8601_format_now(),
- url])
+ """
+ :command: title
+ :pattern-url: 1
+ """
+ url = event["match"].group(0)
+ title = self._get_title(event["target"], event["match"].group(0))
+ if title:
+ message = title
+ if event["target"].get_setting("auto-title-first", False):
+ setting = "url-last-%s" % self._url_hash(url)
+ first_details = event["target"].get_setting(setting, None)
- self.events.on("send.stdout").call(target=event["channel"],
- message=message, module_name="Title",
- server=event["server"])
+ if first_details:
+ first_nickname, first_timestamp, _ = first_details
+ timestamp_parsed = utils.iso8601_parse(first_timestamp)
+ timestamp_human = utils.datetime_human(timestamp_parsed)
+ message = "%s (first posted by %s at %s)" % (title,
+ first_nickname, timestamp_human)
+ else:
+ event["target"].set_setting(setting,
+ [event["user"].nickname, utils.iso8601_format_now(),
+ url])
+ event["stdout"].write(message)
@utils.hook("received.command.t", alias_of="title")
@utils.hook("received.command.title", usage="[URL]")
diff --git a/modules/youtube.py b/modules/youtube.py
index f29250db..8f01fd45 100644
--- a/modules/youtube.py
+++ b/modules/youtube.py
@@ -125,20 +125,17 @@ class Module(ModuleManager.BaseModule):
else:
event["stderr"].write("No search phrase provided")
- @utils.hook("received.message.channel",
+ @utils.hook("command.regex",
priority=EventManager.PRIORITY_LOW)
def channel_message(self, event):
- match = re.search(REGEX_YOUTUBE, event["message"])
- if match and event["channel"].get_setting("auto-youtube", False):
- is_ignored_f = short_url = self.exports.get_one("is-ignored",
- lambda _1, _2: False)
- if is_ignored_f(event["server"], event["user"], "youtube"):
- return
-
- youtube_id = match.group(1)
+ """
+ :command: youtube
+ :-pattern: https?://(?:www.)?
+ (?:youtu.be/|youtube.com/watch\?[\S]*v=)([\w\-]{11})
+ """
+ if event["target"].get_setting("auto-youtube", False):
+ youtube_id = event["match"].group(1)
video_details = self.video_details(youtube_id)
if video_details:
- self.events.on("send.stdout").call(target=event["channel"],
- message=video_details, module_name="Youtube",
- server=event["server"])
+ event["stdout"].write(video_details)
event.eat()