Commit 66c6f8d5 authored by Guillaume Seguin's avatar Guillaume Seguin

Merge branch 'experimental' of github.com:kliment/Printrun into experimental

parents f3fff426 871edba8
......@@ -102,6 +102,9 @@ class printcore():
self.stop_read_thread = True
self.read_thread.join()
self.read_thread = None
if self.print_thread:
self.printing = False
self.print_thread.join()
self._stop_sender()
try:
self.printer.close()
......
......@@ -25,7 +25,7 @@ gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|[a-z][-+]?[0-9]*\.?[0-9]*")
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|[A-Z]:?[-+]?[0-9]*\.?[0-9]*")
move_gcodes = ["G0", "G1", "G2", "G3"]
class Line(object):
class PyLine(object):
__slots__ = ('x','y','z','e','f','i','j','s','p',
'raw','split_raw',
......@@ -34,15 +34,26 @@ class Line(object):
'current_x', 'current_y', 'current_z', 'extruding', 'current_tool',
'gcview_end_vertex')
def __getattr__(self, name):
return None
try:
import gcoder_line
LineBase = gcoder_line.GLine
except ImportError:
LineBase = PyLine
class Line(LineBase):
__slots__ = ()
def __init__(self, l):
super(Line, self).__init__()
self.raw = l
self.split_raw = gcode_exp.findall(self.raw.lower())
self.command = self.split_raw[0].upper() if not self.split_raw[0].startswith("n") else self.split_raw[1].upper()
self.is_move = self.command in move_gcodes
def __getattr__(self, name):
return None
def parse_coordinates(self, imperial = False, force = False):
# Not a G-line, we don't want to parse its arguments
if not force and not self.command[0] == "G":
......@@ -407,6 +418,5 @@ def main():
print "Number of layers: %d" % gcode.num_layers()
print "Estimated duration: %s" % gcode.estimate_duration()
if __name__ == '__main__':
main()
# This file is copied from GCoder.
#
# GCoder is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GCoder is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
from libc.stdlib cimport malloc, free
from libc.stdint cimport uint32_t
cdef extern from "string.h":
char *strncpy(char *dest, char *src, size_t n)
size_t strlen(const char *s)
cdef char* copy_string(object value):
cdef char* orig = value
str_len = len(orig)
cdef char* array = <char *>malloc(str_len + 1)
strncpy(array, orig, str_len)
array[str_len] = 0;
return array
cdef enum BitPos:
pos_x = 1 << 0
pos_y = 1 << 1
pos_z = 1 << 2
pos_e = 1 << 3
pos_f = 1 << 4
pos_i = 1 << 5
pos_j = 1 << 6
pos_s = 1 << 7
pos_p = 1 << 8
pos_is_move = 1 << 9
pos_relative = 1 << 10
pos_relative_e = 1 << 11
pos_extruding = 1 << 12
pos_current_x = 1 << 13
pos_current_y = 1 << 14
pos_current_z = 1 << 15
pos_current_tool = 1 << 16
pos_raw = 1 << 17
pos_split_raw = 1 << 18
pos_command = 1 << 19
pos_gcview_end_vertex = 1 << 20
cdef inline uint32_t has_var(uint32_t status, uint32_t pos):
return status & pos
cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos):
return status | pos
cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos):
return status & ~pos
cdef class GLine(object):
cdef char* _raw
cdef char* _command
cdef object _split_raw
cdef float _x, _y, _z, _e, _f, _i, _j, _s, _p
cdef float _current_x, _current_y, _current_z
cdef uint32_t _gcview_end_vertex
cdef uint32_t _status
cdef char _current_tool
__slots__ = ()
def __cinit__(self):
self._status = 0
self._raw = NULL
self._command = NULL
def __dealloc__(self):
if self._raw != NULL: free(self._raw)
if self._command != NULL: free(self._command)
property x:
def __get__(self):
if has_var(self._status, pos_x): return self._x
else: return None
def __set__(self, value):
self._x = value
self._status = set_has_var(self._status, pos_x)
property y:
def __get__(self):
if has_var(self._status, pos_y): return self._y
else: return None
def __set__(self, value):
self._y = value
self._status = set_has_var(self._status, pos_y)
property z:
def __get__(self):
if has_var(self._status, pos_z): return self._z
else: return None
def __set__(self, value):
self._z = value
self._status = set_has_var(self._status, pos_z)
property e:
def __get__(self):
if has_var(self._status, pos_e): return self._e
else: return None
def __set__(self, value):
self._e = value
self._status = set_has_var(self._status, pos_e)
property f:
def __get__(self):
if has_var(self._status, pos_f): return self._f
else: return None
def __set__(self, value):
self._f = value
self._status = set_has_var(self._status, pos_f)
property i:
def __get__(self):
if has_var(self._status, pos_i): return self._i
else: return None
def __set__(self, value):
self._i = value
self._status = set_has_var(self._status, pos_i)
property j:
def __get__(self):
if has_var(self._status, pos_j): return self._j
else: return None
def __set__(self, value):
self._j = value
self._status = set_has_var(self._status, pos_j)
property s:
def __get__(self):
if has_var(self._status, pos_s): return self._s
else: return None
def __set__(self, value):
self._s = value
self._status = set_has_var(self._status, pos_s)
property p:
def __get__(self):
if has_var(self._status, pos_p): return self._p
else: return None
def __set__(self, value):
self._p = value
self._status = set_has_var(self._status, pos_p)
property is_move:
def __get__(self):
if has_var(self._status, pos_is_move): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_is_move)
else: self._status = unset_has_var(self._status, pos_is_move)
property relative:
def __get__(self):
if has_var(self._status, pos_relative): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_relative)
else: self._status = unset_has_var(self._status, pos_relative)
property relative_e:
def __get__(self):
if has_var(self._status, pos_relative_e): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_relative_e)
else: self._status = unset_has_var(self._status, pos_relative_e)
property extruding:
def __get__(self):
if has_var(self._status, pos_extruding): return True
else: return False
def __set__(self, value):
if value: self._status = set_has_var(self._status, pos_extruding)
else: self._status = unset_has_var(self._status, pos_extruding)
property current_x:
def __get__(self):
if has_var(self._status, pos_current_x): return self._current_x
else: return None
def __set__(self, value):
self._current_x = value
self._status = set_has_var(self._status, pos_current_x)
property current_y:
def __get__(self):
if has_var(self._status, pos_current_y): return self._current_y
else: return None
def __set__(self, value):
self._current_y = value
self._status = set_has_var(self._status, pos_current_y)
property current_z:
def __get__(self):
if has_var(self._status, pos_current_z): return self._current_z
else: return None
def __set__(self, value):
self._current_z = value
self._status = set_has_var(self._status, pos_current_z)
property current_tool:
def __get__(self):
if has_var(self._status, pos_current_tool): return self._current_tool
else: return None
def __set__(self, value):
self._current_tool = value
self._status = set_has_var(self._status, pos_current_tool)
property gcview_end_vertex:
def __get__(self):
if has_var(self._status, pos_gcview_end_vertex): return self._gcview_end_vertex
else: return None
def __set__(self, value):
self._gcview_end_vertex = value
self._status = set_has_var(self._status, pos_gcview_end_vertex)
property split_raw:
def __get__(self):
if has_var(self._status, pos_split_raw): return self._split_raw
else: return None
def __set__(self, value):
self._split_raw = value
self._status = set_has_var(self._status, pos_split_raw)
def __del__(self):
self._split_raw = None
property raw:
def __get__(self):
if has_var(self._status, pos_raw): return self._raw
else: return None
def __set__(self, value):
self._raw = copy_string(value)
self._status = set_has_var(self._status, pos_raw)
property command:
def __get__(self):
if has_var(self._status, pos_command): return self._command
else: return None
def __set__(self, value):
self._command = copy_string(value)
self._status = set_has_var(self._status, pos_command)
......@@ -269,7 +269,8 @@ class VizPane(wx.BoxSizer):
root.gviz = gviz.gviz(parentpanel, (300, 300),
build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width)
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gviz.SetToolTip(wx.ToolTip("Click to examine / edit\n layers of loaded file"))
root.gviz.showall = 1
root.gviz.Bind(wx.EVT_LEFT_DOWN, root.showwin)
......@@ -290,7 +291,8 @@ class VizPane(wx.BoxSizer):
root.gwindow = gviz.window([],
build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width)
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide())
if not isinstance(root.gviz, NoViz):
self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL)
......
......@@ -23,14 +23,14 @@ from printrun_utils import imagefile
ID_ABOUT = 101
ID_EXIT = 110
class window(wx.Frame):
def __init__(self, f, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5):
def __init__(self, f, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000"):
wx.Frame.__init__(self, None, title = "Gcode view, shift to move view, mousewheel to set layer", size = size)
self.CreateStatusBar(1);
self.SetStatusText("Layer number and Z position show here when you scroll");
panel = wx.Panel(self, -1)
self.p = gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, realparent = self)
self.p = gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, bgcolor = bgcolor, realparent = self)
vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(panel, -1, style = wx.TB_HORIZONTAL | wx.NO_BORDER)
......@@ -128,10 +128,12 @@ class gviz(wx.Panel):
self._showall = showall
showall = property(_get_showall, _set_showall)
def __init__(self, parent, size = (200, 200), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, realparent = None):
wx.Panel.__init__(self, parent, -1, size = size)
def __init__(self, parent, size = (200, 200), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000", realparent = None):
wx.Panel.__init__(self, parent, -1)
self.widget = self
self.SetMinSize((150, 150))
size = [max(1.0, x) for x in size]
ratio = size[0] / size[1]
self.SetMinSize((150, 150/ratio))
self.parent = realparent if realparent else parent
self.size = size
self.build_dimensions = build_dimensions
......@@ -163,7 +165,9 @@ class gviz(wx.Panel):
self.hilightqueue = Queue(0)
self.hilightarcsqueue = Queue(0)
self.dirty = 1
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1],-1)
self.bgcolor = wx.Colour()
self.bgcolor.SetFromName(bgcolor)
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1)
def inject(self):
#import pdb; pdb.set_trace()
......@@ -217,11 +221,10 @@ class gviz(wx.Panel):
float(self.size[1] - 1)/self.build_dimensions[1])]
def resize(self, event):
oldside = max(1.0, min(self.size))
old_basescale = self.basescale
self.size = self.GetClientSizeTuple()
self.update_basescale()
newside = max(1.0, min(self.size))
zoomratio = float(newside) / oldside
zoomratio = float(self.basescale[0]) / old_basescale[0]
wx.CallLater(200, self.zoom, 0, 0, zoomratio)
def zoom(self, x, y, factor):
......@@ -230,8 +233,8 @@ class gviz(wx.Panel):
x = y = side / 2
self.scale = [s * factor for s in self.scale]
self.translate = [ x - (x-self.translate[0]) * factor,
y - (y-self.translate[1]) * factor]
self.translate = [x - (x - self.translate[0]) * factor,
y - (y - self.translate[1]) * factor]
penwidth = max(1.0, self.filament_width*((self.scale[0]+self.scale[1])/2.0))
for pen in self.penslist:
pen.SetWidth(penwidth)
......@@ -239,18 +242,18 @@ class gviz(wx.Panel):
wx.CallAfter(self.Refresh)
def _line_scaler(self, x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],)
return (self.scale[0]*x[0],
self.scale[1]*x[1],
self.scale[0]*x[2],
self.scale[1]*x[3],)
def _arc_scaler(self, x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],
self.scale[0]*x[4]+self.translate[0],
self.scale[1]*x[5]+self.translate[1],)
return (self.scale[0]*x[0],
self.scale[1]*x[1],
self.scale[0]*x[2],
self.scale[1]*x[3],
self.scale[0]*x[4],
self.scale[1]*x[5],)
def _drawlines(self, dc, lines, pens):
scaled_lines = map(self._line_scaler, lines)
......@@ -264,7 +267,9 @@ class gviz(wx.Panel):
dc.DrawArc(*scaled_arcs[i])
def repaint_everything(self):
self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1],-1)
width = self.scale[0]*self.build_dimensions[0]
height = self.scale[1]*self.build_dimensions[1]
self.blitmap = wx.EmptyBitmap(width + 1, height + 1, -1)
dc = wx.MemoryDC()
dc.SelectObject(self.blitmap)
dc.SetBackground(wx.Brush((250, 250, 200)))
......@@ -273,9 +278,11 @@ class gviz(wx.Panel):
for grid_unit in self.grid:
if grid_unit > 0:
for x in xrange(int(self.build_dimensions[0]/grid_unit)+1):
dc.DrawLine(self.translate[0]+x*self.scale[0]*grid_unit, self.translate[1], self.translate[0]+x*self.scale[0]*grid_unit, self.translate[1]+self.scale[1]*self.build_dimensions[1])
draw_x = self.scale[0]*x*grid_unit
dc.DrawLine(draw_x, 0, draw_x, height)
for y in xrange(int(self.build_dimensions[1]/grid_unit)+1):
dc.DrawLine(self.translate[0], self.translate[1]+y*self.scale[1]*grid_unit, self.translate[0]+self.scale[0]*self.build_dimensions[0], self.translate[1]+y*self.scale[1]*grid_unit)
draw_y = self.scale[1]*(self.build_dimensions[1]-y*grid_unit)
dc.DrawLine(0, draw_y, width, draw_y)
dc.SetPen(wx.Pen(wx.Colour(0, 0, 0)))
if not self.showall:
......@@ -327,7 +334,9 @@ class gviz(wx.Panel):
self.repaint_everything()
self.paint_hilights()
dc = wx.PaintDC(self)
dc.DrawBitmap(self.blitmap, 0, 0)
dc.SetBackground(wx.Brush(self.bgcolor))
dc.Clear()
dc.DrawBitmap(self.blitmap, self.translate[0], self.translate[1])
def addfile(self, gcode):
self.clear()
......
This diff is collapsed.
......@@ -3,8 +3,10 @@
import tornado.ioloop
import tornado.web
import tornado.websocket
from tornado.web import asynchronous
from tornado import gen
import tornado.httpserver
import uuid
import time
import base64
import logging
......@@ -90,12 +92,51 @@ class StopHandler(tornado.web.RequestHandler):
prontserve.do_stop()
self.finish("ACK")
@tornado.web.stream_body
class JobsHandler(tornado.web.RequestHandler):
def post(self):
self.read_bytes = 0
self.total_bytes = self.request.content_length
self.body = ''
print self.request
session_uuid = self.get_argument("session_uuid", None)
print "me"
print session_uuid
print "them"
self.websocket = None
for c in ConstructSocketHandler.clients:
print c.session_uuid
if c.session_uuid == session_uuid: self.websocket = c
self.request.request_continue()
self.read_chunks()
def read_chunks(self, chunk=''):
self.read_bytes += len(chunk)
self.body += chunk
if chunk: self.process_chunk()
chunk_length = min(100000, self.request.content_length - self.read_bytes)
if chunk_length > 0:
self.request.connection.stream.read_bytes(
chunk_length, self.read_chunks)
else:
self.request._on_request_body(self.body, self.uploaded)
def process_chunk(self):
print self.get_argument("session_uuid", None)
print "bytes: (%i / %i)"%(self.read_bytes, self.total_bytes)
msg = {'uploaded': self.read_bytes, 'total': self.total_bytes}
if self.websocket != None:
self.websocket.send(job_upload_progress_changed = msg)
def uploaded(self):
fileinfo = self.request.files['job'][0]
prontserve.do_add_job(fileinfo['filename'], fileinfo['body'])
self.finish("ACK")
class JobHandler(tornado.web.RequestHandler):
def delete(self, job_id):
prontserve.do_rm_job(job_id)
......@@ -116,6 +157,7 @@ class InspectHandler(tornado.web.RequestHandler):
#class EchoWebSocketHandler(tornado.web.RequestHandler):
class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
clients = []
def on_sensor_changed(self):
for name in ['bed', 'extruder']:
......@@ -141,6 +183,8 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
return "construct.text.0.0.1"
def open(self):
self.session_uuid = str(uuid.uuid4())
self.clients.append(self)
prontserve.listeners.add(self)
self.write_message({'headers': {
'jobs': prontserve.jobs.public_list(),
......@@ -151,6 +195,7 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
for k, v in prontserve.target_values.iteritems():
self.on_uncaught_event("target_temp_changed", {k: v})
self.on_uncaught_event("job_progress_changed", prontserve.previous_job_progress)
self.send(initialized= {'session_uuid': self.session_uuid} )
print "WebSocket opened. %i sockets currently open." % len(prontserve.listeners)
def send(self, dict_args = {}, **kwargs):
......@@ -196,15 +241,15 @@ class ConstructSocketHandler(tornado.websocket.WebSocketHandler):
try:
if cmd == "set": cmd = "construct_set"
response = getattr(prontserve, "do_%s"%cmd)(*args, **kwargs)
print response
if response is not None: self.write_message(response)
except:
self.write_message({"ack": response})
except Exception as ex:
print traceback.format_exc()
self.write_message({"error": "bad command."})
self.write_message({"error": str(ex)})
else:
self.write_message({"error": "%s command does not exist."%cmd})
def on_close(self):
self.clients.remove(self)
prontserve.listeners.remove(self)
print "WebSocket closed. %i sockets currently open." % len(prontserve.listeners)
......@@ -253,6 +298,7 @@ class EventEmitter(object):
class Prontserve(pronsole.pronsole, EventEmitter):
def __init__(self, **kwargs):
self.initializing = True
pronsole.pronsole.__init__(self)
EventEmitter.__init__(self)
self.settings.sensor_names = {'T': 'extruder', 'B': 'bed'}
......@@ -270,8 +316,10 @@ class Prontserve(pronsole.pronsole, EventEmitter):
self.current_job = None
self.previous_job_progress = 0
self.silent = True
self._sensor_update_received = True
self.init_mdns()
self.jobs.listeners.add(self)
self.initializing = False
def init_mdns(self):
sdRef = pybonjour.DNSServiceRegister(name = None,
......@@ -284,7 +332,7 @@ class Prontserve(pronsole.pronsole, EventEmitter):
sdRef.close()
def do_print(self):
if not self.p.online: raise "not online"
if not self.p.online: raise Exception("not online")
self.printing_jobs = True
def do_home(self, *args, **kwargs):
......@@ -315,7 +363,7 @@ class Prontserve(pronsole.pronsole, EventEmitter):
pronsole.pronsole.do_move(self, cmd )
def do_stop_move(self):
raise "Continuous movement not supported"
raise Exception("Continuous movement not supported")
def do_estop(self):
pronsole.pronsole.do_pause(self, "")
......@@ -403,7 +451,16 @@ class Prontserve(pronsole.pronsole, EventEmitter):
self.previous_job_progress = progress
self.fire("job_progress_changed", progress)
def print_progress(self):
if(self.p.printing):
return 100*float(self.p.queueindex)/len(self.p.mainqueue)
if(self.sdprinting):
return self.percentdone
return 0
def run_sensor_loop(self):
if self._sensor_update_received:
self._sensor_update_received = False
if self.dry_run:
self._receive_sensor_update("ok T:%i"%random.randint(20, 50))
else:
......@@ -423,20 +480,11 @@ class Prontserve(pronsole.pronsole, EventEmitter):
if l!="ok" and not l.startswith("ok T") and not l.startswith("T:"):
self._receive_printer_error(l)
def print_progress(self):
if(self.p.printing):
return 100*float(self.p.queueindex)/len(self.p.mainqueue)
if(self.sdprinting):
return self.percentdone
return 0
def _receive_sensor_update(self, l):
self._sensor_update_received = True
words = filter(lambda s: s.find(":") > 0, l.split(" "))
d = dict([ s.split(":") for s in words])
# print "sensor update received!"
for key, value in d.iteritems():
self.__update_sensor(key, value)
......@@ -457,9 +505,17 @@ class Prontserve(pronsole.pronsole, EventEmitter):
print msg
self.fire("log", {'msg': msg, 'level': "debug"})
def logError(self, *msg):
print u"".join(unicode(i) for i in msg)
if self.initializing == False:
raise Exception(u"".join(unicode(i) for i in msg))
def write_prompt(self):
None
def confirm(self):
True
class PrintJobQueue(EventEmitter):
......@@ -548,6 +604,10 @@ if __name__ == "__main__":
help='Does not connect to the 3D printer'
)
parser.add_argument('--loud', default=False, action='store_true',
help='Enables verbose printer output'
)
args = parser.parse_args()
dry_run = args.dry_run
......@@ -557,9 +617,23 @@ if __name__ == "__main__":
sys.stdout.write("\x1B[0;33m Dry Run \x1B[0m")
print ""
print "Prontserve is starting..."
prontserve = Prontserve(dry_run=dry_run)
if dry_run==False: prontserve.do_connect("")
prontserve.p.loud = args.loud
try:
if dry_run==False:
prontserve.do_connect("")
if prontserve.p.printer == None: sys.exit(1)
print "Connecting to printer..."
for x in range(0,50-1):
if prontserve.p.online == True: break
sys.stdout.write(".")
sys.stdout.flush()
time.sleep(0.1)
print ""
if prontserve.p.online == False:
print "Unable to connect to printer: Connection timed-out."
sys.exit(1)
time.sleep(1)
prontserve.run_sensor_loop()
......@@ -577,7 +651,6 @@ if __name__ == "__main__":
warn_if_dry_run()
print "-"*80 + "\n"
try:
prontserve.ioloop.start()
except:
prontserve.p.disconnect()
......@@ -89,5 +89,3 @@ def interceptor(func):
cls._execute = wrapper(cls._execute)
return cls
return classwrapper
print "moo"
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
.morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}
.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -10,12 +10,12 @@
<div class="lead-box">
<h1>
Your printer just got a whole lot better.
Prontserve BETA is Online
</h1>
<p class="lead">
Prontserve is ready to print. Why not try it out with
<a href="/inspect">Inspector</a> or
<a href="https://github.com/D1plo1d/ctrlpanel">Ctrl Panel</a>?
<a href="https://github.com/D1plo1d/tegh">Tegh</a>?
</p>
</div>
......
......@@ -2,8 +2,8 @@
<html>
<head>
<title>Prontserve Inspector</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
<link rel="stylesheet" href="http://cdn.oesmith.co.uk/morris-0.4.1.min.css">
<link href="/static/vendor/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="/static/vendor/css/morris-0.4.1.min.css" rel="stylesheet">
<link href="/static/css/inspect.css" rel="stylesheet">
</head>
......@@ -46,11 +46,11 @@
<div class="focus-lost-overlay modal-backdrop fade out hide"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sugar/1.3.9/sugar.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="http://cdn.oesmith.co.uk/morris-0.4.1.min.js"></script>
<script src="/static/vendor/js/jquery-1.9.1.min.js"></script>
<script src="/static/vendor/js/bootstrap.min.js"></script>
<script src="/static/vendor/js/sugar.min.js"></script>
<script src="/static/vendor/js/raphael-min.js"></script>
<script src="/static/vendor/js/morris-0.4.1.min.js"></script>
<script src="/static/js/inspect.js"></script>
</body>
......
......@@ -21,6 +21,11 @@ from stat import *
from distutils.core import setup
from distutils.command.install import install as _install
from distutils.command.install_data import install_data as _install_data
try:
from Cython.Build import cythonize
extensions = cythonize("printrun/gcoder_line.pyx")
except ImportError:
extensions = None
INSTALLED_FILES = "installed_files"
......@@ -84,7 +89,7 @@ class uninstall (_install):
except:
self.warn ("Could not remove file %s" % file)
ops = ("install", "build", "sdist", "uninstall", "clean")
ops = ("install", "build", "sdist", "uninstall", "clean", "build_ext")
if len (sys.argv) < 2 or sys.argv[1] not in ops:
print "Please specify operation : %s" % " | ".join (ops)
......@@ -148,5 +153,6 @@ setup (
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall,
"install" : install,
"install_data" : install_data}
"install_data" : install_data},
ext_modules = extensions,
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment