X-Git-Url: https://jfr.im/git/erebus.git/blobdiff_plain/522e454a29041bf38e86a402602d00c2d7ab2682..d2439073c0e0cbc981c00e1a26fbd9bab2b2cff7:/modules/trivia.py diff --git a/modules/trivia.py b/modules/trivia.py index cf67a2a..555ad55 100644 --- a/modules/trivia.py +++ b/modules/trivia.py @@ -271,7 +271,7 @@ class TriviaState(object): def endPointVote(self): self.getchan().msg("Voting has ended!") - votelist = sorted(self.voteamounts.items(), key=lambda item: item[1]) #sort into list of tuples: [(option, number_of_votes), ...] + votelist = sorted(self.voteamounts.items(), key=lambda item: (item[1], -item[0])) #sort into list of tuples: [(option, number_of_votes), ...] for i in range(len(votelist)-1): item = votelist[i] self.getchan().msg("%s place: %s (%s votes)" % (len(votelist)-i, item[0], item[1])) @@ -419,6 +419,13 @@ class TriviaState(object): else: return len(self.db['users'])+1 + def get_streak(self, user): + user = str(user).lower() + if user in self.db['streaks']: + return self.db['streaks'][user] + else: + return [0,0] + def targetuser(self, user): if len(self.db['ranks']) == 0: return "no one is ranked!" @@ -466,8 +473,16 @@ def trivia_checkanswer(bot, user, chan, *args): response += ". New score: %d. Rank: %d. Target: %s %s" % (state.addpoint(user), state.rank(user), state.targetuser(user), state.targetpoints(user)) bot.fastmsg(chan, response) + user_lower = str(user).lower() + new_max_streak = "" + if user_lower not in state.db['streaks']: + state.db['streaks'][user_lower] = [0, 0] + if state.streak > state.db['streaks'][user_lower][0]: + state.db['streaks'][user_lower] = [state.streak, time.time()] + new_max_streak = " That's a new record for them!" + if state.streak >= 3: - bot.msg(chan, "\00312%s\003 is on a streak! \00307%d\003 answers correct in a row!" % (user, state.streak)) + bot.msg(chan, "\00312%s\003 is on a streak! \00307%d\003 answers correct in a row!%s" % (user, state.streak, new_max_streak)) if state.hintsgiven == 0: bot.msg(chan, "\00312%s\003 got an extra point for getting it before the hints! New score: %d." % (user, state.addpoint(user))) @@ -488,7 +503,7 @@ def save(bot, user, chan, realtarget, *args): @lib.hook(needchan=False, wantchan=True) @lib.help("[]", "shows how many points you or someone has") def points(bot, user, chan, realtarget, *args): - if chan is not None: eplyto = chan + if chan is not None: replyto = chan else: replyto = user if len(args) != 0: who = args[0] @@ -718,7 +733,7 @@ def questionpause(bot, user, chan, realtarget, *args): bot.msg(user, "Failed to set questionpause.") @lib.hook(glevel=1, needchan=False) -@lib.help("[@category] ", "finds a question (qid) given a (partial) question") +@lib.help("[@] ", "finds a question (qid) given a (partial) question") @lib.argsGE(1) def findq(bot, user, chan, realtarget, *args): args = list(args) @@ -729,7 +744,7 @@ def findq(bot, user, chan, realtarget, *args): questions = state.questions pattern = re.escape(' '.join(args)) - bot.msg(user, _findq(questions, pattern)) + return _findq(questions, pattern) @lib.hook(glevel=1, needchan=False) @lib.help("[@] ", "finds a question (qid) given a regex") @@ -742,17 +757,31 @@ def findqre(bot, user, chan, realtarget, *args): else: questions = state.questions pattern = ' '.join(args) - bot.msg(user, _findq(questions, pattern)) + return _findq(questions, pattern) -def _findq(questions, pattern): +@lib.hook(glevel=1, needchan=False) +@lib.help("[@] ", "finds a question (qid) given a (partial) question or answer") +@lib.argsGE(1) +def findqa(bot, user, chan, realtarget, *args): + args = list(args) + if args[0].startswith("@"): + cat = args.pop(0)[1:].lower() + questions = state.db['questions'][cat] + else: + questions = state.questions + pattern = ' '.join(args) + return _findq(questions, pattern, True) + +def _findq(questions, pattern, check_answers=False): searcher = re.compile(pattern, re.IGNORECASE) - matches = [str(i) for i in range(len(questions)) if searcher.search(questions[i][0]) is not None] + matches = [i for i in range(len(questions)) if searcher.search(questions[i][0]) is not None or (check_answers and searcher.search(questions[i][1]) is not None)] if len(matches) > 25: return "Too many matches! (>25)" elif len(matches) > 1: - return "Multiple matches: %s" % (', '.join(matches)) + return "Multiple matches: %s" % (', '.join(str(x) for x in matches)) elif len(matches) == 1: - return "One match: %s" % (matches[0]) + i = matches[0] + return "One match: %s %s*%s" % (i, questions[i][0], questions[i][1]) else: return "No match." @@ -860,12 +889,59 @@ def delcat(bot, user, chan, realtarget, *args): else: bot.msg(user, "Category does not exist.") +@lib.hook(needchan=False) +@lib.help("[]", "shows a user's (or your own) max streak") +def streak(bot, user, chan, realtarget, *args): + if chan is not None: replyto = chan + else: replyto = user + + if len(args) != 0: who = args[0] + else: who = user + + streak = state.get_streak(who) + bot.msg(replyto, "%s's highest streak is %d, set %s" % (who, streak[0], time.strftime("%d %b %Y %H:%M:%S %Z", time.gmtime(streak[1])))) + +@lib.hook(needchan=False) +@lib.help(None, "shows top streaks of all time") +def topstreaks(bot, user, chan, realtarget, *args): + db = state.db['streaks'] + streaks = [(nick, db[nick][0], db[nick][1]) for nick in db.keys()] + streaks.sort(key=lambda v: v[1], reverse=True) + return "Top streaks of all time: %s (%d), %s (%d), %s (%d)." % (streaks[0][0], streaks[0][1], streaks[1][0], streaks[1][1], streaks[2][0], streaks[2][1]) + +@lib.hook(glevel=lib.MANAGER, needchan=False) +@lib.help(" []", "set a user's max streak") +@lib.argsGE(2) +def setstreak(bot, user, chan, realtarget, *args): + temp = 0 + target = args[0].lower() + try: + newstreak = int(args[1]) + except ValueError: + return "Error: must be integer" + timestamp = time.time() + if len(args) > 2: + try: + timestamp = int(args[2]) + except ValueError: + return "Error: must be integer (unix timestamp)" + + if target in state.db['streaks']: + temp = state.db['streaks'][target] + if newstreak == 0: + del state.db['streaks'][target] + if newstreak > 0: + state.db['streaks'][target] = [newstreak, timestamp] + return "Done. Streak used to be %d set %d" % (temp[0], temp[1]) + @lib.hook(needchan=False) def triviahelp(bot, user, chan, realtarget, *args): bot.slowmsg(user, "START") bot.slowmsg(user, "TOP10") bot.slowmsg(user, "POINTS []") bot.slowmsg(user, "RANK []") + bot.slowmsg(user, "STREAK []") + bot.slowmsg(user, "TOPSTREAKS") bot.slowmsg(user, "BADQ (include info to identify question)") if user.glevel >= 1: bot.slowmsg(user, "SKIP (KNOWN)") @@ -888,6 +964,7 @@ def triviahelp(bot, user, chan, realtarget, *args): bot.slowmsg(user, "HINTTIMER (ADMIN)") bot.slowmsg(user, "HINTNUM (ADMIN)") bot.slowmsg(user, "QUESTIONPAUSE (ADMIN)") + bot.slowmsg(user, "SETSTREAK (ADMIN)") @lib.hooknum(332) # topic is... @lib.hooknum(331) # no topic set @@ -981,3 +1058,14 @@ def spellout(num): # "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", # "sixteen", "seventeen", "eighteen", "nineteen", "twenty" # ][num] + + +def topa(): + answers=__import__('collections').defaultdict(int) + for a in (x[1] for x in state.db['questions']['general']): + answers[a]+=1; + a2=[] + for a, num in answers.items(): + a2.append((a, num)) + a2.sort(key=lambda v: v[1], reverse=True) + return a2