Mercurial > hg > rlgallery-misc
changeset 35:6592cdd1fceb
Add a high score CGI script.
/scoring/high.cgi shows a score list, with a configurable length,
offset, and game list.
author | John "Elwin" Edwards |
---|---|
date | Fri, 03 Jan 2014 11:11:07 -0500 |
parents | 86b616d88020 |
children | 09ef92dc4439 |
files | py/rlgall.py web/scoring/high.cgi |
diffstat | 2 files changed, 124 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/py/rlgall.py Thu Jan 02 13:58:05 2014 -0500 +++ b/py/rlgall.py Fri Jan 03 11:11:07 2014 -0500 @@ -115,16 +115,14 @@ clist.append("{0}".format(field)) of.write(maketablerow(clist, True)) rnum = 0 - for i, entry in enumerate(entries): + for entry in entries: clist = [] for field in fields: - if field == "rank": - clist.append(("{0}".format(i + 1), rcell)) - elif field in entry: + if field in entry: thing = entry[field] if field == "game": clist.append((thing.name, cell)) - elif field == "xl" or field == "score": # Numerics + elif field == "xl" or field == "score" or field == "rank": # Numerics clist.append((str(thing), rcell)) elif field == "name": clist.append((playerlink(thing), cell)) @@ -260,6 +258,43 @@ else: printTable(newest, self.fields, of) return + def getHigh(self, n=10, offset=0): + "Gets the n highest scores (starting at offset) from the database, \ + returning a list of dicts." + qfields = [] + for f in self.rankfields: + if f == "rank": + qfields.append("rank(*) OVER (ORDER BY score DESC)") + else: + qfields.append(f) + qstr = "SELECT " + ", ".join(qfields) + " FROM {0} ".format(self.uname) + qvals = [] + try: + n = int(n) + except (ValueError, TypeError): + return [] + if n <= 0: + return [] + qstr += " LIMIT %s" + qvals.append(n) + try: + offset = int(offset) + except (ValueError, TypeError): + return [] + if offset > 0: + qstr += " OFFSET %s" + qvals.append(offset) + qstr += ";" + conn = psycopg2.connect("dbname=rlg") + cur = conn.cursor() + cur.execute(qstr, qvals) + cols = [ col.name for col in cur.description ] + data = [ dict(zip(cols, row)) for row in cur.fetchall() ] + cur.close() + conn.close() + for d in data: + d["game"] = self + return data # End Game class definition class RogueGame(Game): @@ -311,43 +346,6 @@ cur.close() conn.close() return dictlist - def getHigh(self, n=10, offset=0): - "Gets the n highest scores (starting at offset) from the database, \ - returning a list of dicts." - qstr = "SELECT endt, score, name, xl, fate, startt FROM {0} ORDER BY score DESC ".format(self.uname) - qvals = [] - try: - n = int(n) - except (ValueError, TypeError): - return [] - if n <= 0: - return [] - qstr += " LIMIT %s" - qvals.append(n) - try: - offset = int(offset) - except (ValueError, TypeError): - return [] - if n > 0: - qstr += " OFFSET %s" - qvals.append(offset) - qstr += ";" - conn = psycopg2.connect("dbname=rlg") - cur = conn.cursor() - cur.execute(qstr, qvals) - dictlist = [] - for record in cur: - ndict = {"game": self} - ndict["endt"] = record[0] - ndict["score"] = record[1] - ndict["name"] = record[2] - ndict["xl"] = record[3] - ndict["fate"] = record[4] - ndict["startt"] = record[5] - dictlist.append(ndict) - cur.close() - conn.close() - return dictlist def getPlayer(self, player): "Gets all player's games from the database." qstr = "SELECT endt, score, name, xl, fate, startt FROM " + self.uname + " WHERE name = %s;" @@ -406,43 +404,6 @@ fields = ["name", "score", "class", "xl", "fate", "endt"] rankfields = ["rank", "score", "name", "class", "xl", "fate", "endt"] pfields = ["score", "class", "xl", "fate", "endt"] - def getHigh(self, n=10, offset=0): - "Gets the n highest scores (starting at offset) from the database, \ - returning a list of dicts." - qstr = "SELECT endt, score, name, xl, class, fate FROM {0} ORDER BY score DESC ".format(self.uname) - qvals = [] - try: - n = int(n) - except (ValueError, TypeError): - return [] - if n <= 0: - return [] - qstr += " LIMIT %s" - qvals.append(n) - try: - offset = int(offset) - except (ValueError, TypeError): - return [] - if n > 0: - qstr += " OFFSET %s" - qvals.append(offset) - qstr += ";" - conn = psycopg2.connect("dbname=rlg") - cur = conn.cursor() - cur.execute(qstr, qvals) - dictlist = [] - for record in cur: - ndict = {"game": self} - ndict["endt"] = record[0] - ndict["score"] = record[1] - ndict["name"] = record[2] - ndict["xl"] = record[3] - ndict["class"] = record[4] - ndict["fate"] = record[5] - dictlist.append(ndict) - cur.close() - conn.close() - return dictlist def getRecent(self, n=20): return [] def getPlayer(self, player):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/scoring/high.cgi Fri Jan 03 11:11:07 2014 -0500 @@ -0,0 +1,84 @@ +#!/usr/bin/python3 + +import sys +import cgi +import rlgall + +checkstr = '{0}:<input type="checkbox" name="g" value="{1}" checked="checked"> ' +uncheckstr = '{0}:<input type="checkbox" name="g" value="{1}"> ' + +cgidata = cgi.FieldStorage() + +formgames = cgidata.getlist("g") +if "all" in formgames: + games = rlgall.gamelist +else: + games = [] + for g in rlgall.gamelist: + if g.uname in formgames: + games.append(g) + if not games: + games = rlgall.gamelist + +formstart = cgidata.getfirst("s") +if not formstart: + start = 0 +else: + try: + start = int(formstart) + except ValueError: + start = 0 +if start < 0: + start = 0 + +deflimit = (12 // len(games)) * 5 +formlimit = cgidata.getfirst("l") +if not formlimit: + limit = deflimit +else: + try: + limit = int(formlimit) + except ValueError: + limit = deflimit +if limit <= 0: + limit = deflimit + + +sys.stdout.write("Content-Type: text/html; charset=utf-8\r\n\r\n") +sys.stdout.write(rlgall.phead.format("High Scores")) +sys.stdout.write(rlgall.ptop) +sys.stdout.write(rlgall.navscore.format("High Scores")) +if len(games) == 1: + if start == 0: + intitle = "Top {0} scores for {1}".format(limit, games[0].name) + else: + intitle = "Scores {0} - {1} for {2}".format(start + 1, start + limit, + games[0].name) + sys.stdout.write(rlgall.pti.format(intitle)) + highlist = games[0].getHigh(limit, start) + rlgall.printTable(highlist, games[0].rankfields, sys.stdout) +else: + if start == 0: + intitle = "Top {0} scores".format(limit) + else: + intitle = "Scores {0} - {1}".format(start + 1, start + limit) + sys.stdout.write(rlgall.pti.format(intitle)) + for g in games: + sys.stdout.write(rlgall.secthead.format(g.name)) + highlist = g.getHigh(limit, start) + rlgall.printTable(highlist, g.rankfields, sys.stdout) +sys.stdout.write('<form action="/scoring/high.cgi" method="get">\n') +sys.stdout.write('<div>Number of scores: ') +sys.stdout.write('<input type="text" name="l" value="{0}">'.format(limit)) +sys.stdout.write(' Skip the first: ') +sys.stdout.write('<input type="text" name="s" value="{0}">'.format(start)) +sys.stdout.write('</div><div>') +for game in rlgall.gamelist: + if game in games: + sys.stdout.write(checkstr.format(game.name, game.uname)) + else: + sys.stdout.write(uncheckstr.format(game.name, game.uname)) +sys.stdout.write('</div><div><input type="submit" value="Get Scores">') +sys.stdout.write('</div></form>') +sys.stdout.write(rlgall.pend) +exit()