diff --git a/default.css b/default.css new file mode 100644 index 0000000..7bcc1d7 --- /dev/null +++ b/default.css @@ -0,0 +1,373 @@ +body { + background-position: top center; + background-attachment: fixed; + background-repeat: no-repeat; + text-align: center; + margin: 0; + padding: 0; + font-family: verdana, lucida, arial, helvetica, sans-serif; + } + +#main { + background: none; + width: 600px; + padding: 0px; + margin-left: auto; + margin-right: auto; + } + +#main h1, h2, h3 { + font-family: sans-serif, arial; + font-weight: normal; + letter-spacing: 0.05em; + color: #acacac; + font-variant: small-caps; + padding: 0 1em; + text-align: left; + } + +#main h1 { + font-size: 2em; + } + +#main h2 { + font-size: 1.5em; + } + +#main h3 { + font-size: 1.2em; + } + +#head { + width: 600px; + height: 120px; + margin: 0; + padding: 0; + background-image: url(cryptobox-img/vault_pingu.png); + background-position: top right; + background-attachment: scroll; + background-repeat: no-repeat; + } + +#content { + margin: 0; + padding: 0; + width: 600px; + font-size: 0.9em; + } + +#content a { + line-height: 1.2em; + color: #000000; + text-decoration: none; + font-weight: bold; + font-size: 0.9em; + } + +#content a:hover { + text-decoration: underline; + } + +#content a:visited { + color: #acacac; + } + +#content p { + font-size: 0.9em; + padding: 0 1em; + text-align: justify; + } + +#menu { + text-align: center; + border-top: 1px solid #5e5e5e; + border-bottom: 1px solid #5e5e5e; + background-color: #ACE149; + } + +#menu a:link, #menu a:visited { + color: #5e5e5e; + margin: 5px; + text-decoration: none; + border: none; + padding: 4px; + font-size: 0.8em; + } + +#menu a:hover { + color: #8e8e8e; + } + +#words { + width: 565px; + padding: 1.1em 0em 1.1em 1.1em; + margin-top: 0; + } + +#words h1{ + font-size: 1.8em; + } + +#words h2{ + font-size: 1.4em; + } + +#words ol, #words ul { + font-size: 0.9em; + } + +#words ol li { + padding: 0 1em; + line-height: 1.7em; + } + +#words ul li { + padding: 0 1em; + line-height: 1.7em; + list-style: none; + background: url(cryptobox-img/list.gif) center left no-repeat; + } + +#footer { + clear: both; + text-align: center; + border-top: 1px solid #5e5e5e; + border-bottom: 1px solid #5e5e5e; + background-color: #ACE149; + font-size: 0.8em; + color: #5e5e5e; + } + +#footer a:link, #footer a:visited { + color: white; + margin: 5px; + text-decoration: none; + border: none; + padding: 4px; + color: #5e5e5e; + } + +#footer a:hover { + text-decoration: underline; + } + +#confirmtext span { + color: red; + font-weight: bold; + } + + +/* -------=-=-=- warnings, errors and success messages-=-=-=-------- */ + +#words div.warning,div.error,div.success { + margin-top: 20px; + margin-bottom: 20px; + padding-top: 10px; + padding-bottom: 15px; + color: #707070; + } + +#words .warning,.error,.success { + border: 1px dashed #808080; + text-align: center; + color: #5e5e5e; + text-decoration: none; + font-weight: bold; + font-size: 0.9em; + padding-left: 40px; + padding-right: 40px; + } + +#words .warning { + background-color: #f5f5f5; + } + +#words .error { + background-color: #f5f5f5; + } + +#words .success { +/* background-color: #90EE90; */ + } + +#words div.warning,div.error,div.success h1,h2 { + color: #808080; + } + +#words .warning,.error,.success a { +// TODO: WHY line-height??? +// line-height: 5em; + color: #5e5e5e; + text-decoration: none; + font-weight: bold; + font-size: 0.9em; +} + +#words .note { + text-align: center; + color: #F48659; + font-style: italic; + } + +/* ----------------------=-=-=- Forms -=-=-=--------------------- */ +/* pretty forms and buttons */ +input { + border: 1px solid #333333; + color: #333333; + background: #fff; + padding: 2px 5px 1px 5px; + font-size: 1em; + + } + +input:hover { + background: #fff; + border: 1px solid #ACE149; + color: #7DA721; + font-size: 1em; + + } + +textarea { + font-family: arial, verdana, helvetica; + font-size: 1.1em; + border: 1px solid #BFBFBF; + color: #949494; + padding: 2px 5px 1px 5px; + width: 450px; + + } + +textarea:hover { + background: #fff; + border: 1px solid #ACE149; + color: #7DA721; + + } +/* the submit buttons have to have id="submit" for the following style: ------------------------------------- */ +input#submit { + background-color: #ACE149; + border: 1px solid #222222; + color: #222; + font-size: 0.8em; + font-weight: bold; + cursor: pointer; + } + +input#submit:hover { + background-color: #fff; + border: 1px solid #222; + color: #222; + font-size: 0.8em; + font-weight: bold; + cursor: pointer; + } +/* the submit buttons have to have id="goban" for the following style, for use in goban display ------------- */ +input#goban { + padding: 0px; + border: 0px; + cursor: pointer; + } + + + +#words form label { + min-width: 20em; + } + +#words form p { + text-align: center; + } + +/* ------------=-=-=- language selection -=-=-=------------- */ + +#lang { + position: fixed; + float: right; + right: 5px; + top: 5px; + text-align: right; + } + +#lang a { + color: #acacac; + font-family: verdana, lucida, arial, helvetica, sans-serif; + font-size: smaller; + } + +#lang a:hover { + color: #707070; + } + + +/* ------------=-=-=- documentation -=-=-=------------- */ + +#doc ol,ul li { + text-align: left; + margin-left: 20px; + } + +#doc dl dt { + text-align: left; + margin-left: 20px; + font-style: italic; + } + +#doc h1 { + padding-top: 25px; +} + +#doc h2 { + padding-top: 20px; +} + +#doc h3 { + padding-top: 10px; + } + +/* ------------=-=-=- special things -=-=-=------------- */ + +#partition_info p { + margin-left: 10%; + margin-right: 10%; + font-family: monospace + } + +#words a.popup { + line-height: inherit; + color: inherit; + text-decoration: inherit; + font-weight: inherit; + font-size: inherit; + } + +#words a.popup:hover { + text-decoration: inherit; + } + +#words a.popup span { + display: none; + position: fixed; + bottom: 10px; + left: 9%; + width: 80%; + background: #f0f0f0; + padding: 10px; + border-color: #e0e0e0; + border-width: 2px; + border-style: solid; + margin: 0; + } + +#words a.popup:hover span { + display: inline; + } + +#words a.popup span p { + text-align: left; + } + +#words a.popup span h3 { + color: #909090; + margin-top: 0px; + } diff --git a/deletegame.py b/deletegame.py index 4636e33..d14f7fb 100644 --- a/deletegame.py +++ b/deletegame.py @@ -1,5 +1,7 @@ import psql,login +DEBUG = 1 + def delete_game(gamename,username): """ get name of game and name of user. @@ -24,7 +26,8 @@ def main(req,form): manage the removal of game from game slots of players and delete game from database. """ - req.write(str(form.keys())+" sessionid in form:"+form["sessionid"]+"
") + if DEBUG: + req.write(str(form.keys())+" sessionid in form:"+form["sessionid"]+"
") try: gamename = form["game"] except: @@ -41,7 +44,7 @@ def main(req,form): #delete table psql.drop_table(gamename) #now display game overview form. - login.game_overview_form(req,player,form["sessionid"]) + login.game_overview_form(req,form,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/DATABASE b/documentation/development/DATABASE new file mode 100644 index 0000000..a2446cd --- /dev/null +++ b/documentation/development/DATABASE @@ -0,0 +1,16 @@ +this file describes the database of the game. +there are currently 2 types of tables in the game. + +One is the user table. this table is unique. +do the following to get the details: +cd webgo +python +import psql +print psql.create_user_table.__doc__ + +the other one is a goban table. for each game there exists one goban +table. do the following to get the details: +cd webgo +python +import psql +print psql.create_goban_table.__doc__ diff --git a/documentation/development/README b/documentation/development/README new file mode 100644 index 0000000..07809be --- /dev/null +++ b/documentation/development/README @@ -0,0 +1 @@ +this is webgo, a browser-based version of go. diff --git a/gamecreation.py b/gamecreation.py index 017fb77..6c4c658 100644 --- a/gamecreation.py +++ b/gamecreation.py @@ -1,6 +1,8 @@ from mod_python import * import psql,helper,login +DEBUG = 1 + def display_game_creation_form(req,sessionid,username): """ prints a html form with multiple drop-down lists for choosing players, @@ -21,7 +23,7 @@ def display_game_creation_form(req,sessionid,username):

Goban Size: %s fields

- + """ % (p1data,p2data,gobansize,sessionid,username) @@ -54,7 +56,7 @@ def process_creation_form(req,form): #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"]) + login.game_overview_form(req,form,username,form["sessionid"]) else: #give error message req.write("Sorry, you must be one of the players!
") @@ -97,7 +99,8 @@ def main(req,form): gets a request object and a util.FieldStorage form. returns nothing. """ - req.write(str(form.keys())+"
") + if DEBUG: + req.write(str(form.keys())+"
") username = form["username"] #TODO:check if valid session id diff --git a/generate_goban_images.py b/generate_goban_images.py index 2993d12..16e1357 100755 --- a/generate_goban_images.py +++ b/generate_goban_images.py @@ -2,7 +2,7 @@ """ a simple script using pil to generate the goban from background, grid and stone images. """ -import Image +import Image,ImageOps gridlist = ["bottomleftline","bottomline","bottomrightline", "centerline","hoshi","leftline","rightline", "topleftline", "topline","toprightline"] @@ -15,11 +15,13 @@ for item in gridlist: bg = Image.open("imgsource/background.png").convert("RGBA") img = Image.open("imgsource/"+item+".png").convert("RGBA") bg.paste(img,None,img) + #bg = Image.composite(img,bg,img) bg.save("img/"+item+".png") - tmp = bg #for the black stones + tmp = bg #for the white stones + tmp2 = bg #for the black stones #filling with white stones - bg.paste(whitestone,None,whitestone) - bg.save("img/"+item+"_white.png") + tmp.paste(whitestone,None,whitestone) + tmp.save("img/"+item+"_white.png") #filling with black stones - tmp.paste(blackstone,None,blackstone) - tmp.save("img/"+item+"_black.png") + tmp2.paste(blackstone.convert("RGB"),None,blackstone) + tmp2.save("img/"+item+"_black.png") diff --git a/goban.py b/goban.py index 53c65d5..65ccb8b 100755 --- a/goban.py +++ b/goban.py @@ -1,5 +1,6 @@ #!/usr/bin/python +DEBUG = 1 import sys,string import cgi @@ -24,7 +25,7 @@ def display_goban(goban,req,form): hoshis9x9 = [(3,3),(3,7),(5,5),(7,3),(7,7)] - data += '
' + data += '

' data += """ @@ -49,30 +50,30 @@ def display_goban(goban,req,form): sy = str(y) # check position: if (x == 1) and (y == 1): # upper left - data += '' + data += '' elif (x == 1) and (y == size): # upper right - data += '
' + data += '
' elif (x == size) and (y == size): # lower right - data += '
' + data += '
' elif (x == size) and (y == 1): # lower left - data += '' + data += '' elif (y == 1): #left line - data += '' + data += '' elif (x == 1): # top line - data += '' + data += '' elif (y == size): # right line - data += '
' + data += '
' elif (x == size): #bottom line - data += '' + data += '' else: # hoshi or empty inner field - defaultfield = '' + defaultfield = '' #too lazy to make special images for hoshi fields with stones: if goban[(x,y)] == 1: - hoshifield = '' + hoshifield = '' elif goban[(x,y)] == 2: - hoshifield = '' + hoshifield = '' else: #empty hoshi - hoshifield = '' + hoshifield = '' if size == 19: # 9 hoshis if (x,y) in hoshis19x19: data += hoshifield @@ -89,7 +90,7 @@ def display_goban(goban,req,form): else: data += defaultfield data += '\n' - data += '\n

' + data += '\n

' return data diff --git a/helper.py b/helper.py index 033fa33..6c523a7 100644 --- a/helper.py +++ b/helper.py @@ -1,14 +1,39 @@ import string +DEBUG = 1 + def header(): """return html header""" data = """ - - - + + + + + + WebGo + + + + + + + +

WebGo

""" return data +def debug(req,form, optstr = ""): + """ + print various debug infos, e.g. form content. + gets request, util.FieldStorage form, optional extra string. + returns nothing, writes with request.write. + """ + if DEBUG: + if optstr == "": + req.write(str(form.keys())) + else: + req.write(optstr) + def footer(): """return html footer""" data = """ diff --git a/img/bottomleftline_black.png b/img/bottomleftline_black.png index a045992..a152200 100644 Binary files a/img/bottomleftline_black.png and b/img/bottomleftline_black.png differ diff --git a/img/bottomleftline_white.png b/img/bottomleftline_white.png index c052c28..96f0583 100644 Binary files a/img/bottomleftline_white.png and b/img/bottomleftline_white.png differ diff --git a/img/bottomline_black.png b/img/bottomline_black.png index 85f86d5..cfe37f6 100644 Binary files a/img/bottomline_black.png and b/img/bottomline_black.png differ diff --git a/img/bottomline_white.png b/img/bottomline_white.png index edadbfd..f6ee31f 100644 Binary files a/img/bottomline_white.png and b/img/bottomline_white.png differ diff --git a/img/bottomrightline_black.png b/img/bottomrightline_black.png index a30627d..f3b1fc9 100644 Binary files a/img/bottomrightline_black.png and b/img/bottomrightline_black.png differ diff --git a/img/bottomrightline_white.png b/img/bottomrightline_white.png index 2259f54..504e921 100644 Binary files a/img/bottomrightline_white.png and b/img/bottomrightline_white.png differ diff --git a/img/centerline_black.png b/img/centerline_black.png index a3aa587..050be39 100644 Binary files a/img/centerline_black.png and b/img/centerline_black.png differ diff --git a/img/centerline_white.png b/img/centerline_white.png index 3eb550a..2763511 100644 Binary files a/img/centerline_white.png and b/img/centerline_white.png differ diff --git a/img/hoshi_black.png b/img/hoshi_black.png index a3aa587..050be39 100644 Binary files a/img/hoshi_black.png and b/img/hoshi_black.png differ diff --git a/img/hoshi_white.png b/img/hoshi_white.png index 3eb550a..2763511 100644 Binary files a/img/hoshi_white.png and b/img/hoshi_white.png differ diff --git a/img/leftline_black.png b/img/leftline_black.png index 0f924ed..c2d5142 100644 Binary files a/img/leftline_black.png and b/img/leftline_black.png differ diff --git a/img/leftline_white.png b/img/leftline_white.png index 514e7a5..d2ff592 100644 Binary files a/img/leftline_white.png and b/img/leftline_white.png differ diff --git a/img/rightline_black.png b/img/rightline_black.png index db9ec99..6551b10 100644 Binary files a/img/rightline_black.png and b/img/rightline_black.png differ diff --git a/img/rightline_white.png b/img/rightline_white.png index 70f1e6e..f105bef 100644 Binary files a/img/rightline_white.png and b/img/rightline_white.png differ diff --git a/img/topleftline_black.png b/img/topleftline_black.png index 4ef0fe7..4949581 100644 Binary files a/img/topleftline_black.png and b/img/topleftline_black.png differ diff --git a/img/topleftline_white.png b/img/topleftline_white.png index f52577d..5fffd6d 100644 Binary files a/img/topleftline_white.png and b/img/topleftline_white.png differ diff --git a/img/topline_black.png b/img/topline_black.png index 4f2d4c8..0898803 100644 Binary files a/img/topline_black.png and b/img/topline_black.png differ diff --git a/img/topline_white.png b/img/topline_white.png index b24c02b..ed1d293 100644 Binary files a/img/topline_white.png and b/img/topline_white.png differ diff --git a/img/toprightline_black.png b/img/toprightline_black.png index eafa497..42e666b 100644 Binary files a/img/toprightline_black.png and b/img/toprightline_black.png differ diff --git a/img/toprightline_white.png b/img/toprightline_white.png index 1f2df2a..624544b 100644 Binary files a/img/toprightline_white.png and b/img/toprightline_white.png differ diff --git a/imgsource/blackstone.png b/imgsource/blackstone.png index 209f381..d59caec 100644 Binary files a/imgsource/blackstone.png and b/imgsource/blackstone.png differ diff --git a/imgsource/whitestone.png b/imgsource/whitestone.png index aaa5d3d..2d602f9 100644 Binary files a/imgsource/whitestone.png and b/imgsource/whitestone.png differ diff --git a/init_webgo.py b/init_webgo.py index 335ce47..3e0113f 100755 --- a/init_webgo.py +++ b/init_webgo.py @@ -1,6 +1,5 @@ import psql - def clear(): try: psql.drop_table("users") diff --git a/login.py b/login.py index 5d8299f..5862c34 100755 --- a/login.py +++ b/login.py @@ -5,17 +5,16 @@ def process_form(req,form): """ reads username and password from form """ - req.write(str(form.keys())) #req.write("
"+"name="+form['name']+", password="+form['password']+"
") if form.keys() != []: - if ("name" in form.keys()) and ("password" in form.keys()): #extract name and password name = form["name"] password = form["password"] sessionid = form["sessionid"] origpassword = psql.get_user_info(name,"password") - req.write('
--password:'+str(password)+' ---origpassword:'+str(origpassword)+'
') + #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: @@ -23,7 +22,7 @@ def process_form(req,form): psql.set_user_sessionid(name,sessionid) psql.set_user_timeout(name) #now display list of games. - game_overview_form(req,name,sessionid) + game_overview_form(req,form,name,sessionid) else: req.write("Login incorrect. Please try again.
") req.write(login_form()) @@ -35,9 +34,9 @@ def process_form(req,form): req.write(login_form()) -def game_overview_form(req,user,sessionid): +def game_overview_form(req,form,user,sessionid): """ - gets the name of a user and the queue of games. + gets: request object, util.FieldStorage form, name of user, sessionid. prints a form with the option to select,create and delete games. """ data = helper.header()+ """ @@ -45,7 +44,8 @@ def game_overview_form(req,user,sessionid):
""" gamelist = psql.get_user_game_list(user) - req.write(str(gamelist)+"
\n") + #debug + helper.debug(req,form,str(gamelist)+"
\n") #display list of current games counter = 10 tmp = "" @@ -61,16 +61,16 @@ def game_overview_form(req,user,sessionid): tmp += '\n' % sessionid tmp += '\n' % user data += tmp - data += '\n\n
' + data += '\n\n' #now comes the option for creating new games. - data += "

Start a new Game

\n" + data += "

New Game:

\n" if counter > 0: data+= "You have %s free game slots.
" % counter data += """
- +
""" % (sessionid, user) else: @@ -92,27 +92,44 @@ def login_form():

Pasword:

-

+

""" % helper.generate_session_id() data += helper.footer() - - - return data +def navigation_bar(username,sessionid): + """ + gets username and sessionid + writes the following to req: + - a button to return to the game overview + - a logout button + returns string + """ + #TODO: buttons + data=""" +
+ + + + +
+ """ % (username,sessionid) + return(data) + + def main(req,form): - req.write((str(form.keys())+"
")) + #debug + helper.debug(req,form) + #req.write(helper.footer()) if "sessionid" not in form.keys(): req.write(login_form()) elif ("create" in form.keys()) and ("username" in form.keys()): - #user wants to create a new game - #gamecreation = apache.import_module("gamecreation") - #gamecreation.main(req,form) - #gamecreation.main(req,form) pass + elif ("game overview" in form.keys()) and ("username" in form.keys()) and ("sessionid" in form.keys()): + game_overview_form(req,form,form["username"],form["sessionid"]) else: process_form(req,form) diff --git a/main.py b/main.py index dfefd32..5bbf8ec 100755 --- a/main.py +++ b/main.py @@ -1,9 +1,3 @@ -#!/usr/bin/python -""" -simple cgi wrapper for a cgi script, prints the error of the script as html -taken from http://gnosis.cx/publish/programming/feature_5min_python.html -modified a little -""" import sys, traceback,string,time import init_webgo,psql @@ -32,22 +26,27 @@ def handler(req): #if sessionid=sesssionid and time < timeout: # set_timeout - + helper = apache.import_module("helper") if (psql.get_user_info(username,'timeout') > int(time.time())) and (sessionid == psql.get_user_info(username,'sessionid')): - psql.set_user_timeout(username) - 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()): - playgame = apache.import_module("playgame") - playgame.main(req,form) + psql.set_user_timeout(username) + 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()): + playgame = apache.import_module("playgame") + playgame.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) + return apache.OK except: errtime = '----- '+ time.ctime(time.time()) +' -----\n' @@ -92,7 +91,3 @@ def ErrorMsg(escape=0): import cgi body = cgi.escape(body) return body - - - -#start(req) \ No newline at end of file diff --git a/playgame.py b/playgame.py index f499179..081257c 100644 --- a/playgame.py +++ b/playgame.py @@ -1,6 +1,8 @@ -import goban,helper,psql +import goban,helper,psql,login import string +DEBUG = 1 + def is_my_turn(req,form,gobandict): """ gets request and util.FiedStorage form. @@ -74,11 +76,12 @@ def main(req,form): if is_my_turn(req,form,gobandict): data += ("Its your turn.
") else: - data+= ("This is not your turn. Look, but don't touch ;)
") + data+= ("This is not your turn. You have to wait for the move of the other player.
") #print goban data += goban.display_goban(gobandict,req,form) + data += login.navigation_bar(form["username"],form["sessionid"]) data += helper.footer() req.write(data) diff --git a/psql.py b/psql.py index e7620c6..894106f 100755 --- a/psql.py +++ b/psql.py @@ -1,6 +1,8 @@ import helper import pgdb,sys +DEBUG = 1 + dbusername="webgouser" dbpassword="webgopassword" dbname="webgo"