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)