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.
This commit is contained in:
parent
914f367657
commit
aef04a38e1
10 changed files with 58 additions and 71 deletions
|
|
@ -13,7 +13,7 @@ server.modules += ( "mod_cgi" )
|
||||||
## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini.
|
## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini.
|
||||||
##
|
##
|
||||||
cgi.assign = ( ".pl" => "/usr/bin/perl",
|
cgi.assign = ( ".pl" => "/usr/bin/perl",
|
||||||
".cgi" => "/usr/bin/python",
|
".cgi" => "",
|
||||||
".rb" => "/usr/bin/ruby",
|
".rb" => "/usr/bin/ruby",
|
||||||
".erb" => "/usr/bin/eruby",
|
".erb" => "/usr/bin/eruby",
|
||||||
".py" => "/usr/bin/python" )
|
".py" => "/usr/bin/python" )
|
||||||
|
|
|
||||||
|
|
@ -451,3 +451,7 @@ server.upload-dirs = ( "/var/tmp" )
|
||||||
#include_shell "cat /etc/lighttpd/vhosts.d/*.conf"
|
#include_shell "cat /etc/lighttpd/vhosts.d/*.conf"
|
||||||
##
|
##
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
setenv.add-environment = (
|
||||||
|
"LC_CTYPE" => "en_US.utf8"
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ server.modules = (
|
||||||
# "mod_evasive",
|
# "mod_evasive",
|
||||||
# "mod_redirect",
|
# "mod_redirect",
|
||||||
# "mod_rewrite",
|
# "mod_rewrite",
|
||||||
# "mod_setenv",
|
"mod_setenv",
|
||||||
# "mod_usertrack",
|
# "mod_usertrack",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
2
py/cleandb.py
Normal file → Executable file
2
py/cleandb.py
Normal file → Executable file
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
# cleandb.py: empty the database in an orderly fashion
|
# cleandb.py: empty the database in an orderly fashion
|
||||||
|
|
||||||
import rlgalldb as rlgall
|
import rlgalldb as rlgall
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
# rlgalldb.py
|
# rlgalldb.py
|
||||||
# Module for the Roguelike Gallery, using a postgres database
|
# Module for the Roguelike Gallery, using a postgres database
|
||||||
|
# Requires Python 3.3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import calendar
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from datetime import datetime, tzinfo, timedelta
|
from datetime import datetime
|
||||||
|
import pytz
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
logdir = "/var/dgl/var/games/roguelike/"
|
logdir = "/var/dgl/var/games/roguelike/"
|
||||||
|
|
@ -49,17 +50,6 @@ headerbook = {"endt":"End time", "score":"Score", "name":"Name", "xl":"XL",
|
||||||
offselstr = "SELECT offbytes FROM games WHERE gname = %s;"
|
offselstr = "SELECT offbytes FROM games WHERE gname = %s;"
|
||||||
newoffstr = "UPDATE games SET offbytes = %s 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():
|
def getconn():
|
||||||
"Returns a database connection, or None if the connection fails."
|
"Returns a database connection, or None if the connection fails."
|
||||||
try:
|
try:
|
||||||
|
|
@ -71,7 +61,7 @@ def getconn():
|
||||||
def recnameToTS(filename):
|
def recnameToTS(filename):
|
||||||
pattern = "%Y-%m-%d.%H:%M:%S.ttyrec"
|
pattern = "%Y-%m-%d.%H:%M:%S.ttyrec"
|
||||||
try:
|
try:
|
||||||
dt = datetime.strptime(filename, pattern).replace(tzinfo=utc)
|
dt = datetime.strptime(filename, pattern).replace(tzinfo=pytz.utc)
|
||||||
return dt
|
return dt
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
@ -90,7 +80,7 @@ def linktoArchive(entry):
|
||||||
"Takes an entry dict and returns a link to the ttyrec archivist."
|
"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>'
|
lstr = '<a href="/archive.cgi?name={0};game={1};time={2}">{3}</a>'
|
||||||
linktext = entry["endt"].strftime("%Y/%m/%d %H:%M:%S")
|
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)
|
return lstr.format(entry["name"], entry["game"].uname, stamp, linktext)
|
||||||
|
|
||||||
def maketablerow(cells, isheader=None):
|
def maketablerow(cells, isheader=None):
|
||||||
|
|
@ -156,7 +146,7 @@ class Game:
|
||||||
if self.sqltypes[item] == "bool":
|
if self.sqltypes[item] == "bool":
|
||||||
ndict[item] = bool(int(value))
|
ndict[item] = bool(int(value))
|
||||||
elif self.sqltypes[item] == "timestamptz":
|
elif self.sqltypes[item] == "timestamptz":
|
||||||
ndict[item] = datetime.fromtimestamp(int(value), utc)
|
ndict[item] = datetime.fromtimestamp(int(value), pytz.utc)
|
||||||
else:
|
else:
|
||||||
ndict[item] = value
|
ndict[item] = value
|
||||||
return ndict
|
return ndict
|
||||||
|
|
@ -181,7 +171,7 @@ class Game:
|
||||||
offset = cur.fetchone()[0]
|
offset = cur.fetchone()[0]
|
||||||
newlist = []
|
newlist = []
|
||||||
try:
|
try:
|
||||||
scr = open(self.scores)
|
scr = open(self.scores, encoding="utf-8")
|
||||||
scr.seek(offset)
|
scr.seek(offset)
|
||||||
self.getEntryDicts(scr, newlist)
|
self.getEntryDicts(scr, newlist)
|
||||||
except IOError:
|
except IOError:
|
||||||
|
|
@ -215,7 +205,7 @@ class Game:
|
||||||
if result:
|
if result:
|
||||||
prev = result[0]
|
prev = result[0]
|
||||||
else:
|
else:
|
||||||
prev = datetime.fromtimestamp(0, utc);
|
prev = datetime.fromtimestamp(0, pytz.utc);
|
||||||
ttyrecdir = "/var/dgl/dgldir/ttyrec/{0}/{1}/".format(nameF, self.uname)
|
ttyrecdir = "/var/dgl/dgldir/ttyrec/{0}/{1}/".format(nameF, self.uname)
|
||||||
allfilekeys = [ (recnameToTS(f), f) for f in os.listdir(ttyrecdir) ]
|
allfilekeys = [ (recnameToTS(f), f) for f in os.listdir(ttyrecdir) ]
|
||||||
vfilekeys = [ e for e in allfilekeys if e[0] > prev ]
|
vfilekeys = [ e for e in allfilekeys if e[0] > prev ]
|
||||||
|
|
@ -242,16 +232,17 @@ class Game:
|
||||||
"Prints the most recent games from the logfile, NOT the database."
|
"Prints the most recent games from the logfile, NOT the database."
|
||||||
newest = []
|
newest = []
|
||||||
try:
|
try:
|
||||||
scr = open(self.scores)
|
scr = open(self.scores, encoding="utf-8")
|
||||||
except IOError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
# Text streams don't support random seeking.
|
||||||
try:
|
try:
|
||||||
scr.seek(self.lookback, 2)
|
scr.buffer.seek(self.lookback, 2)
|
||||||
except IOError:
|
except OSError:
|
||||||
scr.seek(0) # The file wasn't that long, start at the beginning
|
scr.buffer.seek(0) # The file wasn't that long, start at the beginning
|
||||||
if scr.tell() != 0:
|
if scr.buffer.tell() != 0:
|
||||||
scr.readline() # Throw away the incomplete line
|
scr.buffer.readline() # Throw away the incomplete line
|
||||||
self.getEntryDicts(scr, newest)
|
self.getEntryDicts(scr, newest)
|
||||||
newest.reverse()
|
newest.reverse()
|
||||||
scr.close()
|
scr.close()
|
||||||
|
|
@ -274,18 +265,11 @@ class RogueGame(Game):
|
||||||
"ttyrecs": "text ARRAY", "startt": "timestamptz"}
|
"ttyrecs": "text ARRAY", "startt": "timestamptz"}
|
||||||
self.logdelim = " "
|
self.logdelim = " "
|
||||||
self.lookback = -1500
|
self.lookback = -1500
|
||||||
colspec = "("
|
# Construct the insert query
|
||||||
valspec = "("
|
fields = self.sqltypes.keys()
|
||||||
for i, col in enumerate(self.sqltypes.keys()):
|
colspec = ", ".join(fields)
|
||||||
colspec += col
|
valspec = ", ".join([ "%({})s".format(c) for c in fields ])
|
||||||
valspec += "%({0})s".format(col)
|
self.insertq = "INSERT INTO {0} ({1}) VALUES ({2});".format(self.uname,
|
||||||
if i == len(self.sqltypes) - 1:
|
|
||||||
colspec += ")"
|
|
||||||
valspec += ")"
|
|
||||||
else:
|
|
||||||
colspec += ", "
|
|
||||||
valspec += ", "
|
|
||||||
self.insertq = "INSERT INTO {0} {1} VALUES {2};".format(self.uname,
|
|
||||||
colspec, valspec)
|
colspec, valspec)
|
||||||
# Class variables, used by some methods
|
# Class variables, used by some methods
|
||||||
fields = ["name", "score", "xl", "fate", "endt"]
|
fields = ["name", "score", "xl", "fate", "endt"]
|
||||||
|
|
@ -380,11 +364,12 @@ class RogueGame(Game):
|
||||||
def putIntoDB(self, dictlist, conn):
|
def putIntoDB(self, dictlist, conn):
|
||||||
"Add the entries in dictlist to the database through connection conn, \
|
"Add the entries in dictlist to the database through connection conn, \
|
||||||
which needs the INSERT privilege."
|
which needs the INSERT privilege."
|
||||||
# FIXME this monster needs to be procedurally generated
|
fields = self.sqltypes.keys()
|
||||||
qstr = "INSERT INTO " + self.uname + " (endt, score, name, xl, fate, ttyrecs, startt) \
|
fstr = ", ".join(fields)
|
||||||
VALUES (%(endt)s, %(score)s, %(name)s, %(xl)s, %(fate)s, %(ttyrecs)s, %(startt)s);"
|
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 = 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()
|
conn.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
return
|
return
|
||||||
|
|
@ -403,18 +388,11 @@ class ARogueGame(Game):
|
||||||
"fate": "text", "ttyrecs": "text ARRAY", "startt": "timestamptz"}
|
"fate": "text", "ttyrecs": "text ARRAY", "startt": "timestamptz"}
|
||||||
self.logdelim = " "
|
self.logdelim = " "
|
||||||
self.lookback = -1800
|
self.lookback = -1800
|
||||||
colspec = "("
|
# Construct the insert query
|
||||||
valspec = "("
|
fields = self.sqltypes.keys()
|
||||||
for i, col in enumerate(self.sqltypes.keys()):
|
colspec = ", ".join(fields)
|
||||||
colspec += col
|
valspec = ", ".join([ "%({})s".format(c) for c in fields ])
|
||||||
valspec += "%({0})s".format(col)
|
self.insertq = "INSERT INTO {0} ({1}) VALUES ({2});".format(self.uname,
|
||||||
if i == len(self.sqltypes) - 1:
|
|
||||||
colspec += ")"
|
|
||||||
valspec += ")"
|
|
||||||
else:
|
|
||||||
colspec += ", "
|
|
||||||
valspec += ", "
|
|
||||||
self.insertq = "INSERT INTO {0} {1} VALUES {2};".format(self.uname,
|
|
||||||
colspec, valspec)
|
colspec, valspec)
|
||||||
# Class variables
|
# Class variables
|
||||||
fields = ["name", "score", "class", "xl", "fate", "endt"]
|
fields = ["name", "score", "class", "xl", "fate", "endt"]
|
||||||
|
|
@ -492,7 +470,7 @@ gamelist = [rogue3, rogue4, rogue5, srogue, arogue5]
|
||||||
def playerpage(pname):
|
def playerpage(pname):
|
||||||
"Generate a player's HTML page"
|
"Generate a player's HTML page"
|
||||||
# Write the beginning of the 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(phead.format(pname))
|
||||||
ppagefi.write(ptop)
|
ppagefi.write(ptop)
|
||||||
ppagefi.write(navplayer.format(pname))
|
ppagefi.write(navplayer.format(pname))
|
||||||
|
|
@ -509,7 +487,7 @@ def playerpage(pname):
|
||||||
scoresum = 0
|
scoresum = 0
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
scoresum += int(entry["score"])
|
scoresum += int(entry["score"])
|
||||||
avgscr = scoresum / len(entries)
|
avgscr = scoresum // len(entries)
|
||||||
ppagefi.write("<p>Average score: {0}</p>\n".format(avgscr))
|
ppagefi.write("<p>Average score: {0}</p>\n".format(avgscr))
|
||||||
# That should settle it. Print the end; then stop.
|
# That should settle it. Print the end; then stop.
|
||||||
ppagefi.write(pend)
|
ppagefi.write(pend)
|
||||||
|
|
@ -518,7 +496,7 @@ def playerpage(pname):
|
||||||
|
|
||||||
def highpage():
|
def highpage():
|
||||||
# open the page and print the beginning
|
# 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(phead.format("High Scores"))
|
||||||
highpfi.write(ptop)
|
highpfi.write(ptop)
|
||||||
highpfi.write(navscore.format("High Scores"))
|
highpfi.write(navscore.format("High Scores"))
|
||||||
|
|
|
||||||
2
py/setupdb.py
Normal file → Executable file
2
py/setupdb.py
Normal file → Executable file
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
# setupdb.py: initializes the database tables used by the rlg system.
|
# setupdb.py: initializes the database tables used by the rlg system.
|
||||||
|
|
||||||
import rlgalldb as rlgall
|
import rlgalldb as rlgall
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import cgi
|
import cgi
|
||||||
import os
|
import os
|
||||||
|
|
@ -6,6 +6,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import calendar
|
import calendar
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import pytz
|
||||||
import rlgalldb as rlgall
|
import rlgalldb as rlgall
|
||||||
#import cgitb
|
#import cgitb
|
||||||
|
|
||||||
|
|
@ -55,7 +56,7 @@ def input_datetime(outf, dvals=[None, None, None, None, None, None]):
|
||||||
emptf = '<input type="text" size="2" maxlength="2" name="{0}">'
|
emptf = '<input type="text" size="2" maxlength="2" name="{0}">'
|
||||||
sstr = '<div>Date: <select name="year">\n'
|
sstr = '<div>Date: <select name="year">\n'
|
||||||
# Default to today
|
# Default to today
|
||||||
now = datetime.now(rlgall.utc)
|
now = datetime.now(pytz.utc)
|
||||||
if dvals[0] == None:
|
if dvals[0] == None:
|
||||||
dvals[0] = now.year
|
dvals[0] = now.year
|
||||||
if dvals[1] == None:
|
if dvals[1] == None:
|
||||||
|
|
@ -164,7 +165,7 @@ def processtime(fdata, errlist, hlist):
|
||||||
chtime = time.gmtime(utime)
|
chtime = time.gmtime(utime)
|
||||||
for i in range(6):
|
for i in range(6):
|
||||||
hlist[i] = chtime[i]
|
hlist[i] = chtime[i]
|
||||||
return datetime.fromtimestamp(utime, rlgall.utc)
|
return datetime.fromtimestamp(utime, pytz.utc)
|
||||||
|
|
||||||
# Now try to get a human-readable specification.
|
# Now try to get a human-readable specification.
|
||||||
lerrors = []
|
lerrors = []
|
||||||
|
|
@ -261,7 +262,7 @@ def processtime(fdata, errlist, hlist):
|
||||||
errlist.extend(lerrors)
|
errlist.extend(lerrors)
|
||||||
return None
|
return None
|
||||||
#return calendar.timegm([year, month, day, hour, minute, second, 0, 0, 0])
|
#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
|
# Begin processing
|
||||||
fdata = cgi.FieldStorage()
|
fdata = cgi.FieldStorage()
|
||||||
|
|
@ -307,7 +308,7 @@ if dosearch:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
# Now we are ready to print the page.
|
# 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.phead.format("Archive"))
|
||||||
sys.stdout.write(rlgall.ptop)
|
sys.stdout.write(rlgall.ptop)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
# CGI script creating page of recent games
|
# CGI script creating page of recent games
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import rlgalldb as rlgall
|
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
|
# 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
|
# The top of the page
|
||||||
sys.stdout.write(rlgall.phead.format("Recent Games"))
|
sys.stdout.write(rlgall.phead.format("Recent Games"))
|
||||||
sys.stdout.write(rlgall.ptop);
|
sys.stdout.write(rlgall.ptop);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import rlgall
|
import rlgalldb as rlgall
|
||||||
|
|
||||||
playerdir = "/var/www/lighttpd/scoring/players/"
|
playerdir = "/var/www/lighttpd/scoring/players/"
|
||||||
linkstr = '<li><a href="./{0}.html">{0}</a></li>\n'
|
linkstr = '<li><a href="./{0}.html">{0}</a></li>\n'
|
||||||
|
|
@ -15,7 +15,7 @@ for filename in filelist:
|
||||||
namelist.append(filename.rsplit(".html", 1)[0])
|
namelist.append(filename.rsplit(".html", 1)[0])
|
||||||
namelist.sort()
|
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.phead.format("Players"))
|
||||||
sys.stdout.write(rlgall.ptop)
|
sys.stdout.write(rlgall.ptop)
|
||||||
sys.stdout.write(rlgall.navscore.format("Players"))
|
sys.stdout.write(rlgall.navscore.format("Players"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue