CGI script working; hopefully
[progcomp2013.git] / qchess / qchess.cgi
1 #!/usr/bin/python
2
3 # CGI wrapper to qchess
4
5 import sys
6 import os
7
8 import cgi
9 import subprocess
10 import time
11 import threading
12 import datetime
13
14 path = "../qchess-cgi-data/"
15
16 def open_fifo(name, mode, timeout=None):
17         if timeout == None:
18                 return open(name, mode)
19         
20         
21         class Worker(threading.Thread):
22                 def __init__(self):
23                         threading.Thread.__init__(self)
24                         self.result = None
25                         self.exception = None
26
27                         
28                 def run(self):          
29                         try:
30                                 self.result = open(name, mode)
31                         except Exception, e:
32                                 self.exception = e
33                                 self.result = None
34                 
35
36         w = Worker()
37         w.start()
38         
39         start = time.time()
40         while time.time() - start < timeout:
41                 if w.is_alive() == False:
42                         w.join()
43                         if w.exception != None:
44                                 raise w.exception
45                         return w.result
46                 time.sleep(0.1)
47         
48         
49         if w.is_alive():
50                 #sys.stderr.write("FIFO_TIMEOUT!\n")
51                 # Recursive to deal with possible race condition
52                 try:
53                         if mode == "r":
54                                 f = open_fifo(name, "w", 1)
55                         else:
56                                 f = open_fifo(name, "r", 1)
57                 except:
58                         pass
59                         
60                 #sys.stderr.write("Opened other end!\n")
61                 while w.is_alive():
62                         time.sleep(0.1)
63                         
64                 w.join()
65                 f.close()
66                 w.result.close()
67                 raise Exception("FIFO_TIMEOUT")
68         else:
69                 w.join()
70                 if w.exception != None:
71                         raise w.exception
72                 return w.result
73
74 def quit():
75         
76         if os.path.exists(path+client+".in") and os.path.exists(path+client+".out"):
77                 try:
78                         fifo_out = open_fifo(path+client+".in", "w", 5)
79                 except:
80                         pass
81                 else:
82                         if fifo_out != None:
83                                 fifo_out.write("quit\n")
84                                 fifo_out.close()
85                 
86                 try:
87                         fifo_in = open_fifo(path+client+".out", "r", 5)
88                 except:
89                         pass
90                 else:
91                         if fifo_in != None:
92                                 s = fifo_in.readline().strip(" \r\n")
93                                 while s != "":
94                         #print s
95                                         s = fifo_in.readline().strip(" \r\n")
96                                         fifo_in.close()
97                         
98         log = open(path+client, "a")
99         log.write(" -> %s\n" % str(datetime.datetime.now()))
100         log.close()
101                         
102         time.sleep(0.5)
103         
104         
105
106
107 def main(argv):
108         print "Content-Type: text/plain\r\n\r\n"
109         
110         global client
111         form = cgi.FieldStorage()
112         client = cgi.escape(os.environ["REMOTE_ADDR"])
113         
114         #client = "127.0.0.1"
115         
116         
117         
118
119         
120         try:
121                 #request = argv[1]
122                 request = form["r"]
123         except:
124                 request = None
125                 mode = None
126         else:
127                 try:
128                         mode = form["m"]
129                 except:
130                         mode = None
131
132         
133         try:
134                 #x = int(argv[1])       
135                 #y = int(argv[2])
136                 x = form["x"]
137                 y = form["y"]
138         except:
139                 
140                 if os.path.exists(path+client+".in") and os.path.exists(path+client+".out"):
141                         if request == "quit":
142                                 print "Quit."
143                                 quit()
144                                 return 0
145                         
146                         print "Game in progress expects x and y."
147                         return 1
148                 elif request == "start":
149                         print "New game."
150                         args = [path+"qchess.py", "--no-graphics"]
151                         if mode == None or mode == "bishop":
152                                 args += ["@fifo:../qchess-cgi-data/"+client, "@internal:AgentBishop"]
153                         if mode == "random":
154                                 args += ["@fifo:../qchess-cgi-data/"+client, "@internal:AgentRandom"]
155                         elif mode == "eigengame":
156                                 args += ["--server=progcomp.ucc.asn.au", "@fifo:../qchess-cgi-data/"+client]
157                         subprocess.Popen(args)
158                         time.sleep(1)
159                         
160                         log = open(path+client, "a")
161                         log.write("%s" % str(datetime.datetime.now()))
162                         log.close()
163                         
164                 else:
165                         print "No game in progress."
166                         return 1
167                         
168         else:
169                 if not (os.path.exists(path+client+".in") and os.path.exists(path+client+".out")):
170                         print "No game in progress."
171                         return 1
172                         
173                 try:
174                         fifo_out = open_fifo(path+client+".in", "w")
175                 except:
176                         quit()
177                 else:
178                         fifo_out.write("%d %d\n" % (x, y))
179                         fifo_out.close()
180                 
181                 
182         
183         #sys.stderr.write("\ncgi read from fifo here\n")
184         try:
185                 fifo_in = open_fifo(path+client+".out", "r")
186         except:
187                 quit()
188         else:
189                 #sys.stderr.write("Opened fine\n")
190                 s = fifo_in.readline().strip(" \r\n")
191         
192                 while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
193                         if s != "":
194                                 print s
195                         
196                         s = fifo_in.readline().strip(" \r\n")
197                 print s
198                 fifo_in.close()
199                 if s.split(" ")[0] in ["white", "black"]:
200                         #sys.stderr.write("cgi quit!\n")
201                         quit()
202         
203         #sys.stderr.write("Done\n")
204         return 0
205
206
207 if __name__ == "__main__":
208         try:
209                 sys.exit(main(sys.argv))
210         except Exception, e:
211                 print e
212                 sys.stderr.write(str(e) + "\n")
213                 sys.exit(1)

UCC git Repository :: git.ucc.asn.au