diff --git a/migration/v01.16.00-karma.py b/migration/v01.16.00-karma.py new file mode 100644 index 00000000..a7a502fd --- /dev/null +++ b/migration/v01.16.00-karma.py @@ -0,0 +1,45 @@ +# Used to migrate karma from prior to v1.16.0 +# usage: $ python3 migration/v01.16.00-karma.py ~/.bitbot/bot.db + +import argparse +parser = argparse.ArgumentParser(description="Migrate pre-v1.16.0 karma") +parser.add_argument("database") +args = parser.parse_args() + +import json, sqlite3 +database = sqlite3.connect(args.database) + +cursor = database.cursor() +cursor.execute( + """SELECT server_id, setting, value FROM server_settings + WHERE setting LIKE 'karma-%'""") +results = cursor.fetchall() + +cursor.execute("SELECT nickname, user_id FROM users") +users = dict(cursor.fetchall()) + +cursor.execute("SELECT server_id, alias FROM servers") +servers = dict(cursor.fetchall()) + +server_users = {} +for server_id, setting, karma in results: + if not server_id in server_users: + cursor.execute( + "INSERT INTO users (server_id, nickname) VALUES (?, ?)", + [server_id, "*karma"]) + cursor.execute( + "SELECT user_id FROM users WHERE server_id=? AND nickname=?", + [server_id, "*karma"]) + server_users[server_id] = cursor.fetchone()[0] + + print("[%s] Migrating '%s' (%s)" % + (servers[server_id], setting.replace("karma-", "", 1), karma)) + cursor.execute( + "INSERT INTO user_settings VALUES (?, ?, ?)", + [server_users[server_id], setting, karma]) + +database.commit() +database.close() + +print() +print("Migration successful!") diff --git a/modules/karma.py b/modules/karma.py index 2634f8d6..2bdd5e99 100644 --- a/modules/karma.py +++ b/modules/karma.py @@ -12,8 +12,6 @@ REGEX_PARENS = re.compile(r"\(([^)]+)\)(\+\+|--)") @utils.export("channelset", utils.BoolSetting("karma-pattern", "Enable/disable parsing ++/-- karma format")) -@utils.export("serverset", utils.BoolSetting("karma-nickname-only", - "Enable/disable karma being for nicknames only")) class Module(ModuleManager.BaseModule): def _karma_str(self, karma): karma_str = str(karma) @@ -43,37 +41,28 @@ class Module(ModuleManager.BaseModule): else: user._last_negative_karma = time.time() - - def _karma(self, server, sender, target, positive): - if self._check_throttle(sender, positive): - nickname_only = server.get_setting("karma-nickname-only", False) - - if server.irc_lower(target) == sender.name: - return False, "You cannot change your own karma" - - setting = "karma-%s" % target - setting_target = server - if nickname_only: - user = server.get_user(target, create=False) - if user == None: - return False, "No such user" - setting = "karma" - setting_target = user - - 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) - - karma_str = self._karma_str(karma) - self._set_throttle(sender, positive) - return True, "%s now has %s karma" % (target, karma_str) - else: + def _change_karma(self, server, sender, target, positive): + if not self._check_throttle(sender, positive): return False, "Try again in a couple of seconds" + if " " in target and server.has_user(target): + target = server.get_user_nickname(target.get_id()) + else: + target = target.lower() + + setting = "karma-%s" % target + karma = sender.get_setting(setting, 0) + karma += 1 if positive else -1 + + if karma == 0: + sender.del_setting(setting) + else: + sender.set_setting(setting, karma) + + self._set_throttle(sender, positive) + karma_str = self._karma_str(karma) + return True, "%s now has %s karma" % (target, karma_str) + @utils.hook("command.regex", pattern=REGEX_WORD) @utils.hook("command.regex", pattern=REGEX_PARENS) @utils.kwarg("command", "karma") @@ -81,8 +70,8 @@ class Module(ModuleManager.BaseModule): if event["target"].get_setting("karma-pattern", False): target = event["match"].group(1) positive = event["match"].group(2)=="++" - success, message = self._karma(event["server"], event["user"], - target, positive) + success, message = self._change_karma( + event["server"], event["user"], target, positive) event["stdout" if success else "stderr"].write(message) @@ -92,8 +81,8 @@ class Module(ModuleManager.BaseModule): @utils.kwarg("usage", "") def changepoint(self, event): positive = event["command"] == "addpoint" - success, message = self._karma(event["server"], event["user"], - event["args"].strip(), positive) + success, message = self._change_karma( + event["server"], event["user"], event["args"].strip(), positive) event["stdout" if success else "stderr"].write(message) @utils.hook("received.command.karma") @@ -108,26 +97,50 @@ class Module(ModuleManager.BaseModule): target = event["user"].nickname target = target.strip() - if event["server"].get_setting("karma-nickname-only", False): - karma = event["server"].get_user(target).get_setting("karma", 0) - else: - karma = event["server"].get_setting("karma-%s" % target, 0) - karma_str = self._karma_str(karma) - event["stdout"].write("%s has %s karma" % (target, karma_str)) + settings = dict( + event["server"].get_all_user_settings("karma-%s" % target)) - @utils.hook("received.command.resetkarma", min_args=1) + target_lower = event["server"].irc_lower(target) + if target_lower in settings: + del settings[target_lower] + + karma = self._karma_str(sum(settings.values())) + event["stdout"].write("%s has %s karma" % (target, karma)) + + + @utils.hook("received.command.resetkarma") + @utils.kwarg("min_args", 2) + @utils.kwarg("help", "Reset a specific karma to 0") + @utils.kwarg("usage", "by|for ") + @utils.kwarg("permission", "resetkarma") def reset_karma(self, event): - """ - :help: Reset a specified karma to 0 - :usage: - :permission: resetkarma - """ - setting = "karma-%s" % event["args_split"][0] - karma = event["server"].get_setting(setting, 0) - if karma == 0: - event["stderr"].write("%s already has 0 karma" % event[ - "args_split"][0]) + subcommand = event["args_split"][0].lower() + target = " ".join(event["args_split"][1:]) + + if subcommand == "by": + target_user = event["server"].get_user(target) + karma = target_user.find_setting(prefix="karma-") + print(target_user) + print(target_user.get_id()) + for setting, _ in karma: + target_user.del_setting(setting) + + if karma: + event["stdout"].write("Cleared karma by %s" % + target_user.nickname) + else: + event["stderr"].write("No karma to clear by %s" % + target_user.nickname) + elif subcommand == "for": + setting = "karma-%s" % target + karma = event["server"].get_all_user_settings(setting) + for nickname, value in karma: + user = event["server"].get_user(nickname) + user.del_setting(setting) + + if karma: + event["stdout"].write("Cleared karma for %s" % target) + else: + event["stderr"].write("No karma to clearfor %s" % target) else: - event["server"].del_setting(setting) - event["stdout"].write("Reset karma for %s" % event[ - "args_split"][0]) + raise utils.EventError("Unknown subcommand '%s'" % subcommand) diff --git a/src/IRCServer.py b/src/IRCServer.py index 1e069e5f..92c82350 100644 --- a/src/IRCServer.py +++ b/src/IRCServer.py @@ -193,6 +193,10 @@ class Server(IRCObject.Object): def has_user_id(self, nickname: str) -> bool: id = self.bot.database.users.get_id(self.id, self.irc_lower(nickname)) return not id == None + + def get_user_nickname(self, user_id: int) -> str: + return self.bot.database.users.get_nickname(self.id, user_id) + def remove_user(self, user: IRCUser.User): del self.users[user.nickname_lower] for channel in user.channels: