qchess.cgi 4.57 KB
Newer Older
judge's avatar
judge committed
1
#!/usr/bin/python -u
Sam Moore's avatar
Sam Moore committed
2 3 4 5 6 7 8 9 10

# CGI wrapper to qchess

import sys
import os

import cgi
import time
import threading
Sam Moore's avatar
Sam Moore committed
11
import datetime
judge's avatar
judge committed
12
import subprocess
Sam Moore's avatar
Sam Moore committed
13

Sam Moore's avatar
Sam Moore committed
14
path = "../qchess-cgi-data/"
Sam Moore's avatar
Sam Moore committed
15 16 17 18 19 20 21 22 23 24

def open_fifo(name, mode, timeout=None):
	if timeout == None:
		return open(name, mode)
	
	
	class Worker(threading.Thread):
		def __init__(self):
			threading.Thread.__init__(self)
			self.result = None
Sam Moore's avatar
Sam Moore committed
25 26
			self.exception = None

Sam Moore's avatar
Sam Moore committed
27 28
			
		def run(self):		
Sam Moore's avatar
Sam Moore committed
29 30 31 32 33
			try:
				self.result = open(name, mode)
			except Exception, e:
				self.exception = e
				self.result = None
Sam Moore's avatar
Sam Moore committed
34 35 36 37 38 39 40 41 42
		

	w = Worker()
	w.start()
	
	start = time.time()
	while time.time() - start < timeout:
		if w.is_alive() == False:
			w.join()
Sam Moore's avatar
Sam Moore committed
43 44
			if w.exception != None:
				raise w.exception
Sam Moore's avatar
Sam Moore committed
45 46 47 48 49 50
			return w.result
		time.sleep(0.1)
	
	
	if w.is_alive():
		#sys.stderr.write("FIFO_TIMEOUT!\n")
Sam Moore's avatar
Sam Moore committed
51 52 53 54 55 56 57 58
		# 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
Sam Moore's avatar
Sam Moore committed
59 60 61 62 63 64 65 66 67 68 69
			
		#sys.stderr.write("Opened other end!\n")
		while w.is_alive():
			time.sleep(0.1)
			
		w.join()
		f.close()
		w.result.close()
		raise Exception("FIFO_TIMEOUT")
	else:
		w.join()
Sam Moore's avatar
Sam Moore committed
70 71
		if w.exception != None:
			raise w.exception
Sam Moore's avatar
Sam Moore committed
72 73
		return w.result

74 75 76 77
def force_quit():
	os.remove(path+client+".in")
	os.remove(path+client+".out")

Sam Moore's avatar
Sam Moore committed
78
def quit():
Sam Moore's avatar
Sam Moore committed
79 80 81 82 83 84 85 86 87 88
	
	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()
Sam Moore's avatar
Sam Moore committed
89
		
Sam Moore's avatar
Sam Moore committed
90 91 92 93 94 95 96 97
		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 != "":
Sam Moore's avatar
Sam Moore committed
98
			#print s
Sam Moore's avatar
Sam Moore committed
99 100 101 102 103 104 105
					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()
			
Sam Moore's avatar
Sam Moore committed
106 107 108 109 110 111
	time.sleep(0.5)
	
	


def main(argv):
112
	print "Content-Type: text/plain\r\n" #Removed the second new line. Makes parsing everything easier ~BG3
Sam Moore's avatar
Sam Moore committed
113
	
Sam Moore's avatar
Sam Moore committed
114
	global client
Sam Moore's avatar
Sam Moore committed
115 116 117 118
	form = cgi.FieldStorage()
	client = cgi.escape(os.environ["REMOTE_ADDR"])
	
	#client = "127.0.0.1"
Sam Moore's avatar
Sam Moore committed
119 120 121 122 123 124
	
	
	

	
	try:
Sam Moore's avatar
Sam Moore committed
125
		#request = argv[1]
judge's avatar
judge committed
126
		request = form["r"].value
Sam Moore's avatar
Sam Moore committed
127 128
	except:
		request = None
Sam Moore's avatar
Sam Moore committed
129 130 131
		mode = None
	else:
		try:
judge's avatar
judge committed
132
			mode = form["m"].value
Sam Moore's avatar
Sam Moore committed
133 134
		except:
			mode = None
