# HG changeset patch # User John "Elwin" Edwards # Date 1388514979 18000 # Node ID e8f3b7994d88d2b07c42d7ca40c0b4867ab8c7fd # Parent 23a769aa487e14c3863897c9d63fe575a1215ca3 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. diff -r 23a769aa487e -r e8f3b7994d88 lighttpd/conf.d/cgi.conf --- 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" ) diff -r 23a769aa487e -r e8f3b7994d88 lighttpd/lighttpd.conf --- 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" +) diff -r 23a769aa487e -r e8f3b7994d88 lighttpd/modules.conf --- 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", ) diff -r 23a769aa487e -r e8f3b7994d88 py/cleandb.py --- 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 diff -r 23a769aa487e -r e8f3b7994d88 py/recorder.py --- 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 diff -r 23a769aa487e -r e8f3b7994d88 py/rlgalldb.py --- 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 = '{3}' 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("

Average score: {0}

\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")) diff -r 23a769aa487e -r e8f3b7994d88 py/setupdb.py --- 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 diff -r 23a769aa487e -r e8f3b7994d88 web/archive.cgi --- 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 = '' sstr = '
Date: