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
@ -42,7 +42,8 @@ def process_form(req,form):
except:
username = ""
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)
data = """
<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")
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):
"""
get request,util.FieldStorage.
@ -27,16 +15,15 @@ def main(req,form):
gamename = ""
if gamename != "":
#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
for player in players:
gameslot = get_game_slot_of_game(player,gamename)
helper.debug(req,form,"delete: got %s as gameslot." % gameslot)
if gameslot != "":
psql.set_game_slot(player,gameslot,"")
myuser = database.Users.byUsername(player)
myuser.removegame(gamename)
#delete table
psql.drop_table(gamename)
mygame.destroySelf()
#now display game overview 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):
"""

View file

@ -1,5 +1,5 @@
from mod_python import *
import psql,helper,login
import helper,login,database
def display_game_creation_form(req,form):
@ -40,6 +40,8 @@ def process_creation_form(req,form):
"""
validates and processes the game creation form.
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"]
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
if (player1 == username) or (player2 == username):
#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
for player in [player1,player2]:
gameslot = psql.get_free_game_slot(player)
if gameslot != "":
psql.set_game_slot(player,gameslot,gamename)
myplayer = database.Users.byUsername(player)
if myplayer.free_slot_left:
myplayer.add_game(gamename)
else:#should not happen: no free game slot.
#print error msg
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.
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
for item in userlist:
#check whether current item = item for preselection

View file

@ -4,7 +4,7 @@ DEBUG = 1
import sys,string
import cgi
import psql,helper,gnugo
import helper,gnugo,database
picklefile = "goban.pickledump"
@ -30,7 +30,9 @@ def display_goban(goban,req,form):
<input type="hidden" name="game" value="%s">
""" % (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)
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
new_sgf = gnugo.make_move_in_sgf(req,form,gobandict,position)
#write new sgf file into database
psql.update_goban_table_field(name,"x1","sgf",new_sgf)
psql.update_turn_number(name,turn+1)
psql.set_time(name)
mygame = database.GobanTable.byName(name)
mygame.sgf = new_sgf
mygame.turn_number = turn + 1
mygame.set_time()
return ""
else: #move not ok
return "This is not a legal move (says Gnugo)."
else: #position 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():
try:
psql.drop_table("users")
database.Users.dropTable(ifExists=True)
except:
pass
def create():
database.Users.createTable(ifExists = False)
#psql.create_goban_table("gast","gast2",9)
psql.create_user_table()
#psql.add_webgo_user("gast","gast")
#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 mod_python import *
@ -11,17 +11,19 @@ def process_form(req,form):
if ("username" in form.keys()) and ("password" in form.keys()):
#extract name and password
username = form["username"]
myuser = database.Users.byUsername(username)
password = form["password"]
sessionid = form["sessionid"]
origpassword = psql.get_user_info(username,"password")
origpassword = myuser.password
#debug:
helper.debug(req,form,'<hr>--password:'+str(password)+' ---origpassword:'+str(origpassword)+'<hr>')
#check if user exists (else we would get an error string)
if origpassword != "no such user": #no error message, now check password
if password == origpassword:
#login accepted
psql.set_user_sessionid(username,sessionid)
psql.set_user_timeout(username)
myuser.sessionid = sessionid
myser.set_timeout()
#now display list of games.
game_overview_form(req,form)
else:
@ -48,7 +50,7 @@ def game_overview_form(req,form):
<h2> Current Games: </h2>
"""
gamelist = psql.get_user_game_list(username)
gamelist = myuser.gamelist()
#debug
helper.debug(req,form,str(gamelist)+"<hr>\n")
#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="game" value="%s">\n' % item
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 == ""):
description = item
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[1]
tmp += '<td>%s</td>\n' % helper.format_time(psql.get_time(item,"created"))
tmp += '<td>%s</td>\n' % helper.format_time(psql.get_time(item,"lastmove"))
tmp += '<td>%s</td>\n' % helper.format_time(mygame.created)
tmp += '<td>%s</td>\n' % helper.format_time(mygame.lastmove)
tmp += '<td><input type=submit class="submit" name="delete" value="Delete"></td>\n'
tmp += '</tr></form>\n'
if helper.clean_list(gamelist) != []:
@ -153,8 +156,9 @@ def logout(req,form):
reads username from form and clears timeout and sessionid from users table.
"""
username = form["username"]
psql.set_user_sessionid(username,"")
psql.set_user_timeout(username,"")
myuser = database.Users.byUsername(username)
myuser.sessionid = ""
myuser.timeout = 0
def main(req,form):

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)

22
main.py
View file

@ -1,5 +1,5 @@
import sys, traceback,string,time
import init_webgo,psql
import init_webgo,database
from mod_python import *
@ -24,10 +24,17 @@ def handler(req):
sessionid=""
username=""
#if sessionid=sesssionid and time < timeout:
# set_timeout
if (psql.get_user_info(username,'timeout') > int(time.time())) and (sessionid == psql.get_user_info(username,'sessionid')):
psql.set_user_timeout(username)
try:
myuser = database.Users.byUsername(username)
valid_user = True
except:
#no such user
valid_user = False
if username != "" and valid_user:
if (myuser.timeout > int(time.time())) and (sessionid == myuser.sessionid):
myuser.set_timeout()
if "create" in form.keys():
gamecreation = apache.import_module("gamecreation")
gamecreation.main(req,form)
@ -44,6 +51,10 @@ def handler(req):
#call login.py
login = apache.import_module("login")
login.main(req,form)
else:
#call login.py
login = apache.import_module("login")
login.main(req,form)
else:
if "createaccount" in form.keys():
createaccount = apache.import_module("createaccount")
@ -52,6 +63,7 @@ def handler(req):
login = apache.import_module("login")
login.main(req,form)
return apache.OK
except:
errtime = '----- '+ time.ctime(time.time()) +' -----\n'

View file

@ -1,4 +1,4 @@
import goban,helper,psql,login,gnugo
import goban,helper,database,login,gnugo
import string
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
returns dict
"""
#read goban table from database
tmplist = psql.read_table(gamename)
#make a dictionary out of the list
tmpdict = psql.fetchall_list_to_goban_dict(tmplist)
sgf = psql.get_sgf(gamename)
#read goban sgf from database
mygame = database.GobanTable.byName(gamename)
sgf = mygame.sgf
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
for key in ["player1","player2","turn_number","name","sgf"]:
gobandict[key] = tmpdict[key]
gobandict["player1"] = mygame.player1
gobandict["player2"] = mygame.player2
gobandict["turn_number"] = mygame.turn_number
gobandict["name"] = mygame.name
gobandict["sgf"] = sgf
return gobandict
def main(req,form):
@ -67,7 +68,7 @@ def main(req,form):
gobandict = create_gobandict(req,form,gamename)
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
""" % (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 not: print '...s move' and display goban.
if is_my_turn(req,form,gobandict):
data += "<br>Its your turn.<br>\n"
data += "<br>It's your turn.<br>\n"
else:
data += "<br>This is not your turn. You have to wait for the move of the other player.<br>\n"
#print goban