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

# CGI wrapper to qchess

import sys
import os

import cgi
import subprocess
import time
import threading
Sam Moore's avatar
Sam Moore committed
12
import datetime
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
122
		#request = argv[1]
		request = form["r"]
Sam Moore's avatar
Sam Moore committed
123
124
	except:
		request = None
Sam Moore's avatar
Sam Moore committed
125
126
127
128
129
130
		mode = None
	else:
		try:
			mode = form["m"]
		except:
			mode = None
Sam Moore's avatar
Sam Moore committed
131
132
133

	
	try:
Sam Moore's avatar
Sam Moore committed
134
135
136
137
		#x = int(argv[1])	
		#y = int(argv[2])
		x = form["x"]
		y = form["y"]
Sam Moore's avatar
Sam Moore committed
138
139
	except:
		
Sam Moore's avatar
Sam Moore committed
140
141
142
143
144
145
146
		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
147
			return 1
Sam Moore's avatar
Sam Moore committed
148
149
150
151
152
153
154
155
156
		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]
Sam Moore's avatar
Sam Moore committed
157
158
159
			subprocess.Popen(args)
			time.sleep(1)
			
Sam Moore's avatar
Sam Moore committed
160
161
162
163
164
165
166
167
			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
168
	else:
Sam Moore's avatar
Sam Moore committed
169
170
171
172
173
174
175
176
177
178
179
		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
180
181
182
		
		
	
Sam Moore's avatar
Sam Moore committed
183
	#sys.stderr.write("\ncgi read from fifo here\n")
Sam Moore's avatar
Sam Moore committed
184
	try:
Sam Moore's avatar
Sam Moore committed
185
		fifo_in = open_fifo(path+client+".out", "r")
Sam Moore's avatar
Sam Moore committed
186
187
188
	except:
		quit()
	else:
Sam Moore's avatar
Sam Moore committed
189
		#sys.stderr.write("Opened fine\n")
Sam Moore's avatar
Sam Moore committed
190
191
		s = fifo_in.readline().strip(" \r\n")
	
Sam Moore's avatar
Sam Moore committed
192
		while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
Sam Moore's avatar
Sam Moore committed
193
194
			if s != "":
				print s
Sam Moore's avatar
Sam Moore committed
195
			
Sam Moore's avatar
Sam Moore committed
196
197
198
199
			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
200
			#sys.stderr.write("cgi quit!\n")
Sam Moore's avatar
Sam Moore committed
201
202
			quit()
	
Sam Moore's avatar
Sam Moore committed
203
	#sys.stderr.write("Done\n")
Sam Moore's avatar
Sam Moore committed
204
205
206
207
208
209
210
	return 0


if __name__ == "__main__":
	try:
		sys.exit(main(sys.argv))
	except Exception, e:
Sam Moore's avatar
Sam Moore committed
211
212
		print e
		sys.stderr.write(str(e) + "\n")
Sam Moore's avatar
Sam Moore committed
213
		sys.exit(1)