kopia lustrzana https://github.com/fellesverkstedet/fabmodules
370 wiersze
12 KiB
Python
Executable File
370 wiersze
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# fabserver.py
|
|
# command line syntax: python fabserver.py port
|
|
#
|
|
# Neil Gershenfeld
|
|
# CBA MIT 12/6/12
|
|
#
|
|
# (c) Massachusetts Institute of Technology 2012
|
|
# Permission granted for experimental and personal use;
|
|
# license for commercial sale available from MIT.
|
|
#
|
|
|
|
from socket import *
|
|
from string import *
|
|
from select import *
|
|
from math import *
|
|
import sys
|
|
import subprocess
|
|
import os
|
|
import glob
|
|
|
|
MAX_PACKET = 4096
|
|
MAX_RESPONSE = 10000000
|
|
PACKET_TIMEOUT = 0.01
|
|
|
|
SERVER_ADDRESS = "127.0.0.1"
|
|
|
|
def send_image(msg):
|
|
client_socket.sendall(
|
|
'HTTP/1.1 200 OK\n'
|
|
+'Content-Length: %d\n'%len(msg)
|
|
+'Content-Type: image/jpeg\n'
|
|
+'\n'
|
|
+msg
|
|
)
|
|
|
|
def send_text(text):
|
|
client_socket.sendall(
|
|
'HTTP/1.1 200 OK\n'
|
|
+'Content-Type: text/html\n'
|
|
+'\n'
|
|
+'\n'
|
|
+text
|
|
)
|
|
|
|
def parse():
|
|
global mode, units, dx, dy, dz, xmin, ymin, zmin, xrot, yrot, zrot, resolution, slices, expression
|
|
#
|
|
# parse math string
|
|
#
|
|
start = 0
|
|
start = 1+find(response,"{",start)
|
|
end = find(response,"}",start)
|
|
mode = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
units = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
dx = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
dy = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
dz = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
xmin = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
ymin = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
zmin = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
xrot = float(response[start:end])
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
yrot = float(response[start:end])
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
zrot = float(response[start:end])
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
resolution = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
slices = response[start:end]
|
|
start = 1+find(response,"{",end)
|
|
end = find(response,"}",start)
|
|
expression = response[start:end]
|
|
|
|
def render():
|
|
#
|
|
# render math string, xy view
|
|
#
|
|
math_file = open("fab_render_xy.math","w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+dx+" "+dy+" "+dz+"\n")
|
|
math_file.write("xmin ymin zmin: "+xmin+" "+ymin+" "+zmin+"\n")
|
|
math_file.write("expression: "+expression+"\n")
|
|
math_file.close()
|
|
os.system("math_png fab_render_xy.math fab_render_xy.png "+resolution+" "+slices)
|
|
os.system("rm fab_render_xy.math")
|
|
if (float(dz) != 0):
|
|
#
|
|
# xz view
|
|
#
|
|
math_file = open("fab_render_xz.math","w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+dx+" "+dz+" "+dy+"\n")
|
|
math_file.write("xmin ymin zmin: "+xmin+" "+zmin+" "+ymin+"\n")
|
|
math_file.write("expression: "+expression+"\n")
|
|
new_expression = replace(expression,'Y','#')
|
|
new_expression = replace(new_expression,'Z','Y')
|
|
new_expression = replace(new_expression,'#','Z')
|
|
math_file.write("expression: "+new_expression+"\n")
|
|
math_file.close()
|
|
os.system("math_png fab_render_xz.math fab_render_xz.png "+resolution+" "+slices)
|
|
os.system("rm fab_render_xz.math")
|
|
#
|
|
# zy view
|
|
#
|
|
math_file = open("fab_render_zy.math","w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+dz+" "+dy+" "+dx+"\n")
|
|
math_file.write("xmin ymin zmin: "+zmin+" "+ymin+" "+xmin+"\n")
|
|
new_expression = replace(expression,'X','#')
|
|
new_expression = replace(new_expression,'Z','((%f)-X)'%(float(dz)+2*float(zmin)))
|
|
new_expression = replace(new_expression,'#','Z')
|
|
math_file.write("expression: "+new_expression+"\n")
|
|
math_file.close()
|
|
os.system("math_png fab_render_zy.math fab_render_zy.png "+resolution+" "+slices)
|
|
os.system("rm fab_render_zy.math")
|
|
#
|
|
# xyz view
|
|
#
|
|
math_file = open("fab_render_xyz.math","w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+"2"+" "+"2"+" "+"2"+"\n")
|
|
math_file.write("xmin ymin zmin: "+"-1"+" "+"-1"+" "+"-1"+"\n")
|
|
#
|
|
# view scaling
|
|
#
|
|
-1
|
|
1
|
|
new_expression = replace(expression,'X','(('+xmin+')+'+dx+'*(X+1)/2)')
|
|
new_expression = replace(new_expression,'Y','(('+ymin+')+'+dy+'*(Y+1)/2)')
|
|
new_expression = replace(new_expression,'Z','(('+zmin+')+'+dz+'*(Z+1)/2)')
|
|
#new_expression = replace(expression,'X','(X+('+xmin+')+1)')
|
|
#new_expression = replace(new_expression,'Y','(Y+('+ymin+')+1)')
|
|
#new_expression = replace(new_expression,'Z','(Z+('+zmin+')+1)')
|
|
#
|
|
# z rotation
|
|
#
|
|
new_expression = replace(new_expression,'X','(('+str(cos(zrot))+')*X+('+str(-sin(zrot))+')*ytemp)')
|
|
new_expression = replace(new_expression,'Y','(('+str(sin(zrot))+')*X+('+str(cos(zrot))+')*Y)')
|
|
new_expression = replace(new_expression,'ytemp','Y')
|
|
#
|
|
# y rotation (not used in GUI)
|
|
#
|
|
#
|
|
# x rotation
|
|
#
|
|
new_expression = replace(new_expression,'Y','(('+str(cos(xrot))+')*Y+('+str(sin(xrot))+')*ztemp)')
|
|
new_expression = replace(new_expression,'Z','(('+str(-sin(xrot))+')*Y+('+str(cos(xrot))+')*Z)')
|
|
new_expression = replace(new_expression,'ztemp','Z')
|
|
#
|
|
# write and evaluate
|
|
#
|
|
math_file.write("expression: "+new_expression+"\n")
|
|
math_file.close()
|
|
os.system("math_png fab_render_xyz.math fab_render_xyz.png "+resolution+" "+slices)
|
|
os.system("rm fab_render_xyz.math")
|
|
#send_text("render")
|
|
|
|
#
|
|
# get command line arguments
|
|
#
|
|
if (len(sys.argv) != 2):
|
|
print "command line syntax: python fabserver.py port"
|
|
sys.exit()
|
|
server_port = sys.argv[1]
|
|
#
|
|
# start listening on server port
|
|
#
|
|
try:
|
|
server_socket = socket(AF_INET, SOCK_STREAM)
|
|
server_socket.bind((SERVER_ADDRESS,int(server_port)))
|
|
server_socket.listen(5)
|
|
print "listening on port "+server_port
|
|
except:
|
|
print "error: couldn't open socket"
|
|
sys.exit()
|
|
|
|
#
|
|
# start main loop
|
|
#
|
|
while 1:
|
|
#
|
|
# blocking select call to wait for a connection
|
|
#
|
|
[read_ready, write_ready, error_ready] = select([server_socket],[],[])
|
|
if (read_ready != []):
|
|
#
|
|
# child process, non-blocking select call to receive packet
|
|
#
|
|
(client_socket, client_address) = server_socket.accept()
|
|
response = ""
|
|
while 1:
|
|
[read_ready, write_ready, error_ready] = select([client_socket],[],[],PACKET_TIMEOUT)
|
|
if (read_ready != []):
|
|
response += client_socket.recv(MAX_PACKET)
|
|
else:
|
|
break
|
|
#
|
|
# process response
|
|
#
|
|
#print response
|
|
if (find(response,"GET / ") == 0):
|
|
#
|
|
# root request, send fab.html
|
|
#
|
|
file = open(os.path.join(os.path.dirname(sys.argv[0]), 'fab.html'),
|
|
'rb')
|
|
msg = file.read()
|
|
file.close()
|
|
send_text(msg)
|
|
elif (find(response,"GET /fab_render_xy.png") == 0):
|
|
try:
|
|
file = open('fab_render_xy.png','rb')
|
|
os.system("rm fab_render_xy.png")
|
|
msg = file.read()
|
|
file.close()
|
|
send_image(msg)
|
|
except IOError:
|
|
print "oops"
|
|
elif (find(response,"GET /fab_render_xz.png") == 0):
|
|
try:
|
|
file = open('fab_render_xz.png','rb')
|
|
os.system("rm fab_render_xz.png")
|
|
msg = file.read()
|
|
file.close()
|
|
send_image(msg)
|
|
except IOError:
|
|
print "oops"
|
|
elif (find(response,"GET /fab_render_zy.png") == 0):
|
|
try:
|
|
file = open('fab_render_zy.png','rb')
|
|
os.system("rm fab_render_zy.png")
|
|
msg = file.read()
|
|
file.close()
|
|
send_image(msg)
|
|
except IOError:
|
|
print "oops"
|
|
elif (find(response,"GET /fab_render_xyz.png") == 0):
|
|
try:
|
|
file = open('fab_render_xyz.png','rb')
|
|
os.system("rm fab_render_xyz.png")
|
|
msg = file.read()
|
|
file.close()
|
|
send_image(msg)
|
|
except IOError:
|
|
print "oops"
|
|
elif (find(response,"GET /fab.html") == 0):
|
|
file = open('fab.html','rb')
|
|
msg = file.read()
|
|
file.close()
|
|
send_text(msg)
|
|
elif (find(response,"GET /quit") == 0):
|
|
break
|
|
elif (find(response,"POST /list_files") == 0):
|
|
files = glob.glob('*.fab')
|
|
file_names = ','.join(files)
|
|
cwd = os.getcwd()
|
|
dirs = filter(os.path.isdir, os.listdir('.'))
|
|
dirs_names = ','.join(dirs)
|
|
send_text(file_names+';'+cwd+';'+dirs_names)
|
|
elif (find(response,"POST /cd") == 0):
|
|
start = 1+find(response,"{")
|
|
end = find(response,"}",start)
|
|
dir_name = response[start:end]
|
|
os.chdir(dir_name)
|
|
files = glob.glob('*.fab')
|
|
file_names = ','.join(files)
|
|
cwd = os.getcwd()
|
|
dirs = filter(os.path.isdir, os.listdir('.'))
|
|
dirs_names = ','.join(dirs)
|
|
send_text(file_names+';'+cwd+';'+dirs_names)
|
|
elif (find(response,"POST /delete") == 0):
|
|
start = 1+find(response,"{")
|
|
end = find(response,"}",start)
|
|
file_name = response[start:end]
|
|
os.remove(file_name)
|
|
files = glob.glob('*.fab')
|
|
file_names = ','.join(files)
|
|
cwd = os.getcwd()
|
|
dirs = filter(os.path.isdir, os.listdir('.'))
|
|
dirs_names = ','.join(dirs)
|
|
send_text(file_names+';'+cwd+';'+dirs_names)
|
|
elif (find(response,"POST /open") == 0):
|
|
start = 1+find(response,"{")
|
|
end = find(response,"}",start)
|
|
file_name = response[start:end]
|
|
print "file"+file_name+"name"
|
|
try:
|
|
file = open(file_name,'rb')
|
|
msg = file.read()
|
|
file.close()
|
|
send_text(msg)
|
|
except IOError:
|
|
print "oops"
|
|
elif (find(response,"POST /render") == 0):
|
|
#
|
|
# render
|
|
#
|
|
parse()
|
|
render()
|
|
elif (find(response,"POST /fabricate") == 0):
|
|
#
|
|
# fabricate
|
|
#
|
|
parse()
|
|
math_file = open("fab_render_xy.math","w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+dx+" "+dy+" "+dz+"\n")
|
|
math_file.write("xmin ymin zmin: "+xmin+" "+ymin+" "+zmin+"\n")
|
|
math_file.write("expression: "+expression+"\n")
|
|
math_file.close()
|
|
os.system("fab fab_render_xy.math")
|
|
os.system("rm fab_render_xy.math")
|
|
elif (find(response,"POST /save_graph") == 0):
|
|
start = 17+find(response,"POST /save_graph")
|
|
end = find(response,"/",start)
|
|
file_name = response[start:end]
|
|
file = open(file_name,"w")
|
|
start = find(response,"graph start:")
|
|
file.writelines(response[start:])
|
|
file.close()
|
|
client_socket.send("saved "+file_name)
|
|
elif (find(response,"POST /save_math") == 0):
|
|
start = 16+find(response,"POST /save_math")
|
|
end = find(response,"/",start)
|
|
file_name = response[start:end]
|
|
parse()
|
|
math_file = open(file_name,"w")
|
|
math_file.write("format: "+mode+"\n")
|
|
math_file.write("mm per unit: "+units+"\n")
|
|
math_file.write("dx dy dz: "+dx+" "+dy+" "+dz+"\n")
|
|
math_file.write("xmin ymin zmin: "+xmin+" "+ymin+" "+zmin+"\n")
|
|
math_file.write("expression: "+expression+"\n")
|
|
math_file.close()
|
|
client_socket.send("saved "+file_name)
|
|
#
|
|
# close connection socket and exit
|
|
#
|
|
client_socket.close()
|
|
#
|
|
# close server socket and exit
|
|
#
|
|
server_socket.close()
|