various bugfixes and cleanups
This commit is contained in:
parent
c4ee02e046
commit
5ea601efc8
10 changed files with 107 additions and 575 deletions
|
@ -12,7 +12,7 @@ import gnugo, helper
|
||||||
dbname = "/home/mtsrc/daten/projekte/webgo/webgo.sqlite"
|
dbname = "/home/mtsrc/daten/projekte/webgo/webgo.sqlite"
|
||||||
#dbname = "/tmp/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=t&debugOutput=t" #don't want SQL debug messages? just change to an empty string: "debug="
|
||||||
#dbdebug = "debug="
|
dbdebug = "debug="
|
||||||
|
|
||||||
#build connection string and connect
|
#build connection string and connect
|
||||||
connection_string='sqlite:%s?%s' %(dbname,dbdebug)
|
connection_string='sqlite:%s?%s' %(dbname,dbdebug)
|
||||||
|
@ -41,7 +41,7 @@ class GobanTable(SQLObject):
|
||||||
size = IntCol()
|
size = IntCol()
|
||||||
turn_number = IntCol(default=1)
|
turn_number = IntCol(default=1)
|
||||||
description = StringCol(default=None)
|
description = StringCol(default=None)
|
||||||
sgf = StringCol(default=gnugo.create_sgf_file(size))
|
sgf = StringCol(default=None)
|
||||||
created = IntCol(default=int(time.time()))
|
created = IntCol(default=int(time.time()))
|
||||||
lastmove = IntCol(default=int(time.time()))
|
lastmove = IntCol(default=int(time.time()))
|
||||||
|
|
||||||
|
@ -54,6 +54,9 @@ class GobanTable(SQLObject):
|
||||||
"""updates self.lastmove to current time"""
|
"""updates self.lastmove to current time"""
|
||||||
self.lastmove = int(time.time())
|
self.lastmove = int(time.time())
|
||||||
|
|
||||||
|
def create_sgf(self):
|
||||||
|
"""create an empty sgf file and safe it as a string in self.sgf."""
|
||||||
|
self.sgf = gnugo.create_sgf_file(self.size)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,10 @@ input.submit:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Board--------------------------------------------------------------------------- --------------------------------- */
|
/* The Board--------------------------------------------------------------------------- --------------------------------- */
|
||||||
|
#board{
|
||||||
|
padding-top:30px;
|
||||||
|
}
|
||||||
|
|
||||||
#board a, a:link, a:visited {
|
#board a, a:link, a:visited {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,8 @@ class GameCreation:
|
||||||
if (player1 == username) or (player2 == username):
|
if (player1 == username) or (player2 == username):
|
||||||
#create game
|
#create game
|
||||||
mygame = database.GobanTable(player1=player1,player2=player2,size=gobansize,description = description)
|
mygame = database.GobanTable(player1=player1,player2=player2,size=gobansize,description = description)
|
||||||
|
#I don't know how to do create_sgf during creation of the column, so it has to be called explicitly.
|
||||||
|
mygame.create_sgf()
|
||||||
gamename = mygame.id
|
gamename = mygame.id
|
||||||
#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]:
|
||||||
|
|
13
gnugo.py
13
gnugo.py
|
@ -155,7 +155,7 @@ def is_legal(gobandict,coords):
|
||||||
tests wether proposed move is legal.
|
tests wether proposed move is legal.
|
||||||
returns True or False.
|
returns True or False.
|
||||||
"""
|
"""
|
||||||
"""size = gobandict["size"]
|
"""
|
||||||
turn = gobandict["turn_number"]
|
turn = gobandict["turn_number"]
|
||||||
#who's turn is it?
|
#who's turn is it?
|
||||||
color = ["white","black"][turn % 2] #even turn: white plays, else black plays
|
color = ["white","black"][turn % 2] #even turn: white plays, else black plays
|
||||||
|
@ -182,7 +182,7 @@ def create_sgf_file(size, filename=""):
|
||||||
returns the content of an empty sgf file.
|
returns the content of an empty sgf file.
|
||||||
"""
|
"""
|
||||||
conn = GTP_connection(gnugocommand)
|
conn = GTP_connection(gnugocommand)
|
||||||
result = conn.exec_cmd("boardsize "+str(size))
|
result = conn.exec_cmd("boardsize %s" % str(size))
|
||||||
if filename == "":
|
if filename == "":
|
||||||
filename = filehandling.gen_temp_file()
|
filename = filehandling.gen_temp_file()
|
||||||
result = conn.exec_cmd("printsgf "+filename)
|
result = conn.exec_cmd("printsgf "+filename)
|
||||||
|
@ -199,16 +199,11 @@ def make_move_in_sgf(gobandict,coords,filename = ""):
|
||||||
returns: sgf string of new file.
|
returns: sgf string of new file.
|
||||||
"""
|
"""
|
||||||
size = gobandict["size"]
|
size = gobandict["size"]
|
||||||
turn = gobandict["turn_number"]
|
|
||||||
sgf = gobandict["sgf"]
|
sgf = gobandict["sgf"]
|
||||||
|
|
||||||
#convert given coordinates
|
#convert given coordinates
|
||||||
gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size)
|
gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size)
|
||||||
# get current player
|
# get current player
|
||||||
#even turn: white plays, else its blacks turn
|
|
||||||
"""
|
|
||||||
color = ["white","black"][turn % 2]
|
|
||||||
"""
|
|
||||||
color = gobandict["play"]
|
color = gobandict["play"]
|
||||||
#generate tmpfile
|
#generate tmpfile
|
||||||
if filename == "":
|
if filename == "":
|
||||||
|
@ -232,9 +227,7 @@ def parse_static_gnugo_sgf(s):
|
||||||
"""
|
"""
|
||||||
gets a string containing the data saved by the gnugo "printsgf" order.
|
gets a string containing the data saved by the gnugo "printsgf" order.
|
||||||
"""
|
"""
|
||||||
|
#dictionary to return
|
||||||
|
|
||||||
#dicitonary to return
|
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
#removing newlines vom given string
|
#removing newlines vom given string
|
||||||
|
|
91
login.py
91
login.py
|
@ -6,36 +6,7 @@ from cherrypy.lib import httptools
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
def navigation_bar(req,form):
|
|
||||||
"" "
|
|
||||||
gets request object and util.FieldStorage form.
|
|
||||||
writes the following to req:
|
|
||||||
- a button to return to the game overview
|
|
||||||
- a logout button
|
|
||||||
returns string
|
|
||||||
" ""
|
|
||||||
username = form["username"]
|
|
||||||
sessionid = form["sessionid"]
|
|
||||||
game = form["game"]
|
|
||||||
#TODO: buttons
|
|
||||||
data=" ""
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="username" value="%s">
|
|
||||||
<input type="hidden" name="sessionid" value="%s">
|
|
||||||
<input type="hidden" name="game" value="%s">
|
|
||||||
<input type="submit" class="submit" name="logout" value="logout">
|
|
||||||
<input type="submit" class="submit" name="game overview" value="game overview">
|
|
||||||
<input type="submit" class="submit" name="refresh" value="refresh">
|
|
||||||
</form>
|
|
||||||
"" " % (username,sessionid,game)
|
|
||||||
return(data)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
class Login:
|
class Login:
|
||||||
def index(self,username=None,password=None):
|
def index(self,username=None,password=None):
|
||||||
"""
|
"""
|
||||||
|
@ -108,40 +79,46 @@ class Overview:
|
||||||
else:
|
else:
|
||||||
return helper.cs_render("templates/not_logged_in.cs")
|
return helper.cs_render("templates/not_logged_in.cs")
|
||||||
|
|
||||||
def game_overview_form(self,username):
|
def game_overview_form(self,username=None):
|
||||||
"""
|
"""
|
||||||
gets:name of user,
|
gets:name of user,
|
||||||
prints a form with the option to select,create and delete games.
|
prints a form with the option to select,create and delete games.
|
||||||
"""
|
"""
|
||||||
myuser = database.Users.byUsername(username)
|
try:
|
||||||
|
myuser = database.Users.byUsername(username)
|
||||||
|
user = True
|
||||||
|
except:
|
||||||
|
user = False
|
||||||
|
if username != "" and user:
|
||||||
|
gamelist = myuser.gamelist()
|
||||||
|
|
||||||
gamelist = myuser.gamelist()
|
settings = {}
|
||||||
|
|
||||||
settings = {}
|
cleanlist = helper.clean_list(gamelist)
|
||||||
|
#display list of current games
|
||||||
cleanlist = helper.clean_list(gamelist)
|
counter = 10 - len(cleanlist)
|
||||||
#display list of current games
|
settings["Data.Counter"] = counter
|
||||||
counter = 10 - len(cleanlist)
|
settings["Data.Gamelist"] = cleanlist
|
||||||
settings["Data.Counter"] = counter
|
tmp = ""
|
||||||
settings["Data.Gamelist"] = cleanlist
|
if cleanlist != []:
|
||||||
tmp = ""
|
settings["Data.GamelistNotEmpty"] = 1
|
||||||
if cleanlist != []:
|
else:
|
||||||
settings["Data.GamelistNotEmpty"] = 1
|
settings["Data.GamelistNotEmpty"] = 0
|
||||||
|
for item in gamelist:
|
||||||
|
if (item != None) and (item != "None"):
|
||||||
|
mygame = database.GobanTable.get(item)
|
||||||
|
description = mygame.description
|
||||||
|
if (description == None) or (description == "None") or (description == ""):
|
||||||
|
description = item
|
||||||
|
settings["Data.Games.%s.Description" % item] = mygame.description
|
||||||
|
settings["Data.Games.%s.Name" % item] = item
|
||||||
|
players = mygame.players()
|
||||||
|
settings["Data.Games.%s.Player1" % item] = mygame.players()[0]
|
||||||
|
settings["Data.Games.%s.Player2" % item] = mygame.players()[1]
|
||||||
|
settings["Data.Games.%s.Created" % item] = helper.format_time(mygame.created)
|
||||||
|
settings["Data.Games.%s.Lastmove" % item] = helper.format_time(mygame.lastmove)
|
||||||
|
return helper.cs_render("templates/overview.cs",settings)
|
||||||
else:
|
else:
|
||||||
settings["Data.GamelistNotEmpty"] = 0
|
return helper.cs_render("templates/not_logged_in.cs")
|
||||||
for item in gamelist:
|
|
||||||
if (item != None) and (item != "None"):
|
|
||||||
mygame = database.GobanTable.get(item)
|
|
||||||
description = mygame.description
|
|
||||||
if (description == None) or (description == "None") or (description == ""):
|
|
||||||
description = item
|
|
||||||
settings["Data.Games.%s.Description" % item] = mygame.description
|
|
||||||
settings["Data.Games.%s.Name" % item] = item
|
|
||||||
players = mygame.players()
|
|
||||||
settings["Data.Games.%s.Player1" % item] = mygame.players()[0]
|
|
||||||
settings["Data.Games.%s.Player2" % item] = mygame.players()[1]
|
|
||||||
settings["Data.Games.%s.Created" % item] = helper.format_time(mygame.created)
|
|
||||||
settings["Data.Games.%s.Lastmove" % item] = helper.format_time(mygame.lastmove)
|
|
||||||
return helper.cs_render("templates/overview.cs",settings)
|
|
||||||
|
|
||||||
index.exposed = True
|
index.exposed = True
|
2
main.py
2
main.py
|
@ -1,4 +1,4 @@
|
||||||
import sys, traceback,string,time
|
import string,time
|
||||||
import login,createaccount,helper,gamecreation,playgame,logout
|
import login,createaccount,helper,gamecreation,playgame,logout
|
||||||
from cherrypy import cpg
|
from cherrypy import cpg
|
||||||
|
|
||||||
|
|
92
playgame.py
92
playgame.py
|
@ -3,43 +3,6 @@ import string
|
||||||
from cherrypy import cpg
|
from cherrypy import cpg
|
||||||
from cherrypy.lib import httptools
|
from cherrypy.lib import httptools
|
||||||
|
|
||||||
DEBUG = 1
|
|
||||||
|
|
||||||
def is_my_turn(req,form,gobandict):
|
|
||||||
"""
|
|
||||||
gets request and util.FiedStorage form.
|
|
||||||
check wether or not the current this is the players turn.
|
|
||||||
return true or false.
|
|
||||||
"""
|
|
||||||
me = form["username"]
|
|
||||||
player1 = gobandict["player1"]
|
|
||||||
player2 = gobandict["player2"]
|
|
||||||
play = gobandict["play"]
|
|
||||||
|
|
||||||
if ((player1 == me) and (play == "white")) or ((player2 == me) and (play == "black")):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def create_gobandict(req,form,gamename):
|
|
||||||
"""
|
|
||||||
gets a gamename
|
|
||||||
loads sgf, transforms it to dict, writes stuff like player names to dict
|
|
||||||
returns dict
|
|
||||||
TODO: is this function still in use?
|
|
||||||
"""
|
|
||||||
#read goban sgf from database
|
|
||||||
mygame = database.GobanTable.byName(gamename)
|
|
||||||
sgf = mygame.sgf
|
|
||||||
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
|
|
||||||
gobandict["player1"] = mygame.player1
|
|
||||||
gobandict["player2"] = mygame.player2
|
|
||||||
gobandict["turn_number"] = mygame.turn_number
|
|
||||||
gobandict["name"] = mygame.name
|
|
||||||
gobandict["sgf"] = sgf
|
|
||||||
return gobandict
|
|
||||||
|
|
||||||
|
|
||||||
class PlayGame:
|
class PlayGame:
|
||||||
"""
|
"""
|
||||||
|
@ -58,6 +21,22 @@ class PlayGame:
|
||||||
else:
|
else:
|
||||||
httptools.redirect("/login")
|
httptools.redirect("/login")
|
||||||
|
|
||||||
|
def is_my_turn(self,gobandict):
|
||||||
|
"""
|
||||||
|
gets request and util.FiedStorage form.
|
||||||
|
check wether or not the current this is the players turn.
|
||||||
|
return true or false.
|
||||||
|
"""
|
||||||
|
me = gobandict["username"]
|
||||||
|
player1 = gobandict["player1"]
|
||||||
|
player2 = gobandict["player2"]
|
||||||
|
play = gobandict["play"]
|
||||||
|
|
||||||
|
if ((player1 == me) and (play == "black")) or ((player2 == me) and (play == "white")):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def display_goban(self,gamename,settings={}):
|
def display_goban(self,gamename,settings={}):
|
||||||
"""
|
"""
|
||||||
gets: dictionary containing the layout of the used goban.
|
gets: dictionary containing the layout of the used goban.
|
||||||
|
@ -72,10 +51,21 @@ class PlayGame:
|
||||||
mygame = database.GobanTable.get(gamename)
|
mygame = database.GobanTable.get(gamename)
|
||||||
sgf = mygame.sgf
|
sgf = mygame.sgf
|
||||||
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
|
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
|
||||||
|
gobandict["username"] = cpg.request.sessionMap["username"]
|
||||||
|
gobandict["player1"],gobandict["player2"] = mygame.players()
|
||||||
size = mygame.size
|
size = mygame.size
|
||||||
|
settings["Data.TurnNumber"] = mygame.turn_number
|
||||||
|
|
||||||
settings["Data.GobanSize"] = size
|
settings["Data.GobanSize"] = size
|
||||||
settings["Data.GameName"] = gamename
|
settings["Data.GameName"] = gamename
|
||||||
|
settings["Data.Play"] = gobandict["play"]
|
||||||
|
if self.is_my_turn(gobandict):
|
||||||
|
settings["Data.MyTurn"] = "True"
|
||||||
|
else:
|
||||||
|
settings["Data.MyTurn"] = "False"
|
||||||
|
|
||||||
|
print gobandict
|
||||||
|
|
||||||
for x in range(1,size+1):
|
for x in range(1,size+1):
|
||||||
for y in range(1,size+1):
|
for y in range(1,size+1):
|
||||||
settings["Data.Goban.%d.%d.x" % (x,y)] = x
|
settings["Data.Goban.%d.%d.x" % (x,y)] = x
|
||||||
|
@ -84,6 +74,8 @@ class PlayGame:
|
||||||
settings["Data.Goban.%d.%d.color" % (x,y)] = "_white"
|
settings["Data.Goban.%d.%d.color" % (x,y)] = "_white"
|
||||||
elif gobandict[(x,y)] == 2:
|
elif gobandict[(x,y)] == 2:
|
||||||
settings["Data.Goban.%d.%d.color" % (x,y)] = "_black"
|
settings["Data.Goban.%d.%d.color" % (x,y)] = "_black"
|
||||||
|
else:
|
||||||
|
settings["Data.Goban.%d.%d.color" % (x,y)] = ""
|
||||||
#now check wether or not this field is hoshi
|
#now check wether or not this field is hoshi
|
||||||
if size == 19: # 9 hoshis
|
if size == 19: # 9 hoshis
|
||||||
if (x,y) in hoshis19x19:
|
if (x,y) in hoshis19x19:
|
||||||
|
@ -112,21 +104,27 @@ class PlayGame:
|
||||||
turn = mygame.turn_number
|
turn = mygame.turn_number
|
||||||
sgf = mygame.sgf
|
sgf = mygame.sgf
|
||||||
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
|
gobandict = gnugo.parse_static_gnugo_sgf(sgf)
|
||||||
|
gobandict["player1"],gobandict["player2"] = mygame.players()
|
||||||
|
gobandict["username"] = cpg.request.sessionMap["username"]
|
||||||
gobandict["name"] = gamename
|
gobandict["name"] = gamename
|
||||||
gobandict["turn_number"] = turn
|
gobandict["turn_number"] = turn
|
||||||
gobandict["sgf"] = sgf
|
gobandict["sgf"] = sgf
|
||||||
settings = {}
|
settings = {}
|
||||||
if (gobandict[position] == 0): #empty field
|
if (gobandict[position] == 0): #empty field
|
||||||
if gnugo.is_legal(gobandict,position): #gnugo says the move is ok
|
if self.is_my_turn(gobandict):
|
||||||
#let gnugo make the above move, let gnugo write move to file
|
if gnugo.is_legal(gobandict,position): #gnugo says the move is ok
|
||||||
new_sgf = gnugo.make_move_in_sgf(gobandict,position)
|
#let gnugo make the above move, let gnugo write move to file
|
||||||
#write new sgf file into database
|
new_sgf = gnugo.make_move_in_sgf(gobandict,position)
|
||||||
mygame.sgf = new_sgf
|
#write new sgf file into database
|
||||||
mygame.turn_number = turn + 1
|
mygame.sgf = new_sgf
|
||||||
mygame.set_time()
|
mygame.turn_number = turn + 1
|
||||||
return self.display_goban(gamename)
|
mygame.set_time()
|
||||||
else: #move not ok
|
return self.display_goban(gamename)
|
||||||
settings["Data.Message"] = "This is not a legal move (says Gnugo)."
|
else: #move not ok
|
||||||
|
settings["Data.Message"] = "This is not a legal move (says Gnugo)."
|
||||||
|
return self.display_goban(gamename,settings)
|
||||||
|
else:
|
||||||
|
settings["Data.Message"] = "This is not your turn. You have to wait for the other player."
|
||||||
return self.display_goban(gamename,settings)
|
return self.display_goban(gamename,settings)
|
||||||
else: #position not empty
|
else: #position not empty
|
||||||
settings["Data.Message"] = "Could not make move: Field not empty."
|
settings["Data.Message"] = "Could not make move: Field not empty."
|
||||||
|
|
450
psql.py
450
psql.py
|
@ -1,450 +0,0 @@
|
||||||
import helper,gnugo
|
|
||||||
import pgdb,sys,time
|
|
||||||
|
|
||||||
DEBUG = 1
|
|
||||||
|
|
||||||
dbusername="webgouser"
|
|
||||||
dbpassword="webgopassword"
|
|
||||||
dbname="webgo"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pgdb.connect(connect_string) -> connection
|
|
||||||
#connect_string = 'host:database:user:password:opt:tty'
|
|
||||||
connect_string='localhost:'+dbname+':'+dbusername+':'+dbpassword
|
|
||||||
db=pgdb.connect(connect_string)
|
|
||||||
|
|
||||||
################# table creation and removal #######################################################################
|
|
||||||
def create_table(name,layout=""):
|
|
||||||
"""
|
|
||||||
create_table(name:string, layout:string)
|
|
||||||
returns name if successfull, None if not.
|
|
||||||
|
|
||||||
|
|
||||||
simple function to create a table. the function itself would just
|
|
||||||
create an empty table with the command 'CREATE TABLE ();'.
|
|
||||||
The real layout is given to the function as an argument of type
|
|
||||||
string. This string contains all column declarations in SQL syntax:
|
|
||||||
"var1 real, var2 int"
|
|
||||||
name is the name of the table
|
|
||||||
|
|
||||||
"""
|
|
||||||
executestring = "CREATE TABLE %s ( %s );" % (name,layout)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
|
|
||||||
def create_goban_table(player1,player2,size,description=""):
|
|
||||||
"""
|
|
||||||
gets:player1, player2, size of goban.
|
|
||||||
creates postgresql table containing goban data.
|
|
||||||
returns: name of created table.
|
|
||||||
|
|
||||||
the table looks like this:
|
|
||||||
line x1
|
|
||||||
turn_number
|
|
||||||
size
|
|
||||||
name
|
|
||||||
description
|
|
||||||
player1
|
|
||||||
player2
|
|
||||||
sgf
|
|
||||||
created
|
|
||||||
lastmove
|
|
||||||
|
|
||||||
and the meaning of these fields:
|
|
||||||
(turn_number,x1) is the current turn,
|
|
||||||
(size,x1) is the length of a side of the goban,
|
|
||||||
(name,x1) is the name of this goban.
|
|
||||||
(description,x1) is the user-given name of this goban.
|
|
||||||
(player1,x1) is the name of one player.
|
|
||||||
(player2,x1) is the name of the other player.
|
|
||||||
(sgf,x1) contains a sgf file with the current board.
|
|
||||||
(created,x1) is the time of creation of the table
|
|
||||||
(lastmove,x1) is the time of the last player move
|
|
||||||
"""
|
|
||||||
tablename = helper.generate_game_name()
|
|
||||||
data="line text, x1 text"
|
|
||||||
create_table(tablename,data)
|
|
||||||
#now insert additional variables
|
|
||||||
insert_into_table(tablename,strtuple("turn_number","1"))
|
|
||||||
#size of goban
|
|
||||||
insert_into_table(tablename,strtuple("size",size))
|
|
||||||
#name of goban (=name of table in database)
|
|
||||||
insert_into_table(tablename,strtuple("name",tablename))
|
|
||||||
#description of goban (=user-given name)
|
|
||||||
insert_into_table(tablename,strtuple("description",description))
|
|
||||||
#name of player1
|
|
||||||
insert_into_table(tablename,strtuple("player1",player1))
|
|
||||||
#name of player2
|
|
||||||
insert_into_table(tablename,strtuple("player2",player2))
|
|
||||||
#empty sgf file as string
|
|
||||||
sgf = gnugo.create_sgf_file(size)
|
|
||||||
insert_into_table(tablename,strtuple("sgf",sgf))
|
|
||||||
#time of creation
|
|
||||||
insert_into_table(tablename,strtuple("created",str(int(time.time()))))
|
|
||||||
#time of last move
|
|
||||||
insert_into_table(tablename,strtuple("lastmove",str(int(time.time()))))
|
|
||||||
|
|
||||||
return tablename
|
|
||||||
|
|
||||||
def strtuple(s1,s2):
|
|
||||||
"""
|
|
||||||
creating a string looking like a tuple.
|
|
||||||
gets 2 strings.
|
|
||||||
useful for inserting something into a table.
|
|
||||||
"""
|
|
||||||
tmplist = []
|
|
||||||
tmplist.append(s1)
|
|
||||||
tmplist.append(s2)
|
|
||||||
return str(tuple(tmplist))
|
|
||||||
|
|
||||||
def create_user_table():
|
|
||||||
"""
|
|
||||||
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?
|
|
||||||
"""
|
|
||||||
data = "username varchar(15)"
|
|
||||||
data += ", password text"
|
|
||||||
for i in range(1,11):
|
|
||||||
data += ", game"+str(i)+" text"
|
|
||||||
data += ", sessionid text"
|
|
||||||
data += ", timeout int"
|
|
||||||
create_table("users",data)
|
|
||||||
|
|
||||||
def drop_table(name):
|
|
||||||
"""
|
|
||||||
gets: name of table.
|
|
||||||
executes DROP TABLE <name>
|
|
||||||
"""
|
|
||||||
executestring = "DROP TABLE %s;" % (name)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################# generic functions ############################################################################
|
|
||||||
|
|
||||||
def insert_into_table(table, content):
|
|
||||||
"""
|
|
||||||
gets the name of a table and a content string.
|
|
||||||
executes INSERT INTO name VALUES content;
|
|
||||||
"""
|
|
||||||
executestring = "INSERT INTO %s VALUES %s" % (table,content)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
|
|
||||||
|
|
||||||
def sql_one_liner(data):
|
|
||||||
"""
|
|
||||||
gets:SQL statement
|
|
||||||
creates a cursor, executes <statement>, closes cursor.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
def read_table(table):
|
|
||||||
"""
|
|
||||||
gets the name of a table, does a
|
|
||||||
SELECT * FROM table;
|
|
||||||
returns output.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data="SELECT * FROM %s;" % (table)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
ret = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update_database_field(table,column,new_value,uniqname,uniqvalue):
|
|
||||||
"""
|
|
||||||
wrapper for SQL UPDATE.
|
|
||||||
gets: table name
|
|
||||||
name of column containing field to be updated
|
|
||||||
new value of field in column
|
|
||||||
name of unique identifier and
|
|
||||||
value of unique identifier for field (e.g. 'username' and 'testuser')
|
|
||||||
"""
|
|
||||||
if new_value == "":
|
|
||||||
executestring ="UPDATE %s SET %s = DEFAULT WHERE %s = '%s'" % (table,column,uniqname,uniqvalue)
|
|
||||||
else:
|
|
||||||
executestring ="UPDATE %s SET %s = '%s' WHERE %s = '%s'" % (table,column,new_value,uniqname,uniqvalue)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
|
|
||||||
################# access of users table #####################################################################
|
|
||||||
|
|
||||||
def get_user_game_list(name):
|
|
||||||
"""
|
|
||||||
gets a username, returns the list of games for user.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
ret = []
|
|
||||||
for x in range(1,11):
|
|
||||||
data="SELECT game%s FROM users WHERE username = '%s'" % (x,name)
|
|
||||||
try:
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
ret.append(cursor.fetchone()[0]) #[0], because return is a list
|
|
||||||
except:
|
|
||||||
ret = "could not get info of all games -- table corrupt?"
|
|
||||||
cursor.close()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def get_user_info(name,infotype):
|
|
||||||
"""
|
|
||||||
gets the name of a user and the type of requested info.
|
|
||||||
returns info from database.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
if infotype in ("password","sessionid","timeout"):
|
|
||||||
|
|
||||||
data="SELECT %s FROM users WHERE username = '%s'" % (infotype,name)
|
|
||||||
try:
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
ret = cursor.fetchone()[0]
|
|
||||||
except:
|
|
||||||
ret = "no such user"
|
|
||||||
cursor.close()
|
|
||||||
else:
|
|
||||||
ret = "Are your sure about the infotype?"
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def set_user_sessionid(username,sessionid):
|
|
||||||
"""
|
|
||||||
gets username and sessionid, writes sessid into database
|
|
||||||
"""
|
|
||||||
update_users_table_field(username,"sessionid",sessionid)
|
|
||||||
|
|
||||||
def set_user_timeout(username,timeout=None):
|
|
||||||
"""
|
|
||||||
gets username, sets timeout to time.time + 30min
|
|
||||||
"""
|
|
||||||
import time
|
|
||||||
if timeout == None:
|
|
||||||
timeout = int(time.time()) + 900 #current time in seconds + seconds for session
|
|
||||||
update_users_table_field(username,"timeout",timeout)
|
|
||||||
|
|
||||||
def update_users_table_field(username,column,new_value):
|
|
||||||
"""
|
|
||||||
gets: username,column name, new content for field in column.
|
|
||||||
executes an update_database_field with uniqname = "username"
|
|
||||||
"""
|
|
||||||
update_database_field("users",column,new_value,"username",username)
|
|
||||||
|
|
||||||
|
|
||||||
def delete_user(username):
|
|
||||||
"""
|
|
||||||
gets username.
|
|
||||||
deletes user from database.
|
|
||||||
"""
|
|
||||||
#TODO: delete all games of user before delting user?
|
|
||||||
executestring ="DELETE FROM users WHERE username='%s'" %(username)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
return executestring
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def add_webgo_user(name,password):
|
|
||||||
"""
|
|
||||||
adds a database entry for a user.
|
|
||||||
gets: username and password
|
|
||||||
"""
|
|
||||||
#size of goban
|
|
||||||
tmplist=[]
|
|
||||||
tmplist.append(name)
|
|
||||||
tmplist.append(password)
|
|
||||||
insert_into_table("users",str(tuple(tmplist)))
|
|
||||||
|
|
||||||
def get_users_with_free_game_slots():
|
|
||||||
"""
|
|
||||||
gets nothing.
|
|
||||||
returns a list of all users who have at least one game slot free.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data = """select username from users where
|
|
||||||
(game1 IS NULL) OR (game2 IS NULL) OR (game3 IS NULL) OR
|
|
||||||
(game4 IS NULL) OR (game5 IS NULL) OR (game6 IS NULL) OR
|
|
||||||
(game7 IS NULL) OR (game8 IS NULL) OR (game9 IS NULL) OR
|
|
||||||
(game10 IS NULL)"""
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
tmplist = cursor.fetchall()
|
|
||||||
ret = [item[0] for item in tmplist]
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def get_free_game_slot(username):
|
|
||||||
"""
|
|
||||||
gets a username
|
|
||||||
returns the name of a free game slot or "" if none found.
|
|
||||||
"""
|
|
||||||
ret = ""
|
|
||||||
for i in range(1,11):
|
|
||||||
cursor=db.cursor()
|
|
||||||
data = "SELECT username FROM users WHERE username='%s' AND game%i IS NULL" % (username,i)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
tmp = [item[0] for item in cursor.fetchall()]
|
|
||||||
if (tmp != []):
|
|
||||||
ret = "game"+str(i)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def set_game_slot(username,gameslot,gamename):
|
|
||||||
"""
|
|
||||||
gets username,game slot,game name.
|
|
||||||
sets the game slot for user username to game name ;>
|
|
||||||
"""
|
|
||||||
if (gamename == "") or (gamename == None) or (gamename == "NULL") :
|
|
||||||
executestring ="UPDATE users SET %s = DEFAULT WHERE username = '%s'" %(gameslot, username)
|
|
||||||
else:
|
|
||||||
executestring ="UPDATE users SET %s = '%s' WHERE username = '%s'" %(gameslot,gamename, username)
|
|
||||||
sql_one_liner(executestring)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
################# access of goban tables ####################################################################
|
|
||||||
|
|
||||||
def get_players_for_game(tablename):
|
|
||||||
"""
|
|
||||||
gets the name of a goban table, returns player1 and player2 as tuple.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data="select x1 from %s where line='player1' OR line='player2';" % (tablename)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
players = [item[0] for item in cursor.fetchall()]
|
|
||||||
cursor.close()
|
|
||||||
return tuple(players)
|
|
||||||
|
|
||||||
|
|
||||||
def update_goban_table_field(table,column,line,new_value):
|
|
||||||
"""
|
|
||||||
gets: table name, column name, line name, new content for field.
|
|
||||||
executes an update_database_field with uniqname = "line"
|
|
||||||
"""
|
|
||||||
update_database_field(table,column,new_value,"line",line)
|
|
||||||
|
|
||||||
def update_turn_number(table,new_number):
|
|
||||||
"""
|
|
||||||
gets: name of table,new turn number
|
|
||||||
modifies 'turn_number' in table
|
|
||||||
"""
|
|
||||||
update_goban_table_field(table,"x1","turn_number",new_number)
|
|
||||||
|
|
||||||
def get_sgf(table):
|
|
||||||
"""
|
|
||||||
gets a table name,
|
|
||||||
returns content of "sgf" field.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data="select x1 from %s where line='sgf';" % (table)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
sgf = cursor.fetchone()[0]
|
|
||||||
cursor.close()
|
|
||||||
return sgf
|
|
||||||
|
|
||||||
def get_description(table):
|
|
||||||
"""
|
|
||||||
gets table name,
|
|
||||||
returns content of "description" field.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data="select x1 from %s where line='description';" % (table)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
sgf = cursor.fetchone()[0]
|
|
||||||
cursor.close()
|
|
||||||
return sgf
|
|
||||||
|
|
||||||
|
|
||||||
def fetchall_list_to_goban_dict(list):
|
|
||||||
"""
|
|
||||||
gets the output from read_table (a list),
|
|
||||||
returns a goban dictionary.
|
|
||||||
"""
|
|
||||||
#create dictionary
|
|
||||||
ret = {}
|
|
||||||
#get size of goban
|
|
||||||
for item in list:
|
|
||||||
if item[0] == "size":
|
|
||||||
size=int(item[1])
|
|
||||||
ret["size"] = size
|
|
||||||
#populate dictionary with goban field
|
|
||||||
for item in list:
|
|
||||||
if item[0][0] == "y": #goban fields
|
|
||||||
#get current y coordinate
|
|
||||||
y = int(item[0][1:])
|
|
||||||
#fill dictionary for current y coordinate
|
|
||||||
for x in range(1,size+1):
|
|
||||||
ret[(x,y)]=helper.check_for_int(item[x])
|
|
||||||
else: #other variables
|
|
||||||
ret[item[0]]=helper.check_for_int(item[1])
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def get_time(table,whichtime):
|
|
||||||
"""
|
|
||||||
gets:
|
|
||||||
- a table name,
|
|
||||||
- a string equal "created" or "lastmove".
|
|
||||||
returns either the time of creation or the time of the last player move for
|
|
||||||
the table, depending of whichtime.
|
|
||||||
"""
|
|
||||||
cursor=db.cursor()
|
|
||||||
data="select x1 from %s where line='%s';" % (table,whichtime)
|
|
||||||
cursor.execute(data)
|
|
||||||
# Commit the changes
|
|
||||||
db.commit()
|
|
||||||
try:
|
|
||||||
time = int(cursor.fetchone()[0])
|
|
||||||
except:
|
|
||||||
time = None
|
|
||||||
cursor.close()
|
|
||||||
return time
|
|
||||||
|
|
||||||
def set_time(tablename):
|
|
||||||
"""
|
|
||||||
gets name of goban table, sets lastmove to current time.
|
|
||||||
"""
|
|
||||||
update_goban_table_field(tablename,"x1","lastmove",int(time.time()))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test():
|
|
||||||
#create_table("test")
|
|
||||||
drop_table("test")
|
|
||||||
create_goban_table(9)
|
|
||||||
update_goban_table_field("test","x1","turn_number",4)
|
|
||||||
list = read_table("test")
|
|
||||||
print list
|
|
||||||
dict = fetchall_list_to_goban_dict(list)
|
|
||||||
print dict
|
|
||||||
print dict["turn_number"]
|
|
||||||
print dict["name"]
|
|
||||||
print type(dict["turn_number"])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#test()
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
<h2> Current Games: </h2>
|
<h2> Current Games: </h2>
|
||||||
<?cs if:Data.GamelistNotEmpty ?>
|
<?cs if:Data.GamelistNotEmpty ?>
|
||||||
<table><tr><td></td><td>Name of game</td><td>White</td>
|
<table><tr><td></td><td>Name of game</td><td>Black</td>
|
||||||
<td>Black</td><td>Time of Creation</td><td>Time of last move</td>
|
<td>White</td><td>Time of Creation</td><td>Time of last move</td>
|
||||||
<td></td></tr>
|
<td></td></tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
<?cs include:"templates/header.cs" ?>
|
<?cs include:"templates/header.cs" ?>
|
||||||
|
|
||||||
|
|
||||||
|
<?cs var:Data.Message ?><br>
|
||||||
|
Current Turn: <?cs var:Data.TurnNumber ?>.
|
||||||
|
<?cs if:(Data.Play == "black") ?> Black to move.<?cs elif:(Data.Play == "white") ?>White to move.<?cs /if ?>
|
||||||
|
<?cs if:(Data.MyTurn == "True") ?> Your Turn.<?cs /if ?>
|
||||||
|
<br>
|
||||||
|
|
||||||
<div id="board">
|
<div id="board">
|
||||||
|
|
||||||
<?cs var:Data.Message ?>
|
|
||||||
|
|
||||||
<?cs loop:x = #1, #Data.GobanSize, #1
|
<?cs loop:x = #1, #Data.GobanSize, #1
|
||||||
?><?cs loop:y = #1, Data.GobanSize, #1
|
?><?cs loop:y = #1, Data.GobanSize, #1
|
||||||
?><?cs
|
?><?cs
|
||||||
|
|
Loading…
Reference in a new issue