From e9e685cd5fa0c4f068df2431232b7c2250ffd0ed Mon Sep 17 00:00:00 2001
From: Sam Moore <matches@ucc.asn.au>
Date: Sun, 19 May 2013 12:36:25 +0800
Subject: [PATCH] CGI script working; hopefully

---
 qchess/qchess.cgi    | 158 +++++++++++++++++++++++++++++--------------
 qchess/qchess.py     |  27 ++++++--
 qchess/src/game.py   |   2 +-
 qchess/src/player.py |  23 +++++--
 4 files changed, 147 insertions(+), 63 deletions(-)

diff --git a/qchess/qchess.cgi b/qchess/qchess.cgi
index 96e45a1..993a36e 100755
--- a/qchess/qchess.cgi
+++ b/qchess/qchess.cgi
@@ -9,7 +9,9 @@ import cgi
 import subprocess
 import time
 import threading
+import datetime
 
+path = "../qchess-cgi-data/"
 
 def open_fifo(name, mode, timeout=None):
 	if timeout == None:
@@ -20,9 +22,15 @@ def open_fifo(name, mode, timeout=None):
 		def __init__(self):
 			threading.Thread.__init__(self)
 			self.result = None
+			self.exception = None
+
 			
 		def run(self):		
-			self.result = open(name, mode)
+			try:
+				self.result = open(name, mode)
+			except Exception, e:
+				self.exception = e
+				self.result = None
 		
 
 	w = Worker()
@@ -32,16 +40,22 @@ def open_fifo(name, mode, timeout=None):
 	while time.time() - start < timeout:
 		if w.is_alive() == False:
 			w.join()
+			if w.exception != None:
+				raise w.exception
 			return w.result
 		time.sleep(0.1)
 	
 	
 	if w.is_alive():
 		#sys.stderr.write("FIFO_TIMEOUT!\n")
-		if mode == "r":
-			f = open(name, "w")
-		else:
-			f = open(name, "r")
+		# Recursive to deal with possible race condition
+		try:
+			if mode == "r":
+				f = open_fifo(name, "w", 1)
+			else:
+				f = open_fifo(name, "r", 1)
+		except:
+			pass
 			
 		#sys.stderr.write("Opened other end!\n")
 		while w.is_alive():
@@ -53,97 +67,140 @@ def open_fifo(name, mode, timeout=None):
 		raise Exception("FIFO_TIMEOUT")
 	else:
 		w.join()
+		if w.exception != None:
+			raise w.exception
 		return w.result
 
 def quit():
-	try:
-		fifo_out = open_fifo("../cgi-data/"+client+".in", "w", 5)
-	except:
-		pass
-	else:
-		fifo_out.write("quit\n")
-		fifo_out.close()
+	
+	if os.path.exists(path+client+".in") and os.path.exists(path+client+".out"):
+		try:
+			fifo_out = open_fifo(path+client+".in", "w", 5)
+		except:
+			pass
+		else:
+			if fifo_out != None:
+				fifo_out.write("quit\n")
+				fifo_out.close()
 		
-	try:
-		fifo_in = open_fifo("../cgi-data/"+client+".out", "w", 5)
-	except:
-		pass
-	else:
-		s = fifo_in.readline().strip(" \r\n")
-		while s != "":
+		try:
+			fifo_in = open_fifo(path+client+".out", "r", 5)
+		except:
+			pass
+		else:
+			if fifo_in != None:
+				s = fifo_in.readline().strip(" \r\n")
+				while s != "":
 			#print s
-			s = fifo_in.readline().strip(" \r\n")
-			fifo_in.close()
+					s = fifo_in.readline().strip(" \r\n")
+					fifo_in.close()
+			
+	log = open(path+client, "a")
+	log.write(" -> %s\n" % str(datetime.datetime.now()))
+	log.close()
+			
 	time.sleep(0.5)
 	
 	
 
 
 def main(argv):
+	print "Content-Type: text/plain\r\n\r\n"
+	
 	global client
-	#form = cgi.FieldStorage()
-	#client = cgi.escape(os.environ["REMOTE_ADDR"])
+	form = cgi.FieldStorage()
+	client = cgi.escape(os.environ["REMOTE_ADDR"])
+	
+	#client = "127.0.0.1"
 	
