Mercurial > hg > rlgallery-misc
changeset 30:e8f3b7994d88
Port to Python 3.
All scripts and modules have been ported to Python 3 and appear to
work. Some changes to the lighttpd configuration were needed.
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Dec 2013 13:36:19 -0500 |
parents | 23a769aa487e |
children | 7303535b5a5d |
files | lighttpd/conf.d/cgi.conf lighttpd/lighttpd.conf lighttpd/modules.conf py/cleandb.py py/recorder.py py/rlgalldb.py py/setupdb.py web/archive.cgi web/recent.cgi web/scoring/players/index.cgi |
diffstat | 10 files changed, 58 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/lighttpd/conf.d/cgi.conf Thu Oct 31 14:33:50 2013 -0700 +++ b/lighttpd/conf.d/cgi.conf Tue Dec 31 13:36:19 2013 -0500 @@ -13,7 +13,7 @@ ## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini. ## cgi.assign = ( ".pl" => "/usr/bin/perl", - ".cgi" => "/usr/bin/python", + ".cgi" => "", ".rb" => "/usr/bin/ruby", ".erb" => "/usr/bin/eruby", ".py" => "/usr/bin/python" )
--- a/lighttpd/lighttpd.conf Thu Oct 31 14:33:50 2013 -0700 +++ b/lighttpd/lighttpd.conf Tue Dec 31 13:36:19 2013 -0500 @@ -451,3 +451,7 @@ #include_shell "cat /etc/lighttpd/vhosts.d/*.conf" ## ####################################################################### + +setenv.add-environment = ( + "LC_CTYPE" => "en_US.utf8" +)
--- a/lighttpd/modules.conf Thu Oct 31 14:33:50 2013 -0700 +++ b/lighttpd/modules.conf Tue Dec 31 13:36:19 2013 -0500 @@ -48,7 +48,7 @@ # "mod_evasive", # "mod_redirect", # "mod_rewrite", -# "mod_setenv", + "mod_setenv", # "mod_usertrack", )
--- a/py/cleandb.py Thu Oct 31 14:33:50 2013 -0700 +++ b/py/cleandb.py Tue Dec 31 13:36:19 2013 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # cleandb.py: empty the database in an orderly fashion import rlgalldb as rlgall
--- a/py/recorder.py Thu Oct 31 14:33:50 2013 -0700 +++ b/py/recorder.py Tue Dec 31 13:36:19 2013 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import psycopg2
--- a/py/rlgalldb.py Thu Oct 31 14:33:50 2013 -0700 +++ b/py/rlgalldb.py Tue Dec 31 13:36:19 2013 -0500 @@ -1,10 +1,11 @@ # rlgalldb.py # Module for the Roguelike Gallery, using a postgres database +# Requires Python 3.3 import os -import calendar import psycopg2 -from datetime import datetime, tzinfo, timedelta +from datetime import datetime +import pytz # Configuration logdir = "/var/dgl/var/games/roguelike/" @@ -49,17 +50,6 @@ offselstr = "SELECT offbytes FROM games WHERE gname = %s;" newoffstr = "UPDATE games SET offbytes = %s WHERE gname = %s;" -# A representation of the UTC time zone. They say Py3k can better handle -# this madness. -class UTC(tzinfo): - def utcoffset(self, dt): - return timedelta(0) - def dst(self, dt): - return timedelta(0) - def tzname(self, dt): - return "UTC" -utc = UTC() - def getconn(): "Returns a database connection, or None if the connection fails." try: @@ -71,7 +61,7 @@ def recnameToTS(filename): pattern = "%Y-%m-%d.%H:%M:%S.ttyrec" try: - dt = datetime.strptime(filename, pattern).replace(tzinfo=utc) + dt = datetime.strptime(filename, pattern).replace(tzinfo=pytz.utc) return dt except ValueError: return None @@ -90,7 +80,7 @@ "Takes an entry dict and returns a link to the ttyrec archivist." lstr = '<a href="/archive.cgi?name={0};game={1};time={2}">{3}</a>' linktext = entry["endt"].strftime("%Y/%m/%d %H:%M:%S") - stamp = calendar.timegm(entry["endt"].utctimetuple()) + stamp = int(entry["endt"].timestamp()) return lstr.format(entry["name"], entry["game"].uname, stamp, linktext) def maketablerow(cells, isheader=None): @@ -156,7 +146,7 @@ if self.sqltypes[item] == "bool": ndict[item] = bool(int(value)) elif self.sqltypes[item] == "timestamptz": - ndict[item] = datetime.fromtimestamp(int(value), utc) + ndict[item] = datetime.fromtimestamp(int(value), pytz.utc) else: ndict[item] = value return ndict @@ -181,7 +171,7 @@ offset = cur.fetchone()[0] newlist = [] try: - scr = open(self.scores) + scr = open(self.scores, encoding="utf-8") scr.seek(offset) self.getEntryDicts(scr, newlist) except IOError: @@ -215,7 +205,7 @@ if result: prev = result[0] else: - prev = datetime.fromtimestamp(0, utc); + prev = datetime.fromtimestamp(0, pytz.utc); ttyrecdir = "/var/dgl/dgldir/ttyrec/{0}/{1}/".format(nameF, self.uname) allfilekeys = [ (recnameToTS(f), f) for f in os.listdir(ttyrecdir) ] vfilekeys = [ e for e in allfilekeys if e[0] > prev ] @@ -242,16 +232,17 @@ "Prints the most recent games from the logfile, NOT the database." newest = [] try: - scr = open(self.scores) - except IOError: + scr = open(self.scores, encoding="utf-8") + except FileNotFoundError: pass else: + # Text streams don't support random seeking. try: - scr.seek(self.lookback, 2) - except IOError: - scr.seek(0) # The file wasn't that long, start at the beginning - if scr.tell() != 0: - scr.readline() # Throw away the incomplete line + scr.buffer.seek(self.lookback, 2) + except OSError: + scr.buffer.seek(0) # The file wasn't that long, start at the beginning + if scr.buffer.tell() != 0: + scr.buffer.readline() # Throw away the incomplete line self.getEntryDicts(scr, newest) newest.reverse() scr.close() @@ -274,18 +265,11 @@ "ttyrecs": "text ARRAY", "startt": "timestamptz"} self.logdelim = " " self.lookback = -1500 - colspec = "(" - valspec = "(" - for i, col in enumerate(self.sqltypes.keys()): - colspec += col - valspec += "%({0})s".format(col) - if i == len(self.sqltypes) - 1: - colspec += ")" - valspec += ")" - else: - colspec += ", " - valspec += ", " - self.insertq = "INSERT INTO {0} {1} VALUES {2};".format(self.uname, + # Construct the insert query + fields = self.sqltypes.keys() + colspec = ", ".join(fields) + valspec = ", ".join([ "%({})s".format(c) for c in fields ]) + self.insertq = "INSERT INTO {0} ({1}) VALUES ({2});".format(self.uname, colspec, valspec) # Class variables, used by some methods fields = ["name", "score", "xl", "fate", "endt"] @@ -380,11 +364,12 @@ def putIntoDB(self, dictlist, conn): "Add the entries in dictlist to the database through connection conn, \ which needs the INSERT privilege." - # FIXME this monster needs to be procedurally generated - qstr = "INSERT INTO " + self.uname + " (endt, score, name, xl, fate, ttyrecs, startt) \ - VALUES (%(endt)s, %(score)s, %(name)s, %(xl)s, %(fate)s, %(ttyrecs)s, %(startt)s);" + fields = self.sqltypes.keys() + fstr = ", ".join(fields) + vstr = ", ".join([ "%({})s".format(c) for c in fields ]) + qstr = "INSERT INTO {0} ({1}) VALUES ({2});".format(self.uname, fstr, vstr); cur = conn.cursor() - cur.executemany(qstr, [ d for d in dictlist if d["game"] == self ]) + cur.executemany(self.insertq, [ d for d in dictlist if d["game"] == self ]) conn.commit() cur.close() return @@ -403,18 +388,11 @@ "fate": "text", "ttyrecs": "text ARRAY", "startt": "timestamptz"} self.logdelim = " " self.lookback = -1800 - colspec = "(" - valspec = "(" - for i, col in enumerate(self.sqltypes.keys()): - colspec += col - valspec += "%({0})s".format(col) - if i == len(self.sqltypes) - 1: - colspec += ")" - valspec += ")" - else: - colspec += ", " - valspec += ", " - self.insertq = "INSERT INTO {0} {1} VALUES {2};".format(self.uname, + # Construct the insert query + fields = self.sqltypes.keys() + colspec = ", ".join(fields) + valspec = ", ".join([ "%({})s".format(c) for c in fields ]) + self.insertq = "INSERT INTO {0} ({1}) VALUES ({2});".format(self.uname, colspec, valspec) # Class variables fields = ["name", "score", "class", "xl", "fate", "endt"] @@ -492,7 +470,7 @@ def playerpage(pname): "Generate a player's HTML page" # Write the beginning of the page - ppagefi = open(ppagename.format(pname), "w") + ppagefi = open(ppagename.format(pname), "w", encoding="utf-8") ppagefi.write(phead.format(pname)) ppagefi.write(ptop) ppagefi.write(navplayer.format(pname)) @@ -509,7 +487,7 @@ scoresum = 0 for entry in entries: scoresum += int(entry["score"]) - avgscr = scoresum / len(entries) + avgscr = scoresum // len(entries) ppagefi.write("<p>Average score: {0}</p>\n".format(avgscr)) # That should settle it. Print the end; then stop. ppagefi.write(pend) @@ -518,7 +496,7 @@ def highpage(): # open the page and print the beginning - highpfi = open(hpagename, "w") + highpfi = open(hpagename, "w", encoding="utf-8") highpfi.write(phead.format("High Scores")) highpfi.write(ptop) highpfi.write(navscore.format("High Scores"))
--- a/py/setupdb.py Thu Oct 31 14:33:50 2013 -0700 +++ b/py/setupdb.py Tue Dec 31 13:36:19 2013 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # setupdb.py: initializes the database tables used by the rlg system. import rlgalldb as rlgall
--- a/web/archive.cgi Thu Oct 31 14:33:50 2013 -0700 +++ b/web/archive.cgi Tue Dec 31 13:36:19 2013 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import cgi import os @@ -6,6 +6,7 @@ import time import calendar from datetime import datetime +import pytz import rlgalldb as rlgall #import cgitb @@ -55,7 +56,7 @@ emptf = '<input type="text" size="2" maxlength="2" name="{0}">' sstr = '<div>Date: <select name="year">\n' # Default to today - now = datetime.now(rlgall.utc) + now = datetime.now(pytz.utc) if dvals[0] == None: dvals[0] = now.year if dvals[1] == None: @@ -164,7 +165,7 @@ chtime = time.gmtime(utime) for i in range(6): hlist[i] = chtime[i] - return datetime.fromtimestamp(utime, rlgall.utc) + return datetime.fromtimestamp(utime, pytz.utc) # Now try to get a human-readable specification. lerrors = [] @@ -261,7 +262,7 @@ errlist.extend(lerrors) return None #return calendar.timegm([year, month, day, hour, minute, second, 0, 0, 0]) - return datetime(year, month, day, hour, minute, second, 0, rlgall.utc) + return datetime(year, month, day, hour, minute, second, 0, pytz.utc) # Begin processing fdata = cgi.FieldStorage() @@ -307,7 +308,7 @@ conn.close() # Now we are ready to print the page. -sys.stdout.write("Content-type: text/html\r\n\r\n") +sys.stdout.write("Content-Type: text/html; charset=utf-8\r\n\r\n") sys.stdout.write(rlgall.phead.format("Archive")) sys.stdout.write(rlgall.ptop)
--- a/web/recent.cgi Thu Oct 31 14:33:50 2013 -0700 +++ b/web/recent.cgi Tue Dec 31 13:36:19 2013 -0500 @@ -1,12 +1,16 @@ -#!/usr/bin/python +#!/usr/bin/python3 # CGI script creating page of recent games import sys import time import rlgalldb as rlgall +# It is assumed that sys.stdout uses UTF-8 encoding. If this is not the case, +# configure the Web server to set the LC_CTYPE environment variable to a UTF-8 +# locale. + # The required header -sys.stdout.write("Content-type: text/html\r\n\r\n") +sys.stdout.write("Content-Type: text/html; charset=utf-8\r\n\r\n") # The top of the page sys.stdout.write(rlgall.phead.format("Recent Games")) sys.stdout.write(rlgall.ptop);
--- a/web/scoring/players/index.cgi Thu Oct 31 14:33:50 2013 -0700 +++ b/web/scoring/players/index.cgi Tue Dec 31 13:36:19 2013 -0500 @@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import sys -import rlgall +import rlgalldb as rlgall playerdir = "/var/www/lighttpd/scoring/players/" linkstr = '<li><a href="./{0}.html">{0}</a></li>\n' @@ -15,7 +15,7 @@ namelist.append(filename.rsplit(".html", 1)[0]) namelist.sort() -sys.stdout.write("Content-type: text/html\r\n\r\n") +sys.stdout.write("Content-Type: text/html; charset=utf-8\r\n\r\n") sys.stdout.write(rlgall.phead.format("Players")) sys.stdout.write(rlgall.ptop) sys.stdout.write(rlgall.navscore.format("Players"))