Franck Pommereau

added POST and headless to JSON

...@@ -8,6 +8,7 @@ from snakes.utils.abcd import CompilationError, DeclarationError ...@@ -8,6 +8,7 @@ from snakes.utils.abcd import CompilationError, DeclarationError
8 from snakes.utils.abcd.simul import Simulator 8 from snakes.utils.abcd.simul import Simulator
9 from snakes.utils.abcd.checker import Checker 9 from snakes.utils.abcd.checker import Checker
10 from snakes.utils.abcd.html import build as html 10 from snakes.utils.abcd.html import build as html
11 +from snakes.utils.simul.html import json
11 12
12 ## 13 ##
13 ## error messages 14 ## error messages
...@@ -88,8 +89,9 @@ opt.add_option("-s", "--simul", ...@@ -88,8 +89,9 @@ opt.add_option("-s", "--simul",
88 dest="simul", action="store_true", default=False, 89 dest="simul", action="store_true", default=False,
89 help="launch interactive code simulator") 90 help="launch interactive code simulator")
90 opt.add_option("--headless", 91 opt.add_option("--headless",
91 - dest="headless", action="store_true", default=False, 92 + dest="headless", action="store", default=None,
92 - help="headless code simulator (don't start browser)") 93 + help="headless code simulator, with saved parameters",
94 + metavar="JSONFILE")
93 opt.add_option("-H", "--html", 95 opt.add_option("-H", "--html",
94 dest="html", action="store", default=None, 96 dest="html", action="store", default=None,
95 help="save net as HTML", 97 help="save net as HTML",
...@@ -280,7 +282,14 @@ def main (args=sys.argv[1:], src=None) : ...@@ -280,7 +282,14 @@ def main (args=sys.argv[1:], src=None) :
280 except : 282 except :
281 bug() 283 bug()
282 simul.start() 284 simul.start()
283 - if not options.headless : 285 + if options.headless :
286 + with open(options.headless, "w") as out :
287 + out.write(json({"res" : "%sr" % simul.url,
288 + "url" : simul.url,
289 + "key" : simul.server.httpd.key,
290 + "host" : "127.0.0.1",
291 + "port" : simul.port}))
292 + else :
284 webbrowser.open(simul.url) 293 webbrowser.open(simul.url)
285 simul.wait() 294 simul.wait()
286 elif trace : 295 elif trace :
......
1 +import tempfile, anydbm, os
1 from snakes.utils.simul import * 2 from snakes.utils.simul import *
2 import snakes.utils.abcd.html as html 3 import snakes.utils.abcd.html as html
3 4
...@@ -25,6 +26,11 @@ class Simulator (BaseHTTPSimulator) : ...@@ -25,6 +26,11 @@ class Simulator (BaseHTTPSimulator) :
25 if nid in n2html.n2a : 26 if nid in n2html.n2a :
26 self.abcd[trans.name] = ", ".join("#" + i for i in 27 self.abcd[trans.name] = ", ".join("#" + i for i in
27 n2html.n2a[nid]) 28 n2html.n2a[nid])
29 + # persistency
30 + self.tmp = tempfile.NamedTemporaryFile()
31 + self.tmp.file.close()
32 + os.unlink(self.tmp.name)
33 + self.store = anydbm.open(self.tmp.name, "c")
28 def getstate (self, state) : 34 def getstate (self, state) :
29 marking = self.states[state] 35 marking = self.states[state]
30 modes = dict((t, []) for t in self.transid) 36 modes = dict((t, []) for t in self.transid)
...@@ -70,4 +76,15 @@ class Simulator (BaseHTTPSimulator) : ...@@ -70,4 +76,15 @@ class Simulator (BaseHTTPSimulator) :
70 "#model .tree" : "hierarchy of ABCD objects", 76 "#model .tree" : "hierarchy of ABCD objects",
71 "#model .petrinet" : "Petri nets semantics"}) 77 "#model .petrinet" : "Petri nets semantics"})
72 return help 78 return help
73 - 79 + @http("text/plain", key=str)
80 + def get (self, key) :
81 + try :
82 + print self.store[key]
83 + return self.store[key]
84 + except KeyError :
85 + raise HTTPError(httplib.NOT_FOUND)
86 + @http("text/plain", key=str, value=str)
87 + def put (self, key, value) :
88 + print "store[%r] = %r" % (key, value)
89 + self.store[key] = value
90 + return "OK"
......
...@@ -151,7 +151,7 @@ class BaseHTTPSimulator (Node) : ...@@ -151,7 +151,7 @@ class BaseHTTPSimulator (Node) :
151 ], 151 ],
152 } 152 }
153 def init_index (self) : 153 def init_index (self) :
154 - return {"res" : "%s/r" % self.url, 154 + return {"res" : "%sr" % self.url,
155 "url" : self.url, 155 "url" : self.url,
156 "key" : self.server.httpd.key, 156 "key" : self.server.httpd.key,
157 "host" : "127.0.0.1", 157 "host" : "127.0.0.1",
......
...@@ -25,6 +25,7 @@ class HTTPError (Exception) : ...@@ -25,6 +25,7 @@ class HTTPError (Exception) :
25 ## 25 ##
26 26
27 encoders = {"application/json" : json, 27 encoders = {"application/json" : json,
28 + "application/binary" : str,
28 "text/plain" : utf8, 29 "text/plain" : utf8,
29 "text/html" : utf8, 30 "text/html" : utf8,
30 } 31 }
...@@ -108,21 +109,30 @@ class ResourceNode (Node) : ...@@ -108,21 +109,30 @@ class ResourceNode (Node) :
108 109
109 class HTTPRequestHandler (BaseHTTPServer.BaseHTTPRequestHandler) : 110 class HTTPRequestHandler (BaseHTTPServer.BaseHTTPRequestHandler) :
110 def do_GET (self) : 111 def do_GET (self) :
112 + url = self.geturl()
113 + self.do(url, url.query)
114 + def do_POST (self) :
115 + content_len = int(self.headers.getheader('content-length'))
116 + data = self.rfile.read(content_len)
117 + self.do(self.geturl(), data)
118 + def geturl (self) :
119 + try :
120 + return urlparse.urlparse(self.path)
121 + except :
122 + raise HTTPError(httplib.BAD_REQUEST, "invalid URL")
123 + def do (self, url, data) :
124 + try :
125 + # warning: parse_qs returns lists for values => use parse_qsl
126 + query = dict(cgi.parse_qsl(data))
127 + # jQuery may add _ in query for cache control, let's drop it
128 + query.pop("_", None)
129 + except :
130 + raise HTTPError(httplib.BAD_REQUEST, "invalid query")
111 try : 131 try :
112 - try :
113 - url = urlparse.urlparse(self.path)
114 - except :
115 - raise HTTPError(httplib.BAD_REQUEST, "invalid URL")
116 try : 132 try :
117 handler = self.server[url.path] 133 handler = self.server[url.path]
118 except KeyError : 134 except KeyError :
119 raise HTTPError(httplib.NOT_FOUND) 135 raise HTTPError(httplib.NOT_FOUND)
120 - try :
121 - query = dict(cgi.parse_qsl(url.query))
122 - # jQuery may add _ in query for cache control, let's drop it
123 - query.pop("_", None)
124 - except :
125 - raise HTTPError(httplib.BAD_REQUEST, "invalid query")
126 content_type, data = handler(**query) 136 content_type, data = handler(**query)
127 self.send_response(httplib.OK) 137 self.send_response(httplib.OK)
128 self.send_header("Content-type", content_type) 138 self.send_header("Content-type", content_type)
......