diff --git a/.gitignore b/.gitignore index 735acc5..a2f5d33 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ settings.json settings.demo.json data/*.json -logs/*.log +logs/*.log* irc/ # ---> Python diff --git a/actions/__init__.py b/actions/__init__.py index e3232d2..155ea41 100644 --- a/actions/__init__.py +++ b/actions/__init__.py @@ -1,8 +1,8 @@ from actions.botlist import botlist -from actions.web import summon, whois from actions.access import banish, pardon from actions.control import puppet, inject, nomad -from actions.stupid import hmm, hmmscore, hmmscoreboard +from actions.web import summon, whois, how_dare_you +from actions.stupid import score_word, wordscore, wordscoreboard actions = [ { @@ -20,6 +20,11 @@ actions = [ "pattern": "/!summon \S+ .+/", "callback": summon }, + { + "type": "response", + "pattern": "/!summon \S+$/", + "callback": how_dare_you + }, { "type": "response", "pattern": "/!banish \S+ .+/", @@ -48,17 +53,32 @@ actions = [ { "type": "response", "pattern": "/hm+/", - "callback": hmm + "callback": score_word("hmm", "hm+") }, { "type": "response", "pattern": "/!hmmscore(\s|$)/", - "callback": hmmscore + "callback": wordscore("hmm") }, { "type": "response", "pattern": "!hmmscoreboard", - "callback": hmmscoreboard + "callback": wordscoreboard("hmm") + }, + { + "type": "response", + "pattern": "/o+f/", + "callback": score_word("oof", "o+f") + }, + { + "type": "response", + "pattern": "/!oofscore(\s|$)/", + "callback": wordscore("oof") + }, + { + "type": "response", + "pattern": "!oofscoreboard", + "callback": wordscoreboard("oof") }, { "type": "response", diff --git a/actions/access.py b/actions/access.py index 778d259..0de9c1f 100644 --- a/actions/access.py +++ b/actions/access.py @@ -16,7 +16,7 @@ def banish(self, name, source, response): "when": datetime.now().timestamp() } - self.bot.save_memories() + self.bot.thread(self.bot.save_memories) confirmation = "{} has been banished for reason: {}".format(user, reason) self.bot.send_message(source, confirmation) @@ -31,7 +31,7 @@ def pardon(self, name, source, response): del self.bot.memories["users"][user]["blacklist"] - self.bot.save_memories() + self.bot.thread(self.bot.save_memories) confirmation = "{} has been pardoned".format(user) self.bot.send_message(source, confirmation) \ No newline at end of file diff --git a/actions/stupid.py b/actions/stupid.py index 299fb87..0658f08 100644 --- a/actions/stupid.py +++ b/actions/stupid.py @@ -1,64 +1,81 @@ import re import operator -def hmm(self, name, source, response): - check = response.lower().strip() +def capitalize(word): + return word[0].upper() + word[1:] - botnick = self.bot.botnick - pattern = re.compile("hm+") - matches = re.findall(pattern, check) - maximum = 10 - score = len(matches) if len(matches) <= maximum else maximum +def score_word(word, regex): + def wording(self, name, source, response): + check = response.lower().strip() - if len(matches) > 1 and len("".join(re.split(pattern, check))) == 0: - return + botnick = self.bot.botnick + pattern = re.compile(regex)#"hm+") + matches = re.findall(pattern, check) + maximum = 10 + score = len(matches) if len(matches) <= maximum else maximum - if name not in self.bot.memories["users"]: - self.bot.memories["users"][name] = dict() + if len(matches) > 1 and len("".join(re.split(pattern, check))) == 0: + return - if "hmmscore" not in self.bot.memories["users"][name]: - self.bot.memories["users"][name]["hmmscore"] = 0 + if name not in self.bot.memories["users"]: + self.bot.memories["users"][name] = dict() - current_score = self.bot.memories["users"][name]["hmmscore"] - self.bot.memories["users"][name]["hmmscore"] = current_score + score + keyword = "{}score".format(word) - self.bot.save_memories() + if keyword not in self.bot.memories["users"][name]: + self.bot.memories["users"][name][keyword] = 0 -def hmmscore(self, name, source, response): - botnick = self.bot.botnick - score = 0 - score_format = "Hmm score for '{}': {}" + current_score = self.bot.memories["users"][name][keyword] + self.bot.memories["users"][name][keyword] = current_score + score - if " " in response: - name = response.split(" ", 1)[1].strip() + self.bot.thread(self.bot.save_memories) + return wording - if name not in self.bot.memories["users"]: +def wordscore(word): + def scoring(self, name, source, response): + botnick = self.bot.botnick + score = 0 + score_format = "%s score for '{}': {}" % (capitalize(word)) + + if " " in response: + name = response.split(" ", 1)[1].strip() + + if name not in self.bot.memories["users"]: + self.bot.send_message(source, score_format.format(name, score)) + return + + keyword = "{}score".format(word) + + if keyword not in self.bot.memories["users"][name]: + self.bot.send_message(source, score_format.format(name, score)) + return + + score = self.bot.memories["users"][name][keyword] self.bot.send_message(source, score_format.format(name, score)) - return + return scoring - if "hmmscore" in self.bot.memories["users"][name]: - score = self.bot.memories["users"][name]["hmmscore"] - self.bot.send_message(source, score_format.format(name, score)) - return +def wordscoreboard(word): + def scoreboard(self, name, source, response): + botnick = self.bot.botnick + scores = list() -def hmmscoreboard(self, name, source, response): - botnick = self.bot.botnick - hmmscores = list() + for user, values in self.bot.memories["users"].items(): + scores.append({ + "name": user, + "score": values.get("{}score".format(word), 0) + }) - for user, values in self.bot.memories["users"].items(): - hmmscores.append({ - "name": user, - "score": values.get("hmmscore", 0) - }) + size = 3 + start = -size - size = 3 - start = -size + sort_scores = sorted(scores, key=lambda k: k["score"]) + top_scores = sort_scores[start:][::-1] - sort_scores = sorted(hmmscores, key=lambda k: k["score"]) - top_scores = sort_scores[start:][::-1] + leaders = " | ".join([ + "{} {}".format(ts["name"], ts["score"]) for ts in top_scores + ]) - leaders = " | ".join([ - "{} {}".format(ts["name"], ts["score"]) for ts in top_scores - ]) + response = "{} Score Leaderboard: {}".format(capitalize(word), leaders) - self.bot.send_message(source, "Hmm Score Leaderboard: {}".format(leaders)) \ No newline at end of file + self.bot.send_message(source, response) + return scoreboard \ No newline at end of file diff --git a/actions/web.py b/actions/web.py index ddc2895..47904d7 100644 --- a/actions/web.py +++ b/actions/web.py @@ -74,6 +74,11 @@ def summon(self, name, source, response): confirmation = "{}: You have summoned {}".format(name, user) self.bot.send_message(source, confirmation) +def how_dare_you(self, name, source, response): + user = response.split("!summon ")[1] + rude = "{}: You think you can just summon someone without a reason? Rude." + self.bot.send_message(source, rude.format(user)) + def whois(self, name, source, response): botnick = self.bot.botnick domain = response.split("!whois ")[1] diff --git a/app.py b/app.py index 3474664..31b722a 100755 --- a/app.py +++ b/app.py @@ -68,17 +68,26 @@ def handle_mode(channel, mode): try_to_king_me(channel) def handle_invite(channel, name): + changed = False + if channel in kingme: try_to_king_me(channel) users = bot.memories["users"] if name not in users: bot.memories["users"][name] = dict() + changed = True if "invites" not in users[name]: bot.memories["users"][name]["invites"] = list() + changed = True - bot.memories["users"][name]["invites"].append(channel) + if channel not in bot.memories["users"][name]["invites"]: + bot.memories["users"][name]["invites"].append(channel) + changed = True + + if changed: + bot.thread(bot.save_memories) def handle_kick(name): users = bot.memories["users"] @@ -86,6 +95,7 @@ def handle_kick(name): bot.memories["users"][name] = dict() bot.memories["users"][name]["kicker"] = True + bot.thread(bot.save_memories) def handle_message(name, source, response): responses.parse(name, source, response) diff --git a/bot/core.py b/bot/core.py index 2240ffd..cfa9d06 100644 --- a/bot/core.py +++ b/bot/core.py @@ -3,6 +3,7 @@ import json import socket import os.path import logging +from threading import Thread from logging.handlers import TimedRotatingFileHandler logging.basicConfig( @@ -76,12 +77,11 @@ class Bot: return raw_users = user_listing[1].split(" \r\n")[0].split(" ") - prefix_filter = lambda u: u[1:] if "~" in u or "@" in u else u - users = list(filter(prefix_filter, raw_users)) + # prefix_filter = lambda u: u[1:] if "~" in u or "@" in u or "+" in u else u + users = list(filter(self.parse_name, raw_users)) remember = self.memories["users"] for user in users: - if user[0] == "~" or user[0] == "@": - user = user[1:] + user = self.parse_name(user) if user not in remember: self.memories["users"][user] = dict() @@ -98,21 +98,31 @@ class Bot: def get_name(self, text): return text.split("!", 1)[0][1:] + def parse_name(self, name): + if name[0] == "~" or name[0] == "@" or name[0] == "+": + return name[1:] + else: + return name + def parse(self, message): before, after = message.split("PRIVMSG ", 1) - name = self.get_name(before) + name = self.parse_name(self.get_name(before)) source, response = after.split(" :", 1) return name, source, response def handle_mode(self, message): before, after = message.split("MODE ", 1) - name = self.get_name(before) + name = self.parse_name(self.get_name(before)) channel, mode = after.split(" ")[:2] return channel, mode def handle_rename(self, message): before, new_name = message.split("NICK ", 1) name = self.get_name(before) + + new_name = self.parse_name(new_name) + name = self.parse_name(name) + user = self.memories["users"][name] del self.memories["users"][name] self.memories["users"][new_name] = user @@ -120,19 +130,19 @@ class Bot: def handle_invite(self, message): before, after = message.split("INVITE ", 1) - name = self.get_name(before) + name = self.parse_name(self.get_name(before)) channel = after.split(":", 1)[1] self.join(channel) return channel, name def handle_kick(self, message): before, after = message.split("KICK ", 1) - name = self.get_name(before) + name = self.parse_name(self.get_name(before)) return name def handle_join(self, message): before, after = message.split("JOIN ", 1) - user = self.get_name(before) + user = self.parse_name(self.get_name(before)) if user not in self.memories["users"]: self.memories["users"][user] = dict() @@ -141,7 +151,7 @@ class Bot: def handle_part(self, message): before, after = message.split("PART ", 1) - user = self.get_name(before) + user = self.parse_name(self.get_name(before)) return user def load_memories(self, location): @@ -156,6 +166,11 @@ class Bot: with open(path, "r") as f: self.memories = json.loads(f.read()) + def thread(self, fn, *args): + print((self, *args)) + t = Thread(target=fn, args=args) + t.start() + def save_memories(self): with open(self.memories_path, "w") as f: try: @@ -243,6 +258,11 @@ class Bot: message = self.ircsock.recv(self.recv_size).decode() message = message.strip(self.splitter) print(message) + + if "new_nick' commands." in message: + self.logger.warning(message) + self.send_message(self.author, "ERROR: {}".format(message)) + self.logger.debug(message) if "raw" in callback: