changed database backend to SqlObject. currently unusable until some bugs are fixed.

This commit is contained in:
phear 2005-11-23 17:34:20 +00:00
parent b94b8fbbe9
commit 6474c7f47c
11 changed files with 308 additions and 123 deletions

View file

@ -1,4 +1,4 @@
import helper,psql import helper,database
maxuser = 1000 maxuser = 1000
@ -42,7 +42,8 @@ def process_form(req,form):
except: except:
username = "" username = ""
if (username != "") and (password1 != "") and (password2 != "") and (password1 == password2): if (username != "") and (password1 != "") and (password2 != "") and (password1 == password2):
psql.add_webgo_user(username,password1) newuser = database.Users(username=username,password=password1)
#.add_webgo_user(username,password1)
req.write("User %s has been successfully created. Click the following button to login:<br>" % username) req.write("User %s has been successfully created. Click the following button to login:<br>" % username)
data = """ data = """
<form method="post"> <form method="post">

184
database.py Normal file
View file

@ -0,0 +1,184 @@
#apt-get install python-sqlobject python-psycopg
from sqlobject import *
import sys, os, time
import gnugo, helper
#account and database name
dbname = "/home/mtsrc/daten/projekte/webgo/webgo.sqlite"
#dbname = "/tmp/webgo.sqlite"
dbdebug = "debug=t&debugOutput=t" #don't want SQL debug messages? just change to an empty string: "debug="
#dbdebug = "debug="
#build connection string and connect
connection_string='sqlite:%s?%s' %(dbname,dbdebug)
connection=connectionForURI(connection_string)
__connection__ = connection
class GobanTable(SQLObject):
"""
Abstract:
A GobanTable instance contains all data of a current goban: players, board etc.
Details: The table looks like this:
player1
player2
turn_number
size
name
description
sgf
created
lastmove
"""
player1 = StringCol()
player2 = StringCol()
size = IntCol()
name = StringCol(default = helper.generate_game_name(), unique=True,notNone=True,alternateID=True)
turn_number = 1
description = StringCol(default=None)
sgf = gnugo.create_sgf_file(size)
created = int(time.time())
lastmove = int(time.time())
def players(self):
"""returns both player names as a tuple"""
return (self.player1,self.player2)
def set_time(self):
"""updates self.lastmove to current time"""
self.lastmove = int(time.time)
#create table which has been defined above:
# if ifNotExists=True, then an existing table does not get overridden.
GobanTable.createTable(ifNotExists=True)
# add a game to goban table
gob = GobanTable(player1="gast",player2="gast",size=9)
class Users(SQLObject):
"""
creates a table named users with following columns:
name - name of user
password - passsword of user
game1 - the 10 game slots of this user contain names
... of goban tables
game10
sessionid - id of current session
timeout - when does session time out?
"""
username = StringCol(unique=True,notNone=True,alternateID=True)
password = StringCol()
game1 = StringCol(default=None)
game2 = StringCol(default=None)
game3 = StringCol(default=None)
game4 = StringCol(default=None)
game5 = StringCol(default=None)
game6 = StringCol(default=None)
game7 = StringCol(default=None)
game8 = StringCol(default=None)
game9 = StringCol(default=None)
game10 = StringCol(default=None)
sessionid = StringCol(default=None)
timeout = IntCol(default=None)
def gamelist(self):
"""
return the list of all games of the given user.
"""
#TODO: how to generate this list automatically?
ret = []
ret.append(self.game1)
ret.append(self.game2)
ret.append(self.game3)
ret.append(self.game4)
ret.append(self.game5)
ret.append(self.game6)
ret.append(self.game7)
ret.append(self.game8)
ret.append(self.game9)
ret.append(self.game10)
return ret
def removegame(self,gamename):
"""removes a game whose name is given."""
if self.game1 == gamename: self.game1=None
if self.game2 == gamename: self.game2=None
if self.game3 == gamename: self.game3=None
if self.game4 == gamename: self.game4=None
if self.game5 == gamename: self.game5=None
if self.game6 == gamename: self.game6=None
if self.game7 == gamename: self.game7=None
if self.game8 == gamename: self.game8=None
if self.game9 == gamename: self.game9=None
if self.game10 == gamename: self.game10=None
def free_slot_left(self):
"""Returns True, if there is an empty game slot left, else returns False."""
if self.game1 == None: return True
elif self.game2 == None: return True
elif self.game3 == None: return True
elif self.game4 == None: return True
elif self.game5 == None: return True
elif self.game6 == None: return True
elif self.game7 == None: return True
elif self.game8 == None: return True
elif self.game9 == None: return True
elif self.game10 == None: return True
else: return False
def add_game(self,gamename):
"""saves the game name into an empty slot"""
if self.game1 == None: self.game1 = gamename
elif self.game2 == None: self.game1 = gamename
elif self.game3 == None: self.game1 = gamename
elif self.game4 == None: self.game1 = gamename
elif self.game5 == None: self.game1 = gamename
elif self.game6 == None: self.game1 = gamename
elif self.game7 == None: self.game1 = gamename
elif self.game8 == None: self.game1 = gamename
elif self.game9 == None: self.game1 = gamename
elif self.game10 == None: self.game1 = gamename
else: return False
def set_timeout(self):
self.timeout = int(time.time()) + 900 #current time in seconds + seconds for session
def get_users_with_free_game_slots():
"""
returns a list of users who have at least one empty game slot """
idlist = Users.select(Users.q.free_slot_left == True)
retlist = []
for entry in idlist:
retlist.append(Users.get(entry).username)
return retlist
#create table which has been defined above:
# if ifNotExists=True, then an existing table does not get overridden.
Users.createTable(ifNotExists=True)
if __name__ == "__main__":
connection_string='sqlite:%s?%s' %(os.path.abspath("webgo.sqlite"),dbdebug)
connection=connectionForURI(connection_string)
__connection__ = connection
# add a game to goban table
user = Users(username="gast",password="gast")
#print user.gamelist()
print user.sessionid
user.sessionid=1
print user.sessionid
#print Users.byUsername("gast")
#deleting a row:
#f = MyObject(1)
#f.destroySelf()

View file

@ -1,19 +1,7 @@
import psql,login,helper import login,helper,database
#helper = apache.import_module("helper") #helper = apache.import_module("helper")
def get_game_slot_of_game(player, gamename):
"""
gets playername and game name,
searches through the game slots and returns the game slot used by the game.
"""
slotlist = psql.get_user_game_list(player)
ret = ""
for i in range(0,len(slotlist)):
if slotlist[i] == gamename:
ret = "game" + str(i+1)
return ret
def main(req,form): def main(req,form):
""" """
get request,util.FieldStorage. get request,util.FieldStorage.
@ -27,16 +15,15 @@ def main(req,form):
gamename = "" gamename = ""
if gamename != "": if gamename != "":
#get player names from game table in database #get player names from game table in database
players = psql.get_players_for_game(gamename) mygame=database.GobanTable.byName(gamename)
players = mygame.players()
#free game slots of players #free game slots of players
for player in players: for player in players:
gameslot = get_game_slot_of_game(player,gamename) myuser = database.Users.byUsername(player)
helper.debug(req,form,"delete: got %s as gameslot." % gameslot) myuser.removegame(gamename)
if gameslot != "":
psql.set_game_slot(player,gameslot,"")
#delete table #delete table
psql.drop_table(gamename) mygame.destroySelf()
#now display game overview form. #now display game overview form.
login.game_overview_form(req,form) login.game_overview_form(req,form)

View file

@ -1,6 +1,29 @@
import os,tempfile,dircache,string,commands import ConfigParser,os,tempfile,dircache,string,commands
configname="webgo.conf"
def read_config(location=None):
config = ConfigParser.ConfigParser()
if location != None:
# location of file was given on command line
try:
config.readfp(open(location))
except:
#TODO: debug-awareness
print "(EE)[%s]: cannot open %s!"%(__name__,location)
else:
#use default config from . or /etc
try:
config.readfp(open('/etc/'+configname))
except:
try:
config.readfp(open(configname))
except:
#TODO: debug-awareness
print "(EE)[%s]: cannot open %s in ./ or /etc/!"%(__name__,location)
return config
def read_file(filename): def read_file(filename):
""" """

View file

@ -1,5 +1,5 @@
from mod_python import * from mod_python import *
import psql,helper,login import helper,login,database
def display_game_creation_form(req,form): def display_game_creation_form(req,form):
@ -40,6 +40,8 @@ def process_creation_form(req,form):
""" """
validates and processes the game creation form. validates and processes the game creation form.
If everything was ok, a game will be created. If everything was ok, a game will be created.
TODO: change this function, so that the original database state canbe
restored, if for example one of the users does not have a free game slot.
""" """
player1 = form["player1"] player1 = form["player1"]
player2 = form["player2"] player2 = form["player2"]
@ -53,12 +55,13 @@ def process_creation_form(req,form):
#check if at least one of the players is the current user #check if at least one of the players is the current user
if (player1 == username) or (player2 == username): if (player1 == username) or (player2 == username):
#create game #create game
gamename = psql.create_goban_table(player1,player2,int(form["gobansize"]),description) mygame = database.GobanTable(player1=player1,player2=player2,size=int(form["gobansize"]),description = description)
gamename = mygame.name
#update entries for player one and player two #update entries for player one and player two
for player in [player1,player2]: for player in [player1,player2]:
gameslot = psql.get_free_game_slot(player) myplayer = database.Users.byUsername(player)
if gameslot != "": if myplayer.free_slot_left:
psql.set_game_slot(player,gameslot,gamename) myplayer.add_game(gamename)
else:#should not happen: no free game slot. else:#should not happen: no free game slot.
#print error msg #print error msg
req.write("Error: No free game slots for player "+player+"!") req.write("Error: No free game slots for player "+player+"!")
@ -77,7 +80,7 @@ def create_user_dropdown_list(listname,selected = ""):
gets a name for the generated list and, optionally, the preselected value. gets a name for the generated list and, optionally, the preselected value.
returns a <select> form as string. returns a <select> form as string.
""" """
userlist = psql.get_users_with_free_game_slots() userlist = database.get_users_with_free_game_slots()
data = '<select name="%s">' % listname data = '<select name="%s">' % listname
for item in userlist: for item in userlist:
#check whether current item = item for preselection #check whether current item = item for preselection

View file

@ -4,7 +4,7 @@ DEBUG = 1
import sys,string import sys,string
import cgi import cgi
import psql,helper,gnugo import helper,gnugo,database
picklefile = "goban.pickledump" picklefile = "goban.pickledump"
@ -30,7 +30,9 @@ def display_goban(goban,req,form):
<input type="hidden" name="game" value="%s"> <input type="hidden" name="game" value="%s">
""" % (form["sessionid"],form["username"],form["game"]) """ % (form["sessionid"],form["username"],form["game"])
sgf = psql.get_sgf(form["game"]) #TODO: check form[game] before the following asignment
mygame = database.GobanTable.byName(form["game"])
sgf = mygame.sgf
helper.debug(req,form,sgf) helper.debug(req,form,sgf)
gobandict = gnugo.parse_static_gnugo_sgf(sgf) gobandict = gnugo.parse_static_gnugo_sgf(sgf)
@ -133,58 +135,13 @@ def set_stone(gobandict, position,req,form):
#let gnugo make the above move, let gnugo write move to file #let gnugo make the above move, let gnugo write move to file
new_sgf = gnugo.make_move_in_sgf(req,form,gobandict,position) new_sgf = gnugo.make_move_in_sgf(req,form,gobandict,position)
#write new sgf file into database #write new sgf file into database
psql.update_goban_table_field(name,"x1","sgf",new_sgf) mygame = database.GobanTable.byName(name)
psql.update_turn_number(name,turn+1) mygame.sgf = new_sgf
psql.set_time(name) mygame.turn_number = turn + 1
mygame.set_time()
return "" return ""
else: #move not ok else: #move not ok
return "This is not a legal move (says Gnugo)." return "This is not a legal move (says Gnugo)."
else: #position not empty else: #position not empty
return "Could not make move: Field not empty." return "Could not make move: Field not empty."
def update_goban_dict_and_table(gobandict,gobanlite):
"""
gets a gobandict and a gobdict light (just coordinates and size).
updates the fields in gobandict and database.
returns changed gobandict and True (or False) if something has been changed (or not).
"""
tf = False
for key in gobanlite.keys():
if gobandict[key] != gobanlite[key]:
#found difference in dicts.
#update gobandict
gobandict[key] = gobanlite[key]
#update databse table. the only valid difference can be changed goban field positions.
psql.update_goban_field(gobandict["name"],key[0],key[1],gobandict[key])
tf = True
return gobandict,tf
###############################################################################
def main(req,form):
"""# Print the required header that tells the browser how to render the text.
#(currently done by error logger)
#print "Content-Type: text/plain\n\n"
gamename = form["game"]
#do stuff
data = helper.header()
#read goban table from database
tmplist = psql.read_table(gamename)
#make a dictionary out of the list
goban = psql.fetchall_list_to_goban_dict(tmplist)
#print goban
(goban,retstring) = process_form(goban)
data += "<p> Turn number: %s, %s Player's Move.</p>" % (goban["turn_number"],("White","Black")[goban["turn_number"] % 2]) #eleet ;>
data += display_goban(goban)
if retstring != "":
data +="\n<p>"+retstring+"</p>\n"
data += helper.footer(req,form)
print data
"""

View file

@ -1,14 +1,14 @@
import psql import database
def clear(): def clear():
try: try:
psql.drop_table("users") database.Users.dropTable(ifExists=True)
except: except:
pass pass
def create(): def create():
database.Users.createTable(ifExists = False)
#psql.create_goban_table("gast","gast2",9) #psql.create_goban_table("gast","gast2",9)
psql.create_user_table()
#psql.add_webgo_user("gast","gast") #psql.add_webgo_user("gast","gast")
#psql.add_webgo_user("gast2","gast2") #psql.add_webgo_user("gast2","gast2")

View file

