diff --git a/deletegame.py b/deletegame.py index c03a0f5..4636e33 100644 --- a/deletegame.py +++ b/deletegame.py @@ -1,15 +1,47 @@ -import psql +import psql,login def delete_game(gamename,username): """ get name of game and name of user. remove game from game slot of user. """ - -def main(gamename,req,form): +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 the name of a game,request,util.FieldStorage. manage the removal of game from game slots of players and delete game from database. - """ \ No newline at end of file + """ + req.write(str(form.keys())+" sessionid in form:"+form["sessionid"]+"
") + try: + gamename = form["game"] + except: + gamename = "" + if gamename != "": + #get player names from game table in database + players = psql.get_players_for_game(gamename) + #free game slots of players + for player in players: + gameslot = get_game_slot_of_game(player,gamename) + if gameslot != "": + psql.set_game_slot(player,gameslot,"") + + #delete table + psql.drop_table(gamename) + #now display game overview form. + login.game_overview_form(req,player,form["sessionid"]) + + else: + req.write('Error: You have to select a game to delete it!') \ No newline at end of file diff --git a/documentation/development/README_DEVEL b/documentation/development/README_DEVEL index 60a57d7..965b644 100644 --- a/documentation/development/README_DEVEL +++ b/documentation/development/README_DEVEL @@ -28,27 +28,10 @@ generate_goban_images.py coding guidelines tab == 4 whitespaces. function names are lowercase with _ as a seperator. ------------------------------------------- -some code snippets for reference: - - -How to make the goban clickable: - data += '
' - data += '' - #insert rest of goban here - data += '
' - print data - -How to extract the data from this POST with the cgi module: - import cgi - #get instance of fieldstorage - form = cgi.FieldStorage() - #if form == empty (which means if page is displayed for the first time): - if form.keys() != []: - #cut out the name of the clicked button - print string.split(form.keys()[0],".x")[0] - ------------------------------------------ known bugs: "DatabaseError: error 'ERROR: current transaction is aborted, commands ignored until end of transaction block" -seems to be a problem with mod_python and a cached database connection. /etc/init.d/apache2 restart helps. \ No newline at end of file +seems to be a problem with mod_python and a cached database connection. /etc/init.d/apache2 restart helps. + +in general: If you get an error message while coding and think you fixed the bug, but the error persists, try +reloading apache. \ No newline at end of file diff --git a/gamecreation.py b/gamecreation.py index 494b217..017fb77 100644 --- a/gamecreation.py +++ b/gamecreation.py @@ -48,13 +48,13 @@ def process_creation_form(req,form): gameslot = psql.get_free_game_slot(player) if gameslot != "": psql.set_game_slot(player,gameslot,gamename) - #TODO:game created, now display game overview form - login.game_overview_form(req,username,form["sessionid"]) else:#should not happen: no free game slot. #print error msg req.write("Error: No free game slots for player "+player+"!") #display form again display_game_creation_form(req,form["sessionid"],username) + #TODO:game created, now display game overview form + login.game_overview_form(req,username,form["sessionid"]) else: #give error message req.write("Sorry, you must be one of the players!
") @@ -106,4 +106,5 @@ def main(req,form): process_creation_form(req,form) else: display_game_creation_form(req,sessionid,username) + \ No newline at end of file diff --git a/init_webgo.py b/init_webgo.py index 700c3ae..335ce47 100755 --- a/init_webgo.py +++ b/init_webgo.py @@ -3,7 +3,6 @@ import psql def clear(): try: - psql.drop_table("test") psql.drop_table("users") except: pass diff --git a/login.py b/login.py index ca83768..af8c70c 100755 --- a/login.py +++ b/login.py @@ -17,7 +17,8 @@ def process_form(req,form): password = form["password"] sessionid = form["sessionid"] origpassword = psql.get_user_info(name,"password") - #check if user exists (else we would get an error string) + req.write('
--password:'+str(password)+' ---origpassword:'+str(origpassword)+'
') + #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 @@ -29,7 +30,7 @@ def process_form(req,form): req.write("Login incorrect. Please try again.
") req.write(login_form()) else: #no such user - req.write("Login incorrect. Please try again.
") + req.write("Login incorrect. Please try again.-
") req.write(login_form()) else: #one of (name,password) is missing: req.write("Please enter your name and password.") @@ -83,7 +84,7 @@ def game_overview_form(req,user,sessionid): if (psql.get_user_info(user,'timeout') >= int(time.time())) and (sessionid == psql.get_user_info(user,'sessionid')): req.write(data) else: - req.write(helper.header()+ 'your session timed out'+helper.footer()) + req.write('your session timed out. -- sessionid: '+sessionid+' --
') def login_form(): """ diff --git a/main.py b/main.py index 83b1df5..0341806 100755 --- a/main.py +++ b/main.py @@ -18,9 +18,6 @@ def handler(req): req.content_type = "text/html"#was:text/html try: # use explicit exception handling #reinitialize database - - #init_webgo.clear() - #init_webgo.create() #init_webgo.main() diff --git a/playgame.py b/playgame.py index bbe5204..9316bba 100644 --- a/playgame.py +++ b/playgame.py @@ -6,24 +6,30 @@ def main(req,form): """ req.write(str(form.keys())+"
") - gamename = form["game"] - #do stuff - data = helper.header() + try: + gamename = form["game"] + except: + gamename = "" + if gamename != "": + #do stuff + data = helper.header() - #read goban table from database - tmplist = psql.read_table(gamename) - #make a dictionary out of the list - gobandict = psql.fetchall_list_to_goban_dict(tmplist) - #print goban - #data += "

Turn number: %s, %s Player's Move.

" % (gobandict["turn_number"],("White","Black")[gobandict["turn_number"] % 2]) #eleet ;> - - #check whether its our turn - #if yes: print 'your move' and display goban and process move - #if not: print '...s move' and display goban. + #read goban table from database + tmplist = psql.read_table(gamename) + #make a dictionary out of the list + gobandict = psql.fetchall_list_to_goban_dict(tmplist) + #print goban + #data += "

Turn number: %s, %s Player's Move.

" % (gobandict["turn_number"],("White","Black")[gobandict["turn_number"] % 2]) #eleet ;> + + #check whether its our turn + #if yes: print 'your move' and display goban and process move + #if not: print '...s move' and display goban. - data += goban.display_goban(gobandict,req,form) - data += helper.footer() - req.write(data) - \ No newline at end of file + data += goban.display_goban(gobandict,req,form) + data += helper.footer() + req.write(data) + + else: + req.write('Error: You have to select a game to play it!') \ No newline at end of file diff --git a/psql.py b/psql.py index d309386..e7620c6 100755 --- a/psql.py +++ b/psql.py @@ -12,7 +12,7 @@ dbname="webgo" 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) @@ -30,39 +30,6 @@ def create_table(name,layout=""): executestring = "CREATE TABLE %s ( %s );" % (name,layout) sql_one_liner(executestring) - - -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 drop_table(name): - """ - gets: name of table. - executes DROP TABLE - """ - executestring = "DROP TABLE %s;" % (name) - sql_one_liner(executestring) - - -def sql_one_liner(data): - """ - gets:SQL statement - creates a cursor, executes , closes cursor. - """ - cursor=db.cursor() - cursor.execute(data) - # Commit the changes - db.commit() - cursor.close() - - def create_goban_table(player1,player2,size): """ gets:player1, player2, size of goban. @@ -133,7 +100,9 @@ def create_goban_table(player1,player2,size): tmplist.append(player2) insert_into_table(tablename,str(tuple(tmplist))) return tablename - + + + def create_user_table(): """ creates a table named users with following columns: @@ -153,7 +122,38 @@ def create_user_table(): data += ", timeout int" create_table("users",data) +def drop_table(name): + """ + gets: name of table. + executes DROP TABLE + """ + 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 , 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 @@ -169,6 +169,22 @@ def read_table(table): 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') + """ + 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. @@ -201,7 +217,7 @@ def get_user_info(name,infotype): cursor.execute(data) # Commit the changes db.commit() - ret = cursor.fetchone()[0] #[0], because return is a list + ret = cursor.fetchone()[0] except: ret = "no such user" cursor.close() @@ -213,8 +229,7 @@ def set_user_sessionid(username,sessionid): """ gets username and sessionid, writes sessid into database """ - executestring ="UPDATE users SET sessionid = '%s' WHERE username = '%s'" %(sessionid, username) - sql_one_liner(executestring) + update_users_table_field(username,"sessionid",sessionid) def set_user_timeout(username): """ @@ -222,31 +237,28 @@ def set_user_timeout(username): """ import time timeout = int(time.time()) + 900 #current time in seconds + seconds for session - executestring ="UPDATE users SET timeout = '%s' WHERE username = '%s'" %(timeout, username) + 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 update_database_field(table,column,line,data): - """ - gets: table name, column name, line name, new content for field. - executes an SQL UPDATE statement for line. - """ - executestring ="UPDATE %s SET %s = '%s' WHERE line = '%s'" %(table,column,data,line) - sql_one_liner(executestring) -def update_goban_field(table,x,y,content): - """ - gets: goban dictionary, x,y coordinates, new content for field. - modifies goban in database. - """ - update_database_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_database_field(table,"x1","turn_number",new_number) def add_webgo_user(name,password): """ @@ -259,32 +271,6 @@ def add_webgo_user(name,password): tmplist.append(password) insert_into_table("users",str(tuple(tmplist))) -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_users_with_free_game_slots(): """ gets nothing. @@ -311,30 +297,101 @@ def get_free_game_slot(username): ret = "" for i in range(1,11): cursor=db.cursor() - data = "SELECT username FROM users WHERE username='%s' AND game%s IS NULL" % (username,i) + 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 != []: + 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 ;> """ - executestring ="UPDATE users SET %s = '%s' WHERE username = '%s'" %(gameslot,gamename, username) + 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 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_database_field("test","x1","turn_number",4) + update_goban_table_field("test","x1","turn_number",4) list = read_table("test") print list dict = fetchall_list_to_goban_dict(list)