[pypy-svn] r32888 - pypy/dist/pypy/translator/js/demo/jsdemo

arigo at codespeak.net arigo at codespeak.net
Wed Oct 4 20:05:08 CEST 2006


Author: arigo
Date: Wed Oct  4 20:05:07 2006
New Revision: 32888

Added:
   pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py   (contents, props changed)
Log:
A new demo based on BaseHTTPServer with MochiKit: a Python console.


Added: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py	Wed Oct  4 20:05:07 2006
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+""" A basic Python console from your browser.
+
+This depends on MochiKit for proper quoting.
+You need to provide the files as ..jsdemo/MochiKit/*.js.
+(Symlinks are your friends.)
+
+Try to type:  import time; time.sleep(2); print 'hi'
+"""
+
+import autopath
+
+import new, sys, os, cStringIO
+from cgi import parse_qs
+from pypy.translator.js.modules._dom import setTimeout, get_document
+from pypy.translator.js.main import rpython2javascript
+from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
+from pypy.translator.js import commproxy
+
+commproxy.USE_MOCHIKIT = True
+
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+#from SimpleHTTPServer import SimpleHTTPRequestHandler
+
+def js_source(functions):
+    mod = new.module('_js_src')
+    function_names = []
+    for func in functions:
+        name = func.__name__
+        if hasattr(mod, name):
+            raise ValueError("exported function name %r is duplicated"
+                             % (name,))
+        mod.__dict__[name] = func
+        function_names.append(name)
+    sys.modules['_js_src'] = mod
+    try:
+        return rpython2javascript(mod, function_names)
+    finally:
+        del sys.modules['_js_src']
+
+# ____________________________________________________________
+
+HTML_PAGE = """
+<html>
+<head>
+  <title>Example</title>
+  <script type="text/javascript" src="jssource"/>
+  <script src="MochiKit/MochiKit.js" type="text/javascript"/>
+</head>
+<body onload="setup_page()">
+<h3>Console</h3>
+
+    <pre id="data"></pre>
+
+    <input id="inp" size="100" type="text"/>
+
+</body>
+</html>
+"""
+
+httpd = None
+
+def callback(data):
+    inp_elem = get_document().getElementById("inp")
+    inp_elem.disabled = False
+    answer = data.get('answer', '')
+    add_text(answer)
+
+def add_text(text):
+    data_elem = get_document().getElementById("data")
+    data_elem.innerHTML += text
+
+def keypressed(key):
+    kc = key.keyCode
+    if kc == ord("\r"):
+        inp_elem = get_document().getElementById("inp")
+        cmd = inp_elem.value
+        add_text(">>> %s\n" % (cmd,))
+        inp_elem.value = ''
+        inp_elem.disabled = True
+        httpd.some_callback(cmd, callback)
+
+def setup_page():
+    get_document().onkeypress = keypressed
+
+class Server(HTTPServer, BasicExternal):
+    # Methods and signatures how they are rendered for JS
+    _methods = {
+        'some_callback' : MethodDesc([('cmd', "aa"),
+                                      ('callback', lambda : None)],
+                                     {'aa': 'aa'})
+    }
+    
+    _render_xmlhttp = True
+    
+    def __init__(self, *args, **kwargs):
+        HTTPServer.__init__(self, *args, **kwargs)
+        self.source = None
+        self.locals = {}
+
+class RequestHandler(BaseHTTPRequestHandler):
+    def do_GET(self):
+        path = self.path
+        if '?' in path:
+            i = path.index('?')
+        else:
+            i = len(path)
+        kwds = parse_qs(path[i+1:])
+        path = path[:i].split("/")
+        if not path[0]:
+            del path[0]
+        if not path:
+            path = ['']
+        cmd = path[0]
+        args = path[1:]
+        method_to_call = getattr(self, "run_" + cmd, None)
+        if method_to_call is None:
+            self.send_error(404, "File %r not found" % (self.path,))
+        else:
+            method_to_call(*args, **kwds)
+    
+    do_POST = do_GET
+    
+    def run_(self):
+        self.run_index()
+    
+    def run_index(self):
+        self.serve_data("text/html", HTML_PAGE)
+
+    def run_MochiKit(self, filename):
+        assert filename in os.listdir('MochiKit')
+        pathname = os.path.join('MochiKit', filename)
+        f = open(pathname, 'r')
+        data = f.read()
+        f.close()
+        self.serve_data("text/javascript", data)
+    
+    def run_some_callback(self, cmd=[""]):
+        cmd = cmd[0]
+        if cmd:
+            buf = cStringIO.StringIO()
+            out1 = sys.stdout
+            err1 = sys.stderr
+            try:
+                sys.stdout = sys.stderr = buf
+                try:
+                    exec compile(cmd, '?', 'single') in self.server.locals
+                except Exception:
+                    import traceback
+                    traceback.print_exc()
+            finally:
+                sys.stdout = out1
+                sys.stderr = err1
+            answer = buf.getvalue()
+        else:
+            answer = ""
+        self.serve_data("text/json", repr({'answer': answer}))
+    
+    def run_jssource(self):
+        if self.server.source:
+            source = self.server.source
+        else:
+            source = js_source([setup_page])
+            self.server.source = source
+        self.serve_data("text/javascript", source)
+    
+    def serve_data(self, content_type, data):
+        self.send_response(200)
+        self.send_header("Content-type", content_type)
+        self.send_header("Content-length", len(data))
+        self.end_headers()
+        self.wfile.write(data)
+
+def _main(server_class=Server,
+          handler_class=RequestHandler):
+    global httpd
+
+    server_address = ('', 8000)
+    httpd = server_class(server_address, handler_class)
+    print 'http://127.0.0.1:%d' % (server_address[1],)
+    httpd.serve_forever()
+
+if __name__ == '__main__':
+    _main()



More information about the Pypy-commit mailing list