@ -1,4 +1,4 @@
import psql,init_webgo,helper,gamecreation import database,init_webgo,helper,gamecreation
from sets import Set as set from sets import Set as set
from mod_python import * from mod_python import *
@ -11,17 +11,19 @@ def process_form(req,form):
if ("username" in form.keys()) and ("password" in form.keys()): if ("username" in form.keys()) and ("password" in form.keys()):
#extract name and password #extract name and password
username = form["username"] username = form["username"]
myuser = database.Users.byUsername(username)
password = form["password"] password = form["password"]
sessionid = form["sessionid"] sessionid = form["sessionid"]
origpassword = psql.get_user_info(username,"password")
origpassword = myuser.password
#debug: #debug:
helper.debug(req,form,'<hr>--password:'+str(password)+' ---origpassword:'+str(origpassword)+'<hr>') helper.debug(req,form,'<hr>--password:'+str(password)+' ---origpassword:'+str(origpassword)+'<hr>')
#check if user exists (else we would get an error string) #check if user exists (else we would get an error string)
if origpassword != "no such user": #no error message, now check password if origpassword != "no such user": #no error message, now check password
if password == origpassword: if password == origpassword:
#login accepted #login accepted
psql.set_user_sessionid(username,sessionid) myuser.sessionid = sessionid
psql.set_user_timeout(username) myser.set_timeout()
#now display list of games. #now display list of games.
game_overview_form(req,form) game_overview_form(req,form)
else: else:
@ -48,7 +50,7 @@ def game_overview_form(req,form):
<h2> Current Games: </h2> <h2> Current Games: </h2>
""" """
gamelist = psql.get_user_game_list(username) gamelist = myuser.gamelist()
#debug #debug
helper.debug(req,form,str(gamelist)+"<hr>\n") helper.debug(req,form,str(gamelist)+"<hr>\n")
#display list of current games #display list of current games
@ -65,15 +67,16 @@ def game_overview_form(req,form):
tmp += '<input type="hidden" name="username" value="%s">\n' % username tmp += '<input type="hidden" name="username" value="%s">\n' % username
tmp += '<input type="hidden" name="game" value="%s">\n' % item tmp += '<input type="hidden" name="game" value="%s">\n' % item
tmp += '<td><input type=submit class="submit" name="play" value="Play"></td>\n' tmp += '<td><input type=submit class="submit" name="play" value="Play"></td>\n'
description = psql.get_description(item) mygame = database.GobanTable.byName(item)
description = mygame.description
if (description == None) or (description == "None") or (description == ""): if (description == None) or (description == "None") or (description == ""):
description = item description = item
tmp += '<td>%s</td>\n' % description tmp += '<td>%s</td>\n' % description
players = psql.get_players_for_game(item) players = mygame.players()
tmp += '<td>%s</td>\n' % players[0] tmp += '<td>%s</td>\n' % players[0]
tmp += '<td>%s</td>\n' % players[1] tmp += '<td>%s</td>\n' % players[1]
tmp += '<td>%s</td>\n' % helper.format_time(psql.get_time(item,"created")) tmp += '<td>%s</td>\n' % helper.format_time(mygame.created)
tmp += '<td>%s</td>\n' % helper.format_time(psql.get_time(item,"lastmove")) tmp += '<td>%s</td>\n' % helper.format_time(mygame.lastmove)
tmp += '<td><input type=submit class="submit" name="delete" value="Delete"></td>\n' tmp += '<td><input type=submit class="submit" name="delete" value="Delete"></td>\n'
tmp += '</tr></form>\n' tmp += '</tr></form>\n'
if helper.clean_list(gamelist) != []: if helper.clean_list(gamelist) != []:
@ -153,9 +156,10 @@ def logout(req,form):
reads username from form and clears timeout and sessionid from users table. reads username from form and clears timeout and sessionid from users table.
""" """
username = form["username"] username = form["username"]
psql.set_user_sessionid(username,"") myuser = database.Users.byUsername(username)
psql.set_user_timeout(username,"") myuser.sessionid = ""
myuser.timeout = 0
def main(req,form): def main(req,form):
#debug #debug

13
logout.py Normal file
View file

@ -0,0 +1,13 @@
import database
import login
def process_form(req,form):
username = form["username"]
myuser = database.Users.byUsername(username)
myuser.sessionid = None
login.main(req,form)
def main(req,form):
process_form(req,form)

50
main.py
View file