judge's avatar
judge committed
135
	
Sam Moore's avatar
Sam Moore committed
136 137 138

	
	try:
Sam Moore's avatar
Sam Moore committed
139 140
		#x = int(argv[1])	
		#y = int(argv[2])
judge's avatar
judge committed
141 142
		x = int(form["x"].value)
		y = int(form["y"].value)
Sam Moore's avatar
Sam Moore committed
143
	except:
144 145 146 147 148
		if request == "force_quit":
			force_quit()
			quit()
			return 0

Sam Moore's avatar
Sam Moore committed
149 150 151 152 153 154 155
		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."
Sam Moore's avatar
Sam Moore committed
156
			return 1
Sam Moore's avatar
Sam Moore committed
157 158
		elif request == "start":
			print "New game."
judge's avatar
judge committed
159
			args = path+"qchess.py --no-graphics"
160 161 162 163 164
			if mode == "black":
				args += " @internal:AgentBishop @fifo:../qchess-cgi-data/"+client
			elif mode == None or mode == "bishop":
				args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentBishop"
			elif mode == "random":
judge's avatar
judge committed
165
				args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentRandom"
Sam Moore's avatar
Sam Moore committed
166
			elif mode == "eigengame":
judge's avatar
judge committed
167 168
				args += " --server=progcomp.ucc.asn.au @fifo:../qchess-cgi-data/"+client

169 170
			args += " [email protected]/qchess-cgi-data/"+client+".log";

judge's avatar
judge committed
171 172 173 174 175 176
			os.system("echo '"+args+"' | at now")

		#	subprocess.Popen(args)
		#	os.spawnl(os.P_NOWAIT, args)


Sam Moore's avatar
Sam Moore committed
177 178
			time.sleep(1)
			
Sam Moore's avatar
Sam Moore committed
179 180 181 182 183 184 185 186
			log = open(path+client, "a")
			log.write("%s" % str(datetime.datetime.now()))
			log.close()
			
		else:
			print "No game in progress."
			return 1
			
Sam Moore's avatar
Sam Moore committed
187
	else:
Sam Moore's avatar
Sam Moore committed
188 189 190 191 192 193 194 195 196 197 198
		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()
Sam Moore's avatar
Sam Moore committed
199 200 201
		
		
	
Sam Moore's avatar
Sam Moore committed
202
	#sys.stderr.write("\ncgi read from fifo here\n")
Sam Moore's avatar
Sam Moore committed
203
	try:
Sam Moore's avatar
Sam Moore committed
204
		fifo_in = open_fifo(path+client+".out", "r")
Sam Moore's avatar
Sam Moore committed
205 206 207
	except:
		quit()
	else:
judge's avatar
judge committed
208
		#	sys.stderr.write("cgi opened fine\n")
Sam Moore's avatar
Sam Moore committed
209
		s = fifo_in.readline().strip(" \r\n")
judge's avatar
judge committed
210
		#sys.stderr.write("cgi read first line: "+str(s)+"\n")	
Sam Moore's avatar
Sam Moore committed
211
		while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
Sam Moore's avatar
Sam Moore committed
212 213
			if s != "":
				print s
judge's avatar
judge committed
214
		#	sys.stderr.write("Read: " + str(s) + "\n")
Sam Moore's avatar
Sam Moore committed
215
			
Sam Moore's avatar
Sam Moore committed
216 217 218 219
			s = fifo_in.readline().strip(" \r\n")
		print s
		fifo_in.close()
		if s.split(" ")[0] in ["white", "black"]:
Sam Moore's avatar
Sam Moore committed
220
			#sys.stderr.write("cgi quit!\n")
Sam Moore's avatar
Sam Moore committed
221 222
			quit()
	
judge's avatar
judge committed
223
	#sys.stderr.write("cgi qchess Done\n")
Sam Moore's avatar
Sam Moore committed
224 225 226 227 228 229 230
	return 0


if __name__ == "__main__":
	try:
		sys.exit(main(sys.argv))
	except Exception, e:
Sam Moore's avatar
Sam Moore committed
231
		print e
judge's avatar
judge committed
232
		sys.stderr.write(sys.argv[0] + ": " + str(e) + "\n")
Sam Moore's avatar
Sam Moore committed
233
		sys.exit(1)