Franck Pommereau

added POST and headless to JSON

......@@ -8,6 +8,7 @@ from snakes.utils.abcd import CompilationError, DeclarationError
from snakes.utils.abcd.simul import Simulator
from snakes.utils.abcd.checker import Checker
from snakes.utils.abcd.html import build as html
from snakes.utils.simul.html import json
##
## error messages
......@@ -88,8 +89,9 @@ opt.add_option("-s", "--simul",
dest="simul", action="store_true", default=False,
help="launch interactive code simulator")
opt.add_option("--headless",
dest="headless", action="store_true", default=False,
help="headless code simulator (don't start browser)")
dest="headless", action="store", default=None,
help="headless code simulator, with saved parameters",
metavar="JSONFILE")
opt.add_option("-H", "--html",
dest="html", action="store", default=None,
help="save net as HTML",
......@@ -280,7 +282,14 @@ def main (args=sys.argv[1:], src=None) :
except :
bug()
simul.start()
if not options.headless :
if options.headless :
with open(options.headless, "w") as out :
out.write(json({"res" : "%sr" % simul.url,
"url" : simul.url,
"key" : simul.server.httpd.key,
"host" : "127.0.0.1",
"port" : simul.port}))
else :
webbrowser.open(simul.url)
simul.wait()
elif trace :
......
import tempfile, anydbm, os
from snakes.utils.simul import *
import snakes.utils.abcd.html as html
......@@ -25,6 +26,11 @@ class Simulator (BaseHTTPSimulator) :
if nid in n2html.n2a :
self.abcd[trans.name] = ", ".join("#" + i for i in
n2html.n2a[nid])
# persistency
self.tmp = tempfile.NamedTemporaryFile()
self.tmp.file.close()
os.unlink(self.tmp.name)
self.store = anydbm.open(self.tmp.name, "c")
def getstate (self, state) :
marking = self.states[state]
modes = dict((t, []) for t in self.transid)
......@@ -70,4 +76,15 @@ class Simulator (BaseHTTPSimulator) :
"#model .tree" : "hierarchy of ABCD objects",
"#model .petrinet" : "Petri nets semantics"})
return help
@http("text/plain", key=str)
def get (self, key) :
try :
print self.store[key]
return self.store[key]
except KeyError :
raise HTTPError(httplib.NOT_FOUND)
@http("text/plain", key=str, value=str)
def put (self, key, value) :
print "store[%r] = %r" % (key, value)
self.store[key] = value
return "OK"
......
......@@ -151,7 +151,7 @@ class BaseHTTPSimulator (Node) :
],
}
def init_index (self) :
return {"res" : "%s/r" % self.url,
return {"res" : "%sr" % self.url,
"url" : self.url,
"key" : self.server.httpd.key,
"host" : "127.0.0.1",
......
......@@ -25,6 +25,7 @@ class HTTPError (Exception) :
##
encoders = {"application/json" : json,
"application/binary" : str,
"text/plain" : utf8,
"text/html" : utf8,
}
......@@ -108,21 +109,30 @@ class ResourceNode (Node) :
class HTTPRequestHandler (BaseHTTPServer.BaseHTTPRequestHandler) :
def do_GET (self) :
url = self.geturl()
self.do(url, url.query)
def do_POST (self) :
content_len = int(self.headers.getheader('content-length'))
data = self.rfile.read(content_len)
self.do(self.geturl(), data)
def geturl (self) :
try :
return urlparse.urlparse(self.path)
except :
raise HTTPError(httplib.BAD_REQUEST, "invalid URL")
def do (self, url, data) :
try :
# warning: parse_qs returns lists for values => use parse_qsl
query = dict(cgi.parse_qsl(data))
# jQuery may add _ in query for cache control, let's drop it
query.pop("_", None)
except :
raise HTTPError(httplib.BAD_REQUEST, "invalid query")
try :
try :
url = urlparse.urlparse(self.path)
except :
raise HTTPError(httplib.BAD_REQUEST, "invalid URL")
try :
handler = self.server[url.path]
except KeyError :
raise HTTPError(httplib.NOT_FOUND)
try :
query = dict(cgi.parse_qsl(url.query))
# jQuery may add _ in query for cache control, let's drop it
query.pop("_", None)
except :
raise HTTPError(httplib.BAD_REQUEST, "invalid query")
content_type, data = handler(**query)
self.send_response(httplib.OK)
self.send_header("Content-type", content_type)
......