diff --git a/createaccount.py b/createaccount.py index 31d93b3..4393509 100644 --- a/createaccount.py +++ b/createaccount.py @@ -1,79 +1,72 @@ import helper,database +#,database maxuser = 1000 -def display_create_form(req,form): - """ - gets a request object and a util.FieldStorage form. - writes a HTML page containing one name and two password fields. - """ - data = """ -
-

Your username:
-

-

Your Password:
-

-

Please retype your Password:
-

- - -

-
- """ % helper.generate_session_id() - req.write(data) -def process_form(req,form): - """ - gets a request object and a util.FieldStorage form. - Tries to read out username, password1 and password2 from form. - If all needed data is there, create the named user and return a 'success' - page. Else fail with detailed error. - """ - try: - password1 = form["password1"] - except: - password1 = "" - try: - password2 = form["password2"] - except: - password2 = "" - try: - username = form["username"] - except: - username = "" - if (username != "") and (password1 != "") and (password2 != "") and (password1 == password2): - 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:
" % username) - data = """ +""" + + +""" +class CreateAccount: + def index(self,username = None, password1 = None, password2 = None): + """ + checks if there are some parameters from the form. If not, displays creation form. Else processes form data + """ + if username != None and password1 != None and password2 != None: + return self.process_form(username,password1,password2) + else: + return self.display_create_form() + + + def display_create_form(self): + """ + returns a HTML page containing one name and two password fields. + """ + data = helper.header() + data += """
-

-

- -

+

Your username:
+

+

Your Password:
+

+

Please retype your Password:
+

+ + +

- """ % (username,password1,helper.generate_session_id()) - req.write(data) - else: - if username == "": - req.write("Please enter a username you would like to have.
") - if (password1 == "") or (password2 == "") or (password1 != password2): - req.write("Both given passwords have to be the same and non-empty.
") - display_create_form(req,form) - - -def main(req,form): + """ % helper.generate_session_id() + data += helper.footer() + return(data) - req.write(helper.header()) - helper.debug(req,form,str(form.keys())) - try: - createvalue = form["createaccount"] - except: - createvalue = "" - if createvalue == "process": - process_form(req,form) - else: - display_create_form(req,form) + def process_form(self,username, password1, password2): + """ + gets username, password1 and password2. + If all data is there and correct, create the named user and return a 'success' + page. Else fail with detailed error. + """ + data = helper.header() + if (password1 == password2): + #try: + #.add_webgo_user(username,password1) + newuser = database.Users(username=username,password=password1) + created_user = True + #except: + # #user already exists + # created_user = False + if created_user: + data += ('User %s has been successfully created. Click here to login.
' % username) + else: + data += ("User %s already exists. Please retry with another name." % username) + data += self.display_create_form() + else: + if (password1 == "") or (password2 == "") or (password1 != password2): + data += ("Both given passwords have to be the same and non-empty.
") + data += self.display_create_form() + data += helper.footer() + return data + index.exposed = True - req.write(helper.footer(req,form)) \ No newline at end of file + \ No newline at end of file diff --git a/database.py b/database.py index ac1ca5f..7ad5e50 100644 --- a/database.py +++ b/database.py @@ -39,7 +39,7 @@ class GobanTable(SQLObject): player1 = StringCol() player2 = StringCol() size = IntCol() - name = StringCol(default = helper.generate_game_name(), unique=True,notNone=True,alternateID=True) + #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) @@ -54,13 +54,8 @@ class GobanTable(SQLObject): """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) @@ -155,16 +150,19 @@ class Users(SQLObject): 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) + idlist = list(Users.select()) retlist = [] + for entry in idlist: - retlist.append(Users.get(entry).username) + if entry.free_slot_left() == True: + retlist.append(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) +GobanTable.createTable(ifNotExists=True) if __name__ == "__main__": connection_string='sqlite:%s?%s' %(os.path.abspath("webgo.sqlite"),dbdebug) connection=connectionForURI(connection_string) diff --git a/gamecreation.py b/gamecreation.py index 4113327..8ab36f9 100644 --- a/gamecreation.py +++ b/gamecreation.py @@ -1,79 +1,9 @@ -from mod_python import * import helper,login,database +from cherrypy import cpg +from cherrypy.lib import httptools -def display_game_creation_form(req,form): - """ - prints a html form with multiple drop-down lists for choosing players, - goban size and so on. - gets a mod_python request, prints to req.write. - """ - username = form["username"] - sessionid = form["sessionid"] - - data = helper.header() - p1data = create_user_dropdown_list("player1",username) - p2data = create_user_dropdown_list("player2") - gobansize = create_goban_size_dropdown_list("gobansize") - #start form - #choose player one (black),choose player two (white),choose goban size - #'hidden' session id and username - data += """ -
-

Player One (Black): %s

-

Player Two (White): %s

-

Goban Size: %s fields

-

Optional name for game:

- - - -
- """ % (p1data,p2data,gobansize,sessionid,username) - - - - data+=helper.footer(req,form) - req.write(data) - -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"] - username = form["username"] - try: - description = form["description"] - except: - description = "" - helper.debug(req,form,"game creation: will use '%s' as description." % description) - - #check if at least one of the players is the current user - if (player1 == username) or (player2 == username): - #create game - 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]: - 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+"!") - #display form again - display_game_creation_form(req,form["sessionid"],username) - #TODO:game created, now display game overview form - login.game_overview_form(req,form) - else: - #give error message - req.write("Sorry, you must be one of the players!
") - #display form again - display_game_creation_form(req,form["sessionid"],username) def create_user_dropdown_list(listname,selected = ""): """ @@ -105,20 +35,87 @@ def create_goban_size_dropdown_list(listname): """ % listname return data -def main(req,form): +class GameCreation: """ - display and process forms for game creation. - gets a request object and a util.FieldStorage form. - returns nothing. + manages the creation of games. """ - req.write(str(form.keys())+"
") - - username = form["username"] - #TODO:check if valid session id - sessionid = form["sessionid"] - if "gobansize" in form.keys(): #user already clicked on create - process_creation_form(req,form) - else: - display_game_creation_form(req,form,) + def index(self,player1 = None, player2 = None, description = None,gobansize = None): + username = cpg.request.sessionMap["username"] + myuser = database.Users.byUsername(username) + sessionid = cpg.request.sessionMap["_sessionId"] + if myuser.sessionid == sessionid: + if player1 != None and player2 != None and gobansize != None: + return self.process_creation_form(player1,player2,gobansize,description) + else: + return self.display_game_creation_form() + + else: + httptools.redirect("/login") + + def display_game_creation_form(self): + """ + prints a html form with multiple drop-down lists for choosing players, + goban size and so on. - \ No newline at end of file + """ + username = cpg.request.sessionMap["username"] + myuser = database.Users.byUsername(username) + sessionid = cpg.request.sessionMap["_sessionId"] + + + data = helper.header() + p1data = create_user_dropdown_list("player1",username) + p2data = create_user_dropdown_list("player2") + gobansize = create_goban_size_dropdown_list("gobansize") + #start form + #choose player one (black),choose player two (white),choose goban size + data += """ +
+

Player One (Black): %s

+

Player Two (White): %s

+

Goban Size: %s fields

+

Optional name for game:

+ +
+ """ % (p1data,p2data,gobansize) + data += helper.footer() + return data + + def process_creation_form(self,player1,player2,gobansize,description=None): + """ + 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. + """ + username = cpg.request.sessionMap["username"] + myuser = database.Users.byUsername(username) + sessionid = cpg.request.sessionMap["_sessionId"] + + data = helper.header() + #check if at least one of the players is the current user + if (player1 == username) or (player2 == username): + #create game + mygame = database.GobanTable(player1=player1,player2=player2,size=gobansize,description = description) + gamename = mygame.id + #update entries for player one and player two + for player in [player1,player2]: + 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 + data += "Error: No free game slots for player %s!
" % player + #display form again + return self.display_game_creation_form() + + httptools.redirect("/overview") + else: + #give error message + data += "Sorry, you must be one of the players!
" + #display form again + return self.display_game_creation_form() + + data+=helper.footer(req,form) + return data + index.exposed = True \ No newline at end of file diff --git a/helper.py b/helper.py index b028c0f..1ebb761 100644 --- a/helper.py +++ b/helper.py @@ -12,7 +12,7 @@ def header(): - +

WebGo

@@ -31,7 +31,7 @@ def debug(req,form, optstr = ""): else: req.write("Debug: "+optstr+"
\n") -def footer(req,form,display_buttons=0): +def footer(display_buttons=0): """return html footer""" try: username=form["username"] @@ -63,11 +63,7 @@ def generate_session_id(): def generate_game_name(): from whrandom import choice - chars = string.letters - name = '' - for i in range(16): - name = name + choice(chars) - return name.lower() + return generate_session_id() def check_for_int(data): diff --git a/login.py b/login.py index 334321b..6f99b48 100755 --- a/login.py +++ b/login.py @@ -1,143 +1,27 @@ -import database,init_webgo,helper,gamecreation +#import database,init_webgo,helper,gamecreation +import helper,database from sets import Set as set -from mod_python import * - -def process_form(req,form): - """ - reads username and password from form - """ - #req.write("
"+"name="+form['name']+", password="+form['password']+"
") - if form.keys() != []: - 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 = myuser.password - #debug: - helper.debug(req,form,'
--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 - myuser.sessionid = sessionid - myser.set_timeout() - #now display list of games. - game_overview_form(req,form) - else: - req.write("Login incorrect. Please try again.
") - req.write(login_form(req,form)) - else: #no such user - req.write("Login incorrect. Please try again.-
") - req.write(login_form(req,form)) - else: #one of (name,password) is missing: - req.write("Please enter your name and password.") - req.write(login_form(req,form)) +from cherrypy import cpg +from cherrypy.lib import httptools +""" -def game_overview_form(req,form): - """ - gets: request object, util.FieldStorage form, name of user, sessionid. - prints a form with the option to select,create and delete games. - """ - username = form["username"] - sessionid = form["sessionid"] - - - data = helper.header()+ """ -

Current Games:

- - """ - gamelist = myuser.gamelist() - #debug - helper.debug(req,form,str(gamelist)+"
\n") - #display list of current games - counter = 10 - len(helper.clean_list(gamelist)) - tmp = "" - if helper.clean_list(gamelist) != []: - tmp += "" - tmp += "" - tmp += "" - for item in set(helper.clean_list(gamelist)): - if (item != None) and (item != "None"): - tmp += '\n' - tmp += '\n' % sessionid - tmp += '\n' % username - tmp += '\n' % item - tmp += '\n' - mygame = database.GobanTable.byName(item) - description = mygame.description - if (description == None) or (description == "None") or (description == ""): - description = item - tmp += '\n' % description - players = mygame.players() - tmp += '\n' % players[0] - tmp += '\n' % players[1] - tmp += '\n' % helper.format_time(mygame.created) - tmp += '\n' % helper.format_time(mygame.lastmove) - tmp += '\n' - tmp += '\n' - if helper.clean_list(gamelist) != []: - tmp += '
Name of gameWhiteBlackTime of CreationTime of last move
%s%s%s%s%s
' - - if gamelist == []: #no current games - data += "You don't have any running games.\n" - else: - - data += tmp - #now comes the option for creating new games. - data += "

New Game:

\n" - if counter > 0: - data+= "You have %s free game slots.
" % counter - data += """ -
- - - -
- """ % (sessionid, username) - else: - data+= "Sorry, all your game slots are in use." - data+=helper.footer(req,form,1) - req.write(data) - -def login_form(req,form): - """ - print welcome message and html form. - """ - - data = helper.header() + """ -
-

Name:
-

-

Password:
-

- -

-
-
- - -
- """ % helper.generate_session_id() - data += helper.footer(req,form) - return data +""" +""" 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=""" + data=" ""
@@ -146,15 +30,15 @@ def navigation_bar(req,form):
- """ % (username,sessionid,game) + "" " % (username,sessionid,game) return(data) def logout(req,form): - """ + "" " gets request object and util.FieldStorage form. reads username from form and clears timeout and sessionid from users table. - """ + "" " username = form["username"] myuser = database.Users.byUsername(username) myuser.sessionid = "" @@ -174,3 +58,127 @@ def main(req,form): process_form(req,form) else: process_form(req,form) +""" +class Login: + def index(self,username=None,password=None): + """ + Without arguments, this function writes a login form. Else the login data is evaluated + and the user is eventually logged in. + """ + if username == None and password == None: + return self.login_form() + else: + return self.process_form(username,password) + + def login_form(self): + """ + print welcome message and html form. + """ + + data = helper.header() + data += """ +
+

Name:
+

+

Password:
+

+

+
+ create account
+ """ + data += helper.footer() + return data + + def process_form(self,username,password): + """ + gets username and password, checks for validity, eventually the user is logged in. + TODO: check for session timeout + """ + data = helper.header() + sessionid = cpg.request.sessionMap["_sessionId"] + + myuser = database.Users.byUsername(username) + origpassword = myuser.password + if password == origpassword: + #login accepted + myuser.sessionid = sessionid + myuser.set_timeout() + cpg.request.sessionMap["username"] = username + #now display list of games. + httptools.redirect("/overview") + #data += "Login accepted." + else: + data += "Login incorrect. Please try again.
" + data += self.login_form() + data += helper.footer() + return data + + + + + index.exposed=True + +class Overview: + """ + give out a list of current games and stuff.""" + def index(self): + username = cpg.request.sessionMap["username"] + myuser = database.Users.byUsername(username) + sessionid = cpg.request.sessionMap["_sessionId"] + if myuser.sessionid == sessionid: + return self.game_overview_form(username) + else: + return "You must be logged in to access this page." + + def game_overview_form(self,username): + """ + gets:name of user, + prints a form with the option to select,create and delete games. + """ + myuser = database.Users.byUsername(username) + data = helper.header()+ """ +

Current Games:

+ + """ + gamelist = myuser.gamelist() + #display list of current games + counter = 10 - len(helper.clean_list(gamelist)) + tmp = "" + if helper.clean_list(gamelist) != []: + tmp += "" + tmp += "" + tmp += "" + for item in helper.clean_list(gamelist): + if (item != None) and (item != "None"): + tmp += '\n' + tmp += '\n' % username + tmp += '\n' % item + tmp += '\n' + mygame = database.GobanTable.get(item) + description = mygame.description + if (description == None) or (description == "None") or (description == ""): + description = item + tmp += '\n' % description + players = mygame.players() + tmp += '\n' % players[0] + tmp += '\n' % players[1] + tmp += '\n' % helper.format_time(mygame.created) + tmp += '\n' % helper.format_time(mygame.lastmove) + tmp += '\n' + tmp += '\n' + if helper.clean_list(gamelist) != []: + tmp += '
Name of gameWhiteBlackTime of CreationTime of last move
%s%s%s%s%s
' + if gamelist == []: #no current games + data += "You don't have any running games.\n" + else: + data += tmp + #now comes the option for creating new games. + data += "

New Game:

\n" + if counter > 0: + data+= "You have %s free game slots.
" % counter + data += ' Start a new game
' + else: + data+= "Sorry, all your game slots are in use." + data+=helper.footer() + return data + index.exposed = True \ No newline at end of file diff --git a/main.py b/main.py index fe5f512..fd94ff9 100755 --- a/main.py +++ b/main.py @@ -1,110 +1,29 @@ import sys, traceback,string,time -import init_webgo,database +import login,createaccount,helper,gamecreation +from cherrypy import cpg -from mod_python import * +class WebGoSite: + def index(self): + data = helper.header() + data += """ This is WebGo.
+ login
+ create an account
+ """ + data += helper.footer() + return data + index.exposed = True +cpg.root = WebGoSite() +cpg.root.createaccount = createaccount.CreateAccount() +cpg.root.login = login.Login() +cpg.root.overview = login.Overview() +cpg.root.gamecreation = gamecreation.GameCreation() -DEBUG = 1 - - -def handler(req): - # "Content-type: text/html\n\n" - req.content_type = "text/html"#was:text/html - try: # use explicit exception handling - #reinitialize database - #init_webgo.main() - - - #load form, then delegate request - form = util.FieldStorage(req) - try: - sessionid=form["sessionid"] - username=form["username"] - except: - sessionid="" - 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) - elif "delete" in form.keys(): - 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: - #call login.py - login = apache.import_module("login") - login.main(req,form) - else: - if "createaccount" in form.keys(): - createaccount = apache.import_module("createaccount") - createaccount.main(req,form) - else:#call login.py - login = apache.import_module("login") - login.main(req,form) - - - return apache.OK - except: - errtime = '----- '+ time.ctime(time.time()) +' -----\n' - errlog = open('/tmp/cgi_errors.log', 'a') - errlog.write(errtime) - errlog.write(ErrorMsg()) - data = """CGI Error Encountered! -

Sorry, a problem was encountered running WebGo.

-

Please check the error log on the server for details.

-
"""
-		data += ErrorMsg()
-		data+="
\n" - req.write(data) - return apache.OK - - - - -def ErrorMsg(escape=0): - """ - returns: string - - simualtes the traceback output and if argemument - set to 1 (true) the string will be - converted to fit into html documents without problems. - from Dirk Holtwick - """ - import traceback, sys, string - - type=None - value=None - tb=None - limit=None - type, value, tb = sys.exc_info() - body = "Traceback (innermost last):\n" - list = traceback.format_tb(tb, limit) + traceback.format_exception_only(type, value) - body = body + "%-20s %s" % ( - string.join(list[:-1], ""), - list[-1], - ) - if escape: - import cgi - body = cgi.escape(body) - return body +cpg.server.start(configMap={'sessionStorageType' : 'ram', + 'sessionCookieName' : 'WebGoSessionCookie', + 'sessionTimeout' : 15, #Session expires in n minutes + + 'staticContentList': + [['default.css','default.css']] + } + )