qchess.cgi 4.21 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 74
		return w.result

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


def main(argv):
Sam Moore's avatar
Sam Moore committed
108 109
	print "Content-Type: text/plain\r\n\r\n"
	
Sam Moore's avatar
Sam Moore committed
110
	global client
Sam Moore's avatar
Sam Moore committed
111 112 113 114
	form = cgi.FieldStorage()
	client = cgi.escape(os.environ["REMOTE_ADDR"])
	
	#client = "127.0.0.1"
Sam Moore's avatar
Sam Moore committed
115 116 117 118 119 120
	
	
	

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

	
	try:
Sam Moore's avatar
Sam Moore committed
135 136
		#x = int(argv[1])	
		#y = int(argv[2])
judge's avatar
judge committed
137 138
		x = int(form["x"].value)
		y = int(form["y"].value)
Sam Moore's avatar
Sam Moore committed
139 140
	except:
		
Sam Moore's avatar
Sam Moore committed
141 142 143 144 145 146 147
		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
148
			return 1
Sam Moore's avatar
Sam Moore committed
149 150
		elif request == "start":
			print "New game."
judge's avatar
judge committed
151
			args = path+"qchess.py --no-graphics"
Sam Moore's avatar
Sam Moore committed
152
			if mode == None or mode == "bishop":
judge's avatar
judge committed
153
				args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentBishop"
Sam Moore's avatar
Sam Moore committed
154
			if mode == "random":
judge's avatar
judge committed
155
				args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentRandom"
Sam Moore's avatar
Sam Moore committed
156
			elif mode == "eigengame":
judge's avatar
judge committed
157 158 159 160 161 162 163 164
				args += " --server=progcomp.ucc.asn.au @fifo:../qchess-cgi-data/"+client

			os.system("echo '"+args+"' | at now")

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


Sam Moore's avatar
Sam Moore committed
165 166
			time.sleep(1)
			
Sam Moore's avatar
Sam Moore committed
167 168 169 170 171 172 173 174
			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
175
	else:
Sam Moore's avatar
Sam Moore committed
176 177 178 179 180 181 182 183 184 185 186
		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
187 188 189
		
		
	
Sam Moore's avatar
Sam Moore committed
190
	#sys.stderr.write("\ncgi read from fifo here\n")
Sam Moore's avatar
Sam Moore committed
191
	try:
Sam Moore's avatar
Sam Moore committed
192
		fifo_in = open_fifo(path+client+".out", "r")
Sam Moore's avatar
Sam Moore committed
193 194 195
	except:
		quit()
	else:
judge's avatar
judge committed
196
		#	sys.stderr.write("cgi opened fine\n")
Sam Moore's avatar
Sam Moore committed
197
		s = fifo_in.readline().strip(" \r\n")
judge's avatar
judge committed
198
		#sys.stderr.write("cgi read first line: "+str(s)+"\n")	
Sam Moore's avatar
Sam Moore committed
199
		while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
Sam Moore's avatar
Sam Moore committed
200 201
			if s != "":
				print s
judge's avatar
judge committed
202
		#	sys.stderr.write("Read: " + str(s) + "\n")
Sam Moore's avatar
Sam Moore committed
203
			
Sam Moore's avatar
Sam Moore committed
204 205 206 207
			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
208
			#sys.stderr.write("cgi quit!\n")
Sam Moore's avatar
Sam Moore committed
209 210
			quit()
	
judge's avatar
judge committed
211
	#sys.stderr.write("cgi qchess Done\n")
Sam Moore's avatar
Sam Moore committed
212 213 214 215 216 217 218
	return 0


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