752fabf61432bea877e665493456d0ba82bcdc87
[progcomp2013.git] / qchess / qchess.cgi
1 #!/usr/bin/python -u
2
3 # CGI wrapper to qchess
4
5 import sys
6 import os
7
8 import cgi
9 import time
10 import threading
11 import datetime
12 import subprocess
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"].value
123         except:
124                 request = None
125                 mode = None
126         else:
127                 try:
128                         mode = form["m"].value
129                 except:
130                         mode = None
131         
132
133         
134         try:
135                 #x = int(argv[1])       
136                 #y = int(argv[2])
137                 x = int(form["x"].value)
138                 y = int(form["y"].value)
139         except:
140                 
141                 if os.path.exists(path+client+".in") and os.path.exists(path+client+".out"):
142                         if request == "quit":
143                                 print "Quit."
144                                 quit()
145                                 return 0
146                         
147                         print "Game in progress expects x and y."
148                         return 1
149                 elif request == "start":
150                         print "New game."
151                         args = path+"qchess.py --no-graphics"
152                         if mode == None or mode == "bishop":
153                                 args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentBishop"
154                         if mode == "random":
155                                 args += " @fifo:../qchess-cgi-data/"+client+" @internal:AgentRandom"
156                         elif mode == "eigengame":
157                                 args += " --server=progcomp.ucc.asn.au @fifo:../qchess-cgi-data/"+client
158
159                         os.system("echo '"+args+"' | at now")
160
161                 #       subprocess.Popen(args)
162                 #       os.spawnl(os.P_NOWAIT, args)
163
164
165                         time.sleep(1)
166                         
167                         log = open(path+client, "a")
168                         log.write("%s" % str(datetime.datetime.now()))
169                         log.close()
170                         
171                 else:
172                         print "No game in progress."
173                         return 1
174                         
175         else:
176                 if not (os.path.exists(path+client+".in") and os.path.exists(path+client+".out")):
177                         print "No game in progress."
178                         return 1
179                         
180                 try:
181                         fifo_out = open_fifo(path+client+".in", "w")
182                 except:
183                         quit()
184                 else:
185                         fifo_out.write("%d %d\n" % (x, y))
186                         fifo_out.close()
187                 
188                 
189         
190         #sys.stderr.write("\ncgi read from fifo here\n")
191         try:
192                 fifo_in = open_fifo(path+client+".out", "r")
193         except:
194                 quit()
195         else:
196                 #       sys.stderr.write("cgi opened fine\n")
197                 s = fifo_in.readline().strip(" \r\n")
198                 #sys.stderr.write("cgi read first line: "+str(s)+"\n")  
199                 while s != "SELECT?" and s != "MOVE?" and not s.split(" ")[0] in ["white","black"]:
200                         if s != "":
201                                 print s
202                 #       sys.stderr.write("Read: " + str(s) + "\n")
203                         
204                         s = fifo_in.readline().strip(" \r\n")
205                 print s
206                 fifo_in.close()
207                 if s.split(" ")[0] in ["white", "black"]:
208                         #sys.stderr.write("cgi quit!\n")
209                         quit()
210         
211         #sys.stderr.write("cgi qchess Done\n")
212         return 0
213
214
215 if __name__ == "__main__":
216         try:
217                 sys.exit(main(sys.argv))
218         except Exception, e:
219                 print e
220                 sys.stderr.write(sys.argv[0] + ": " + str(e) + "\n")
221                 sys.exit(1)

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