-	client = "127.0.0.1"
 	
 	
-	print "Content-Type: text/plain\r\n\r\n"
 
 	
 	try:
-		request = argv[1]
+		#request = argv[1]
+		request = form["r"]
 	except:
 		request = None
+		mode = None
+	else:
+		try:
+			mode = form["m"]
+		except:
+			mode = None
 
 	
 	try:
-		x = int(argv[1])	
-		y = int(argv[2])
+		#x = int(argv[1])	
+		#y = int(argv[2])
+		x = form["x"]
+		y = form["y"]
 	except:
-		if request == "quit":
-			quit()
-			return 0
 		
-		if os.path.exists("../cgi-bin/"+client+".in") and os.path.exists("../cgi-bin/"+client+".out"):
-			print "Error: Game in progress expects x and y"
+		if os.path.exists(path+client+".in") and os.path.exists(path+client+".out"):
+			if request == "quit":
+				print "Quit."
+				quit()
+				return 0
+			
+			print "Game in progress expects x and y."
 			return 1
-		else:
-			print "NEW GAME"
-			args = ["./qchess.py"]
-			if request == None:
-				args += ["@fifo:../cgi-data/"+client, "@internal:AgentBishop"]
-			elif request == "eigengame":
-				args += ["--server=progcomp.ucc.asn.au", "@fifo:../cgi-data/"+client]
+		elif request == "start":
+			print "New game."
+			args = [path+"qchess.py", "--no-graphics"]
+			if mode == None or mode == "bishop":
+				args += ["@fifo:../qchess-cgi-data/"+client, "@internal:AgentBishop"]
+			if mode == "random":
+				args += ["@fifo:../qchess-cgi-data/"+client, "@internal:AgentRandom"]
+			elif mode == "eigengame":
+				args += ["--server=progcomp.ucc.asn.au", "@fifo:../qchess-cgi-data/"+client]
 			subprocess.Popen(args)
 			time.sleep(1)
 			
+			log = open(path+client, "a")
+			log.write("%s" % str(datetime.datetime.now()))
+			log.close()
+			
+		else:
+			print "No game in progress."
+			return 1
+			
 	else:
-		
-		fifo_out = open_fifo("../cgi-data/"+client+".in", "w")
-		fifo_out.write("%d %d\n" % (x, y))
-		fifo_out.close()
+		if not (os.path.exists(path+client+".in") and os.path.exists(path+client+".out")):
+			print "No game in progress."
+			return 1
+			
+		try:
+			fifo_out = open_fifo(path+client+".in", "w")
+		except:
+			quit()
+		else:
+			fifo_out.write("%d %d\n" % (x, y))
+			fifo_out.close()
 		
 		
 	
-	sys.stderr.write("\ncgi read from fifo here\n")
+	#sys.stderr.write("\ncgi read from fifo here\n")
 	try:
-		fifo_in = open_fifo("../cgi-data/"+client+".out", "r")
+		fifo_in = open_fifo(path+client+".out", "r")
 	except:
 		quit()
 	else:
-		sys.stderr.write("Opened fine\n")
+		#sys.stderr.write("Opened fine\n")
 		s = fifo_in.readline().strip(" \r\n")
 	
-		while s != "SELECT?" and s != "MOVE?" and s.split(" ")[0] not in ["white", "black"]:
+		while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
 			if s != "":
 				print s
+			
 			s = fifo_in.readline().strip(" \r\n")
 		print s
 		fifo_in.close()
 		if s.split(" ")[0] in ["white", "black"]:
+			#sys.stderr.write("cgi quit!\n")
 			quit()
 	
-	sys.stderr.write("Done\n")
+	#sys.stderr.write("Done\n")
 	return 0
 
 
@@ -151,5 +208,6 @@ if __name__ == "__main__":
 	try:
 		sys.exit(main(sys.argv))
 	except Exception, e:
-		print "Exception: ", e
+		print e
+		sys.stderr.write(str(e) + "\n")
 		sys.exit(1)
