From d2ed4859958a24677fd4dab25391e9e6016a81f8 Mon Sep 17 00:00:00 2001 From: random-nick Date: Tue, 24 Jul 2018 18:27:45 +0200 Subject: [PATCH] Rework how the !rolestats command parses its arguments (#350) Now it tries completing the everything as a role first before attempting to complete it as a gamemode. --- src/db.py | 44 ++++++++++++++++++++++++++++-------- src/utilities.py | 12 ++++------ src/wolfgame.py | 59 +++++++++++++++++++++++++++++++----------------- 3 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/db.py b/src/db.py index 2b6a7e2e..b54f2a29 100644 --- a/src/db.py +++ b/src/db.py @@ -512,23 +512,47 @@ def get_role_stats(role, mode=None): else: return "No stats for \u0002{0}\u0002 in \u0002{1}\u0002.".format(role, mode) -def get_role_totals(): +def get_role_totals(mode=None): conn = _conn() c = conn.cursor() - c.execute("SELECT COUNT(1) FROM game") + if mode is None: + c.execute("SELECT COUNT(1) FROM game") + else: + c.execute("SELECT COUNT(1) FROM game WHERE gamemode = ?", (mode,)) total_games = c.fetchone()[0] if not total_games: - return "No games played." - c.execute("""SELECT - gpr.role AS role, - COUNT(1) AS count - FROM game_player_role gpr - GROUP BY role - ORDER BY count DESC""") + if mode is None: + return "No games played." + else: + return "No games played in the \u0002{0}\u0002 gamemode".format(mode) + + if mode is None: + c.execute("""SELECT + gpr.role AS role, + COUNT(1) AS count + FROM game_player_role gpr + GROUP BY role + ORDER BY count DESC""") + else: + c.execute("""SELECT + gpr.role AS role, + COUNT(1) AS count + FROM game_player_role gpr + JOIN game_player gp + ON gp.id = gpr.game_player + JOIN game g + ON g.id = gp.game + WHERE g.gamemode = ? + GROUP BY role + ORDER BY count DESC""", (mode,)) + totals = [] for row in c: totals.append("\u0002{0}\u0002: {1}".format(*row)) - return "Total games: {0} | {1}".format(total_games, ", ".join(totals)) + if mode is None: + return "Total games: {0} | {1}".format(total_games, ", ".join(totals)) + else: + return "\u0002{0}\u0002 games: {1} | {2}".format(mode, total_games, ", ".join(totals)) def get_warning_points(acc, hostmask): diff --git a/src/utilities.py b/src/utilities.py index b2842b2b..446f3323 100644 --- a/src/utilities.py +++ b/src/utilities.py @@ -376,7 +376,7 @@ def get_victim(cli, nick, victim, in_chan, self_in_list=False, bot_in_list=False class InvalidModeException(Exception): pass -def complete_role(var, wrapper, role): +def complete_role(var, role): if role not in var.ROLE_GUIDE.keys(): special_keys = {"lover"} evt = Event("get_role_metadata", {}) @@ -387,12 +387,8 @@ def complete_role(var, wrapper, role): else: matches = complete_match(role, var.ROLE_GUIDE.keys() | special_keys) if not matches: - wrapper.reply(messages["no_such_role"].format(role)) - return False - if len(matches) > 1: - wrapper.reply(messages["ambiguous_role"].format(", ".join(matches))) - return False - return matches[0] - return role + return [] + return matches + return [role] # vim: set sw=4 expandtab: diff --git a/src/wolfgame.py b/src/wolfgame.py index b4e4a223..de0ef74b 100644 --- a/src/wolfgame.py +++ b/src/wolfgame.py @@ -5591,30 +5591,47 @@ def role_stats(var, wrapper, rest): wrapper.pm(messages["stats_wait_for_game_end"]) return - rest = rest.split() - if len(rest) == 0: + params = rest.split() + + if len(params) == 0: # this is a long message wrapper.pm(db.get_role_totals()) - elif len(rest) == 1 or (rest[-1] == "all" and rest.pop()): - role = complete_role(var, wrapper, " ".join(rest)) - if role: - wrapper.reply(db.get_role_stats(role)) - else: - role = complete_role(var, wrapper, " ".join(rest[:-1])) - if not role: + return + + roles = complete_role(var, rest) + if params[-1] == "all" and len(roles) != 1: + roles = complete_role(var, " ".join(params[:-1])) + if len(roles) == 1: + wrapper.reply(db.get_role_stats(roles[0])) + return + + gamemode = params[-1] + if gamemode not in var.GAME_MODES.keys(): + matches = complete_match(gamemode, var.GAME_MODES.keys()) + if len(matches) == 1: + gamemode = matches[0] + else: + if len(roles) > 0: + wrapper.pm(messages["ambiguous_role"].format(", ".join(roles))) + elif len(matches) > 0: + wrapper.pm(messages["ambiguous_mode"].format(gamemode, ", ".join(matches))) + else: + wrapper.pm(messages["no_such_role"].format(rest)) return - gamemode = rest[-1] - if gamemode not in var.GAME_MODES.keys(): - matches = complete_match(gamemode, var.GAME_MODES.keys()) - if len(matches) == 1: - gamemode = matches[0] - if not matches: - wrapper.pm(messages["invalid_mode"].format(rest[1])) - return - if len(matches) > 1: - wrapper.pm(messages["ambiguous_mode"].format(rest[1], ", ".join(matches))) - return - wrapper.reply(db.get_role_stats(role, gamemode)) + + if len(params) == 1: + wrapper.pm(db.get_role_totals(gamemode)) + return + + role = " ".join(params[:-1]) + roles = complete_role(var, role) + if len(roles) != 1: + if len(roles) == 0: + wrapper.pm(messages["no_such_role"].format(role)) + else: + wrapper.pm(messages["ambiguous_role"].format(", ".join(roles))) + return + wrapper.reply(db.get_role_stats(roles[0], gamemode)) # Called from !game and !join, used to vote for a game mode def vote_gamemode(var, wrapper, gamemode, doreply):