@ -1,5 +1,5 @@
import sys, traceback,string,time import sys, traceback,string,time
import init_webgo,psql import init_webgo,database
from mod_python import * from mod_python import *
@ -24,33 +24,45 @@ def handler(req):
sessionid="" sessionid=""
username="" username=""
#if sessionid=sesssionid and time < timeout: try:
# set_timeout myuser = database.Users.byUsername(username)
if (psql.get_user_info(username,'timeout') > int(time.time())) and (sessionid == psql.get_user_info(username,'sessionid')): valid_user = True
psql.set_user_timeout(username) except:
if "create" in form.keys(): #no such user
gamecreation = apache.import_module("gamecreation") valid_user = False
gamecreation.main(req,form)
elif "delete" in form.keys(): if username != "" and valid_user:
deletegame = apache.import_module("deletegame") if (myuser.timeout > int(time.time())) and (sessionid == myuser.sessionid):
deletegame.main(req,form) myuser.set_timeout()
elif ("play" in form.keys()) or ("refresh" in form.keys()):
playgame = apache.import_module("playgame") if "create" in form.keys():
playgame.main(req,form) gamecreation = apache.import_module("gamecreation")
elif "logout" in form.keys(): gamecreation.main(req,form)
logout = apache.import_module("logout") elif "delete" in form.keys():
logout.main(req,form) deletegame = apache.import_module("deletegame")
deletegame.main(req,form)
elif ("play" in form.keys()) or ("refresh" in form.keys()):
playgame = apache.import_module("playgame")
playgame.main(req,form)
elif "logout" in form.keys():
logout = apache.import_module("logout")
logout.main(req,form)
else:
#call login.py
login = apache.import_module("login")
login.main(req,form)
else: else:
#call login.py #call login.py
login = apache.import_module("login") login = apache.import_module("login")
login.main(req,form) login.main(req,form)
else: else:
if "createaccount" in form.keys(): if "createaccount" in form.keys():
createaccount = apache.import_module("createaccount") createaccount = apache.import_module("createaccount")
createaccount.main(req,form) createaccount.main(req,form)
else:#call login.py else:#call login.py
login = apache.import_module("login") login = apache.import_module("login")
login.main(req,form) login.main(req,form)
return apache.OK return apache.OK
except: except:

View file

@ -1,4 +1,4 @@
import goban,helper,psql,login,gnugo import goban,helper,database,login,gnugo
import string import string
DEBUG = 1 DEBUG = 1
@ -26,14 +26,15 @@ def create_gobandict(req,form,gamename):
loads sgf, transforms it to dict, writes stuff like player names to dict loads sgf, transforms it to dict, writes stuff like player names to dict
returns dict returns dict
""" """
#read goban table from database #read goban sgf from database
tmplist = psql.read_table(gamename) mygame = database.GobanTable.byName(gamename)
#make a dictionary out of the list sgf = mygame.sgf
tmpdict = psql.fetchall_list_to_goban_dict(tmplist)
sgf = psql.get_sgf(gamename)
gobandict = gnugo.parse_static_gnugo_sgf(sgf) gobandict = gnugo.parse_static_gnugo_sgf(sgf)
for key in ["player1","player2","turn_number","name","sgf"]: gobandict["player1"] = mygame.player1
gobandict[key] = tmpdict[key] gobandict["player2"] = mygame.player2
gobandict["turn_number"] = mygame.turn_number
gobandict["name"] = mygame.name
gobandict["sgf"] = sgf
return gobandict return gobandict
def main(req,form): def main(req,form):
@ -67,7 +68,7 @@ def main(req,form):
gobandict = create_gobandict(req,form,gamename) gobandict = create_gobandict(req,form,gamename)
else: else:
helper.debug(req,form,"its not my turn.") helper.debug(req,form,"it's not my turn.")
data += """<br>Turn number: %s. %s plays.\n data += """<br>Turn number: %s. %s plays.\n
""" % (str(gobandict["turn_number"]), (string.capitalize(gobandict["play"]))) """ % (str(gobandict["turn_number"]), (string.capitalize(gobandict["play"])))
@ -75,7 +76,7 @@ def main(req,form):
#if yes: print 'your move' and display goban and process move #if yes: print 'your move' and display goban and process move
#if not: print '...s move' and display goban. #if not: print '...s move' and display goban.
if is_my_turn(req,form,gobandict): if is_my_turn(req,form,gobandict):
data += "<br>Its your turn.<br>\n" data += "<br>It's your turn.<br>\n"
else: else:
data += "<br>This is not your turn. You have to wait for the move of the other player.<br>\n" data += "<br>This is not your turn. You have to wait for the move of the other player.<br>\n"
#print goban #print goban