diff --git a/qchess/qchess.py b/qchess/qchess.py
index 0ff4209..092a121 100755
--- a/qchess/qchess.py
+++ b/qchess/qchess.py
@@ -663,10 +663,15 @@ def open_fifo(name, mode, timeout=None):
 		def __init__(self):
 			threading.Thread.__init__(self)
 			self.result = None
+			self.exception = None
 
 			
 		def run(self):		
-			self.result = open(name, mode)
+			try:
+				self.result = open(name, mode)
+			except Exception, e:
+				self.exception = e
+				self.result = None
 		
 
 	w = Worker()
@@ -676,16 +681,22 @@ def open_fifo(name, mode, timeout=None):
 	while time.time() - start < timeout:
 		if w.is_alive() == False:
 			w.join()
+			if w.exception != None:
+				raise w.exception
 			return w.result
 		time.sleep(0.1)
 	
 	
 	if w.is_alive():
 		#sys.stderr.write("FIFO_TIMEOUT!\n")
-		if mode == "r":
-			f = open(name, "w")
-		else:
-			f = open(name, "r")
+		# Recursive to deal with possible race condition
+		try:
+			if mode == "r":
+				f = open_fifo(name, "w", 1)
+			else:
+				f = open_fifo(name, "r", 1)
+		except:
+			pass
 			
 		#sys.stderr.write("Opened other end!\n")
 		while w.is_alive():
@@ -697,6 +708,8 @@ def open_fifo(name, mode, timeout=None):
 		raise Exception("FIFO_TIMEOUT")
 	else:
 		w.join()
+		if w.exception != None:
+			raise w.exception
 		return w.result
 	
 
@@ -1792,7 +1805,7 @@ class GameThread(StoppableThread):
 				except Exception,e:
 				#if False:
 					result = e.message
-					#sys.stderr.write(result + "\n")
+					sys.stderr.write("qchess.py exception: "+result + "\n")
 					
 					self.stop()
 					
@@ -2974,4 +2987,4 @@ if __name__ == "__main__":
 		
 
 # --- main.py --- #
-# EOF - created from make on Sun May 19 00:54:03 WST 2013
+# EOF - created from make on Sun May 19 12:36:10 WST 2013
diff --git a/qchess/src/game.py b/qchess/src/game.py
index 6972c5c..73adfe7 100644
--- a/qchess/src/game.py
+++ b/qchess/src/game.py
@@ -147,7 +147,7 @@ class GameThread(StoppableThread):
 				except Exception,e:
 				#if False:
 					result = e.message
-					#sys.stderr.write(result + "\n")
+					sys.stderr.write("qchess.py exception: "+result + "\n")
 					
 					self.stop()
 					
diff --git a/qchess/src/player.py b/qchess/src/player.py
index 1f40066..346674b 100644
--- a/qchess/src/player.py
+++ b/qchess/src/player.py
@@ -38,10 +38,15 @@ def open_fifo(name, mode, timeout=None):
 		def __init__(self):
 			threading.Thread.__init__(self)
 			self.result = None
+			self.exception = None
 
 			
 		def run(self):		
-			self.result = open(name, mode)
+			try:
+				self.result = open(name, mode)
+			except Exception, e:
+				self.exception = e
+				self.result = None
 		
 
 	w = Worker()
@@ -51,16 +56,22 @@ def open_fifo(name, mode, timeout=None):
 	while time.time() - start < timeout:
 		if w.is_alive() == False:
 			w.join()
+			if w.exception != None:
+				raise w.exception
 			return w.result
 		time.sleep(0.1)
 	
 	
 	if w.is_alive():
 		#sys.stderr.write("FIFO_TIMEOUT!\n")
-		if mode == "r":
-			f = open(name, "w")
-		else:
-			f = open(name, "r")
+		# Recursive to deal with possible race condition
+		try:
+			if mode == "r":
+				f = open_fifo(name, "w", 1)
+			else:
+				f = open_fifo(name, "r", 1)
+		except:
+			pass
 			
 		#sys.stderr.write("Opened other end!\n")
 		while w.is_alive():
@@ -72,6 +83,8 @@ def open_fifo(name, mode, timeout=None):
 		raise Exception("FIFO_TIMEOUT")
 	else:
 		w.join()
+		if w.exception != None:
+			raise w.exception
 		return w.result
 	
 
-- 
GitLab