Skip to content

Commit a8ee64d

Browse files
author
hartsantler
committed
added Tornado test server that automatically converts python scripts into javascript.
1 parent 83bfb40 commit a8ee64d

3 files changed

Lines changed: 192 additions & 1 deletion

File tree

bindings/three.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# THREE.js wrapper for PythonScript
22
# by Brett Hartshorn - copyright 2013
3-
# License: "New" BSD
3+
# License: PSFLv2 - http://www.python.org/psf/license/
4+
5+
6+
class _Vector3:
7+
def __init__(self, jsobject=None):
8+
self._vec = jsobject
49

510
class _ObjectBase:
611
def add(self, child):

tests/helloworld.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<html>
2+
<head>
3+
<script src="pythonscript.js"></script>
4+
5+
<script type="text/python">
6+
def test():
7+
print('hello world')
8+
9+
</script>
10+
</head>
11+
12+
<body>
13+
<button onclick="test()">click me</button>
14+
</body>
15+
</html>

tests/server.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/python3
2+
# Test Server for PythonScript
3+
# by Brett Hartshorn - copyright 2013
4+
# License: PSFLv2 - http://www.python.org/psf/license/
5+
# Requires: Python3 and Tornado
6+
7+
try:
8+
import tornado
9+
except ImportError:
10+
print('ERROR: Tornado is not installed')
11+
print('download Tornado from - http://www.tornadoweb.org/en/stable/')
12+
raise SystemExit
13+
14+
import tornado.ioloop
15+
import tornado.web
16+
import os, subprocess
17+
18+
PATHS = dict(
19+
webroot = os.path.dirname(os.path.abspath(__file__)),
20+
pythonscript = os.path.abspath('../pythonscript'),
21+
bindings = os.path.abspath('../bindings'),
22+
closure = os.path.expanduser( '~/closure-compiler/compiler.jar'),
23+
runtime = os.path.abspath('../pythonscript.js'),
24+
)
25+
26+
27+
def python_to_pythonjs( src ):
28+
p = subprocess.Popen(
29+
['python2', os.path.join( PATHS['pythonscript'], 'python_to_pythonjs.py')],
30+
stdin = subprocess.PIPE,
31+
stdout = subprocess.PIPE
32+
)
33+
stdout, stderr = p.communicate( src.encode('utf-8') )
34+
return stdout.decode('utf-8')
35+
36+
def pythonjs_to_javascript( src, closure_compiler=False ):
37+
p = subprocess.Popen(
38+
['python2', os.path.join( PATHS['pythonscript'],'pythonjs.py')],
39+
stdin = subprocess.PIPE,
40+
stdout = subprocess.PIPE
41+
)
42+
stdout, stderr = p.communicate( src.encode('utf-8') )
43+
a = stdout.decode('utf-8')
44+
45+
if closure_compiler and os.path.isfile( PATHS['closure'] ):
46+
x = '/tmp/input.js'; y = '/tmp/output.js'
47+
f = open(x, 'wb'); f.write( a.encode('utf-8') ); f.close()
48+
subprocess.call( ['java', '-jar', PATHS['closure'], '--compilation_level', 'ADVANCED_OPTIMIZATIONS', '--js', x, '--js_output_file', y] )
49+
f = open(y, 'rb'); a = f.read().decode('utf-8'); f.close()
50+
51+
return a
52+
53+
def python_to_javascript( src, closure_compiler=False ):
54+
a = python_to_pythonjs( src )
55+
return pythonjs_to_javascript( a, closure_compiler=closure_compiler )
56+
57+
58+
59+
#########################################################
60+
def get_main_page():
61+
root = PATHS['webroot']
62+
r = ['<html><head><title>index</title></head><body>']
63+
r.append( '<ul>' )
64+
for name in os.listdir( root ):
65+
if name == os.path.split(__file__)[-1]: continue
66+
path = os.path.join( root, name )
67+
if os.path.isfile( path ):
68+
r.append( '<a href="%s"><li>%s</li></a>' %(name,name) )
69+
r.append('</ul>')
70+
r.append('</body></html>')
71+
return ''.join(r)
72+
73+
74+
def convert_python_html_document( data ):
75+
'''
76+
rewrites html document, converts python scripts into javascript.
77+
example:
78+
<script type="text/python" closure="true">
79+
print("hello world")
80+
</script>
81+
'''
82+
doc = list()
83+
script = None
84+
use_closure = False
85+
for line in data.splitlines():
86+
if line.strip().startswith('<script') and 'type="text/python"' in line:
87+
if 'closure="true"' in line.lower(): use_closure = True
88+
else: use_closure = False
89+
doc.append( '<script type="text/javascript">')
90+
script = list()
91+
92+
elif line.strip() == '</script>':
93+
if script:
94+
src = '\n'.join( script )
95+
js = python_to_javascript( src, closure_compiler=use_closure )
96+
doc.append( js )
97+
doc.append( line )
98+
script = None
99+
100+
elif isinstance( script, list ):
101+
script.append( line )
102+
103+
else:
104+
doc.append( line )
105+
106+
return '\n'.join( doc )
107+
108+
class MainHandler( tornado.web.RequestHandler ):
109+
def get(self, path=None):
110+
print('path', path)
111+
if not path:
112+
self.write( get_main_page() )
113+
elif path == 'pythonscript.js':
114+
data = open( PATHS['runtime'], 'rb').read()
115+
self.set_header("Content-Type", "text/javascript; charset=utf-8")
116+
self.set_header("Content-Length", len(data))
117+
self.write(data)
118+
elif path.startswith('bindings/'):
119+
name = path.split('/')[-1]
120+
local_path = os.path.join( PATHS['bindings'], name )
121+
122+
if os.path.isfile( local_path ):
123+
data = open(local_path, 'rb').read()
124+
else:
125+
raise tornado.web.HTTPError(404)
126+
127+
if path.endswith('.py'):
128+
data = python_to_javascript( data.decode('utf-8'), closure_compiler=False )
129+
130+
self.set_header("Content-Type", "text/javascript; charset=utf-8")
131+
self.set_header("Content-Length", len(data))
132+
self.write( data )
133+
134+
else:
135+
local_path = os.path.join( PATHS['webroot'], path )
136+
if os.path.isfile( local_path ):
137+
data = open(local_path, 'rb').read()
138+
if path.endswith( '.html' ):
139+
data = convert_python_html_document( data.decode('utf-8') )
140+
self.set_header("Content-Type", "text/html; charset=utf-8")
141+
elif path.endswith('.py'):
142+
data = python_to_javascript( data.decode('utf-8'), closure_compiler=True )
143+
self.set_header("Content-Type", "text/html; charset=utf-8")
144+
145+
self.set_header("Content-Length", len(data))
146+
self.write( data )
147+
148+
else:
149+
self.write('Hello World')
150+
151+
152+
Handlers = [
153+
(r'/(.*)', MainHandler)
154+
]
155+
156+
157+
if __name__ == '__main__':
158+
assert os.path.isfile( PATHS['runtime'] )
159+
assert os.path.isdir( PATHS['pythonscript'] )
160+
assert os.path.isdir( PATHS['bindings'] )
161+
162+
app = tornado.web.Application(
163+
Handlers,
164+
#cookie_secret = 'some random text',
165+
#login_url = '/login',
166+
#xsrf_cookies = False,
167+
)
168+
169+
170+
app.listen( 8080 )
171+
tornado.ioloop.IOLoop.instance().start()

0 commit comments

Comments
 (0)