435 lines
11 KiB
Python
Executable file
435 lines
11 KiB
Python
Executable file
import helper,gnugo
|
|
import pgdb,sys
|
|
|
|
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):
|
|
"""
|
|
gets:player1, player2, size of goban.
|
|
creates postgresql table containing goban data.
|
|
returns: name of created table.
|
|
|
|
the table looks like this:
|
|
line x1 x2 x3 x4 ... x(size)
|
|
y1
|
|
y2
|
|
y3
|
|
...
|
|
y(size)
|
|
turn_number
|
|
size
|
|
name
|
|
player1
|
|
player2
|
|
sgf
|
|
|
|
and the meaning of these fields:
|
|
(xn,yn) is a field of the goban,
|
|
(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.
|
|
(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.
|
|
"""
|
|
tablename = helper.generate_game_name()
|
|
data="line text"
|
|
for i in range(1,size+1):
|
|
if data != "":
|
|
data += ", "
|
|
data += "x"+str(i) + ' text'
|
|
create_table(tablename,data)
|
|
#table created, now fill the table
|
|
for i in range(1,size+1):
|
|
tmplist=[]
|
|
tmplist.append("y"+str(i))
|
|
for k in range(1,size+1):
|
|
tmplist.append(0)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#ok, goban itself has been created and filled,
|
|
#now insert additional variables
|
|
tmplist=[]
|
|
tmplist.append("turn_number")
|
|
tmplist.append("1")
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#size of goban
|
|
tmplist=[]
|
|
tmplist.append("size")
|
|
tmplist.append(size)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#name of goban (=name of table in database)
|
|
tmplist=[]
|
|
tmplist.append("name")
|
|
tmplist.append(tablename)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#name of player1
|
|
tmplist=[]
|
|
tmplist.append("player1")
|
|
tmplist.append(player1)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#name of player2
|
|
tmplist=[]
|
|
tmplist.append("player2")
|
|
tmplist.append(player2)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
#empty sgf file as string
|
|
tmplist=[]
|
|
tmplist.append("sgf")
|
|
sgf = gnugo.create_sgf_file(size)
|
|
tmplist.append(sgf)
|
|
insert_into_table(tablename,str(tuple(tmplist)))
|
|
return tablename
|
|
|
|
|
|
|
|
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?"
|
|
return ret
|
|
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_goban_field(table,x,y,content):
|
|
"""
|
|
gets: goban dictionary, x,y coordinates, new content for field.
|
|
modifies goban in database.
|
|
"""
|
|
update_goban_table_field(table,"x"+str(x),"y"+str(y),content)
|
|
|
|
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 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 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()
|
|
|
|
|