Make command processing a bit more readable and comment the logic since it's all a bit complex
Diff
dave/dave.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 67 insertions(+), 32 deletions(-)
@@ -44,6 +44,7 @@
def signedOn(self):
"""Called when bot has succesfully signed on to server."""
self.mode(self.nickname, True, "B")
for channel in config.config["irc"]["channels"]:
@@ -57,69 +58,102 @@
def privmsg(self, user, channel, msg):
"""This will get called when the bot receives a message."""
nick = user.split("!", 1)[0]
userhost = user.split("!", 1)[1]
nick, userhost = user.split("!", 1)
log.msg("<{}> {}".format(user, msg))
path = modules.__path__
prefix = "{}.".format(modules.__name__)
method = (99999, None)
method = (99999, None)
run = []
if channel == self.nickname:
channel = nick
match = re.match(r"^(?:{}[:,]? ){}(.*)$".format(
self.nickname,
"?" if channel == nick else ""
), msg)
invoked = bool(match)
msg = match.group(1) if invoked else msg
for importer, modname, ispkg in pkgutil.iter_modules(path, prefix):
m = importer.find_module(modname).load_module(modname)
for name, val in m.__dict__.items():
if callable(val) and hasattr(val, "rule"):
priority = val.priority.value if hasattr(val, "priority") else 0
if method[0] < priority and not hasattr(val, "always_run"):
if not callable(val) or not hasattr(val, "rule"):
continue
priority = val.priority.value if hasattr(val, "priority") else 0
if method[0] < priority and not hasattr(val, "always_run"):
continue
for rule in val.rule:
if rule["named"] and not invoked:
continue
for rule in val.rule:
if channel == nick:
regex = r"^(?:{}(?::|,|) )?(.*)$".format(self.nickname) \
if rule["named"] else r"^(.*)$"
match = re.match(rule["pattern"], msg)
if match:
if hasattr(val, "always_run"):
run.append((val, match.groups()))
else:
regex = r"^{}(?::|,|) (.*)$".format(self.nickname) \
if rule["named"] else r"^(.*)$"
match = re.match(regex, msg)
if match:
match = re.match(rule["pattern"], match.group(1))
if match:
if hasattr(val, "always_run"):
run.append((val, match.groups()))
else:
method = (priority, val, match.groups(),
rule["named"])
method = (priority, val, match.groups(), rule["named"])
break
ignore_dont_always_run = False
if method[1] is not None:
if ratelimit(method[1], userhost):
deferToThread(method[1], self, method[2], nick, channel)
elif method[3]:
self.reply(channel, nick, "You have been ratelimited for this command.")
else:
ignore_dont_always_run = True
if method[1] is None or ignore_dont_always_run or \
not (hasattr(method[1], "dont_always_run") and method[1].dont_always_run):
for m in run:
if not hasattr(m[0], "ratelimit") or ratelimit(m[0], userhost):
@@ -127,10 +161,11 @@
def irc_unknown(self, prefix, command, params):
if command == "INVITE":
self.join(params[1])
def msg(self, dest, message, length=None):
"""Override msg() to log what the bot says"""
"""Override msg() to log what the bot says and to make msg thread safe."""
log.msg("<{}> {}".format(self.nickname, message))
reactor.callFromThread(super(Dave, self).msg, dest, message, length)