Merge pull request #264 from iXce/experimental

Build system and CLI switch to request webinterface
master
kliment 2012-09-05 00:40:22 -07:00
commit 7e2e6a519f
34 changed files with 306 additions and 3191 deletions

File diff suppressed because it is too large Load Diff

View File

@ -17,12 +17,10 @@
# Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows)
import os, gettext, Queue, re
import os, Queue, re
if os.path.exists('/usr/share/pronterface/locale'):
gettext.install('plater', '/usr/share/pronterface/locale', unicode=1)
else:
gettext.install('plater', './locale', unicode=1)
from printrun.printrun_utils import install_locale
install_locale('plater')
import wx
import time
@ -31,12 +29,13 @@ import threading
import math
import sys
import stltool
from printrun import stltool
from printrun.printrun_utils import pixmapfile
glview = False
if "-nogl" not in sys.argv:
try:
import stlview
from printrun import stlview
glview = True
except:
pass
@ -245,7 +244,7 @@ class showstl(wx.Window):
class stlwin(wx.Frame):
def __init__(self, size=(800, 580), callback=None, parent=None):
wx.Frame.__init__(self, parent, title=_("Plate building tool"), size=size)
self.SetIcon(wx.Icon("plater.ico", wx.BITMAP_TYPE_ICO))
self.SetIcon(wx.Icon(pixmapfile("plater.ico"), wx.BITMAP_TYPE_ICO))
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel = wx.Panel(self, -1, size=(150, 600), pos=(0, 0))
#self.panel.SetBackgroundColour((10, 10, 10))

View File

@ -13,6 +13,9 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx,time
from printrun_utils import imagefile
ID_ABOUT = 101
ID_EXIT = 110
class window(wx.Frame):
@ -22,11 +25,11 @@ class window(wx.Frame):
vbox = wx.BoxSizer(wx.VERTICAL)
toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
toolbar.AddSimpleTool(1, wx.Image('./images/zoom_in.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom In [+]', '')
toolbar.AddSimpleTool(2, wx.Image('./images/zoom_out.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom Out [-]', '')
toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom In [+]', '')
toolbar.AddSimpleTool(2, wx.Image(imagefile('zoom_out.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom Out [-]', '')
toolbar.AddSeparator()
toolbar.AddSimpleTool(3, wx.Image('./images/arrow_up.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Move Up a Layer [U]', '')
toolbar.AddSimpleTool(4, wx.Image('./images/arrow_down.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Move Down a Layer [D]', '')
toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Move Up a Layer [U]', '')
toolbar.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Move Down a Layer [D]', '')
toolbar.AddSimpleTool(5, wx.EmptyBitmap(16,16), 'Reset view', '')
toolbar.AddSeparator()
#toolbar.AddSimpleTool(5, wx.Image('./images/inject.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Insert Code at start of this layer', '')

View File

@ -0,0 +1,37 @@
import os
import gettext
def install_locale(domain):
if os.path.exists('/usr/share/pronterface/locale'):
gettext.install(domain, '/usr/share/pronterface/locale', unicode=1)
elif os.path.exists('/usr/local/share/pronterface/locale'):
gettext.install(domain, '/usr/local/share/pronterface/locale', unicode=1)
else:
gettext.install(domain, './locale', unicode=1)
def imagefile(filename):
for prefix in ['/usr/local/share/pronterface/images', '/usr/share/pronterface/images']:
candidate = os.path.join(prefix, filename)
if os.path.exists(candidate):
return candidate
local_candidate = os.path.join(os.path.dirname(__file__), "images", filename)
if os.path.exists(local_candidate):
return local_candidate
else:
return os.path.join(os.path.split(os.path.split(__file__)[0])[0], "images", filename)
def lookup_file(filename, prefixes):
for prefix in prefixes:
candidate = os.path.join(prefix, filename)
if os.path.exists(candidate):
return candidate
return filename
def pixmapfile(filename):
return lookup_file(filename, ['/usr/local/share/pixmaps', '/usr/share/pixmaps'])
def sharedfile(filename):
return lookup_file(filename, ['/usr/local/share/pronterface', '/usr/share/pronterface'])
def configfile(filename):
return lookup_file(filename, [os.path.expanduser("~/.printrun/"),])

View File

@ -1,7 +1,10 @@
#!/usr/bin/python
import cherrypy, pronterface, re, ConfigParser, threading, sys
import pronterface
import cherrypy, re, ConfigParser, threading, sys
import os.path
from printrun.printrun_utils import configfile, imagefile, sharedfile
users = {}
def PrintHeader():
@ -238,7 +241,7 @@ class WebInterface(object):
config = ConfigParser.SafeConfigParser(allow_no_value=True)
else:
config = ConfigParser.SafeConfigParser()
config.read('auth.config')
config.read(configfile(pface.web_auth_config or 'auth.config'))
users[config.get("user", "user")] = config.get("user", "pass")
self.pface = pface
global gPronterPtr
@ -358,19 +361,19 @@ def KillWebInterfaceThread():
def StartWebInterfaceThread(webInterface):
current_dir = os.path.dirname(os.path.abspath(__file__))
cherrypy.config.update({'engine.autoreload_on':False})
cherrypy.config.update("http.config")
cherrypy.config.update(configfile(webInterface.pface.web_config or "http.config"))
conf = {'/css/style.css': {'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.join(current_dir, 'css/style.css'),
'tools.staticfile.filename': sharedfile('css/style.css'),
},
'/images/control_xy.png': {'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.join(current_dir, 'images/control_xy.png'),
'tools.staticfile.filename': imagefile('control_xy.png'),
},
'/images/control_z.png': {'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.join(current_dir, 'images/control_z.png'),
'tools.staticfile.filename': imagefile('control_z.png'),
}}
cherrypy.config.update("http.config")
cherrypy.config.update(configfile(webInterface.pface.web_config or "http.config"))
cherrypy.quickstart(webInterface, '/', config=conf)
if __name__ == '__main__':
cherrypy.config.update("http.config")
cherrypy.config.update(configfile("http.config"))
cherrypy.quickstart(WebInterfaceStub())

View File

@ -15,14 +15,8 @@
import wx, os, math
from bufferedcanvas import *
from printrun_utils import *
def imagefile(filename):
if os.path.exists(os.path.join(os.path.dirname(__file__), "images", filename)):
return os.path.join(os.path.dirname(__file__), "images", filename)
else:
return os.path.join(os.path.split(os.path.split(__file__)[0])[0], "images", filename)
def sign(n):
if n < 0: return -1
elif n > 0: return 1

View File

@ -15,14 +15,7 @@
import wx, os, math
from bufferedcanvas import *
def imagefile(filename):
if os.path.exists(os.path.join(os.path.dirname(__file__), "images", filename)):
return os.path.join(os.path.dirname(__file__), "images", filename)
else:
return os.path.join(os.path.split(os.path.split(__file__)[0])[0], "images", filename)
from printrun_utils import *
def sign(n):
if n < 0: return -1

View File

@ -15,16 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import cmd, printcore, sys
import cmd, sys
import glob, os, time
import sys, subprocess
import math, codecs
from math import sqrt
import gettext
if os.path.exists('/usr/share/pronterface/locale'):
gettext.install('pronterface', '/usr/share/pronterface/locale', unicode=1)
else:
gettext.install('pronterface', './locale', unicode=1)
from printrun import printcore
from printrun.printrun_utils import install_locale
install_locale('pronterface')
if os.name=="nt":
try:
@ -277,6 +276,9 @@ class pronsole(cmd.Cmd):
self.helpdict["z_feedrate"] = _("Feedrate for Control Panel Moves in Z (default: 200mm/min)")
self.helpdict["final_command"] = _("Executable to run when the print is finished")
self.commandprefixes='MGT$'
self.webrequested=False
self.web_config=None
self.web_auth_config=None
def set_temp_preset(self,key,value):
if not key.startswith("bed"):
@ -1216,11 +1218,17 @@ class pronsole(cmd.Cmd):
def parse_cmdline(self,args):
import getopt
opts,args = getopt.getopt(args, "c:e:h", ["conf=","config=","help"])
opts,args = getopt.getopt(args, "c:e:hw", ["conf=","config=","help","web","web-config=", "web-auth-config="])
for o,a in opts:
#print repr((o,a))
if o in ("-c","--conf","--config"):
self.load_rc(a)
elif o in ("-w","--web"):
self.webrequested = True
elif o == "--web-config":
self.web_config = a
elif o == "--web-auth-config":
self.web_auth_config = a
elif o in ("-h","--help"):
print "Usage: "+sys.argv[0]+' [-c filename [-c filename2 ... ] ] [-e "command" ...]'
print " -c | --conf | --config - override startup .pronsolerc file"

View File

@ -17,23 +17,18 @@
# Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows)
import os, gettext, Queue, re
import os, Queue, re
if os.path.exists('/usr/share/pronterface/locale'):
gettext.install('pronterface', '/usr/share/pronterface/locale', unicode=1)
else:
gettext.install('pronterface', './locale', unicode=1)
from printrun.printrun_utils import install_locale
install_locale('pronterface')
try:
import wx
except:
print _("WX is not installed. This program requires WX to run.")
raise
import printcore, sys, glob, time, threading, traceback, gviz, traceback, cStringIO, subprocess
try:
os.chdir(os.path.split(__file__)[0])
except:
pass
import sys, glob, time, threading, traceback, cStringIO, subprocess
StringIO=cStringIO
thread=threading.Thread
@ -49,24 +44,19 @@ if os.name=="nt":
pass
from xybuttons import XYButtons
from zbuttons import ZButtons
from graph import Graph
from printrun import printcore, gviz
from printrun.xybuttons import XYButtons
from printrun.zbuttons import ZButtons
from printrun.graph import Graph
from printrun.printrun_utils import pixmapfile, configfile
import pronsole
webavail = False
try :
if webavail:
import cherrypy, webinterface
from threading import Thread
except:
print _("CherryPy is not installed. Web Interface Disabled.")
webavail = False
def dosify(name):
return os.path.split(name)[1].split(".")[0][:8]+".g"
def parse_temperature_report(report, key):
return float(filter(lambda x: x.startswith(key), report.split())[0].split(":")[1].split("/")[0])
class Tee(object):
def __init__(self, target):
self.stdout = sys.stdout
@ -106,7 +96,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.filename=filename
os.putenv("UBUNTU_MENUPROXY","0")
wx.Frame.__init__(self,None,title=_("Printer Interface"),size=size);
self.SetIcon(wx.Icon("P-face.ico",wx.BITMAP_TYPE_ICO))
self.SetIcon(wx.Icon(pixmapfile("P-face.ico"),wx.BITMAP_TYPE_ICO))
self.panel=wx.Panel(self,-1,size=size)
self.statuscheck=False
@ -135,7 +125,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.panel.SetBackgroundColour(self.settings.bgcolor)
customdict={}
try:
execfile("custombtn.txt",customdict)
execfile(configfile("custombtn.txt"),customdict)
if len(customdict["btns"]):
if not len(self.custombuttons):
try:
@ -169,11 +159,22 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.cur_button=None
self.hsetpoint=0.0
self.bsetpoint=0.0
if webavail:
self.webInterface=webinterface.WebInterface(self)
self.webThread = Thread(target=webinterface.StartWebInterfaceThread, args=(self.webInterface, ))
self.webThread.start()
if(self.filename is not None):
self.webInterface=None
if self.webrequested:
try :
import cherrypy
from printrun import webinterface
except:
print _("CherryPy is not installed. Web Interface Disabled.")
try:
self.webInterface=webinterface.WebInterface(self)
self.webThread=threading.Thread(target=webinterface.StartWebInterfaceThread, args=(self.webInterface, ))
self.webThread.start()
except:
print _("Failed to start web interface")
traceback.print_exc(file = sys.stdout)
self.webInterface = None
if self.filename is not None:
self.do_load(self.filename)
def startcb(self):
@ -272,7 +273,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
#self.bedtgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetBedTargetTemperature,int(f))
if f>0:
wx.CallAfter(self.btemp.SetValue,l)
wx.CallAfter(self.btemp.SetValue,str(f))
self.set("last_bed_temperature",str(f))
wx.CallAfter(self.setboff.SetBackgroundColour,"")
wx.CallAfter(self.setboff.SetForegroundColour,"")
@ -292,7 +293,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
#self.hottgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetExtruder0TargetTemperature,int(f))
if f>0:
wx.CallAfter(self.htemp.SetValue,l)
wx.CallAfter(self.htemp.SetValue,str(f))
self.set("last_temperature",str(f))
wx.CallAfter(self.settoff.SetBackgroundColour,"")
wx.CallAfter(self.settoff.SetForegroundColour,"")
@ -309,7 +310,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def do_settemp(self,l=""):
try:
if not (l.__class__=="".__class__ or l.__class__==u"".__class__) or (not len(l)):
if not (l.__class__=="".__class__ or l.__class__==u"".__class__) or not l:
l=str(self.htemp.GetValue().split()[0])
l=l.lower().replace(",",".")
for i in self.temps.keys():
@ -326,7 +327,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
print _("You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0.")
except Exception,x:
print _("You must enter a temperature. (%s)" % (repr(x),))
if webavail:
if self.webInterface:
self.webInterface.AddLog("You must enter a temperature. (%s)" % (repr(x),))
def do_bedtemp(self,l=""):
@ -344,15 +345,15 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.setbedgui(f)
else:
print _("Printer is not online.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Printer is not online.")
else:
print _("You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0.")
except:
print _("You must enter a temperature.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("You must enter a temperature.")
def end_macro(self):
@ -373,7 +374,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.delete_macro(macro_name)
return
print _("Cancelled.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Cancelled.")
return
self.cur_macro_name = macro_name
@ -393,7 +394,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.capture_skip_newline = True
return
wx.CallAfter(self.addtexttolog,l);
def scanserial(self):
"""scan for available ports. return a list of device names."""
baselist=[]
@ -409,12 +410,12 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
return baselist+glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') +glob.glob("/dev/tty.*")+glob.glob("/dev/cu.*")+glob.glob("/dev/rfcomm*")
def project(self,event):
import projectlayer
from printrun import projectlayer
if(self.p.online):
projectlayer.setframe(self,self.p).Show()
else:
print _("Printer is not online.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Printer is not online.")
def popmenu(self):
@ -493,7 +494,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
old_def = self.macros[macro]
elif len([c for c in macro.encode("ascii","replace") if not c.isalnum() and c != "_"]):
print _("Macro name may contain only ASCII alphanumeric symbols and underscores")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Macro name may contain only alphanumeric symbols and underscores")
return
elif hasattr(self.__class__,"do_"+macro):
@ -793,7 +794,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.gviz.showall=1
try:
raise ""
import stlview
from printrun import stlview
self.gwindow=stlview.GCFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size=(600,600))
except:
self.gwindow=gviz.window([],
@ -979,7 +980,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
def help_button(self):
print _('Defines custom button. Usage: button <num> "title" [/c "colour"] command')
if webavail:
if self.webInterface:
self.webInterface.AddLog('Defines custom button. Usage: button <num> "title" [/c "colour"] command')
def do_button(self,argstr):
@ -1003,7 +1004,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
command=argstr.strip()
if num<0 or num>=64:
print _("Custom button number should be between 0 and 63")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Custom button number should be between 0 and 63")
return
while num >= len(self.custombuttons):
@ -1271,7 +1272,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.cur_button=None
except:
print _("event object missing")
if webavail:
if self.webInterface:
self.webInterface.AddLog("event object missing")
self.cur_button=None
raise
@ -1289,7 +1290,8 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
except:
pass
self.Destroy()
if webavail:
if self.webInterface:
from printrun import webinterface
webinterface.KillWebInterfaceThread()
def do_monitor(self,l=""):
@ -1303,16 +1305,16 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
wx.CallAfter(self.monitorbox.SetValue,self.monitor_interval>0)
except:
print _("Invalid period given.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Invalid period given.")
self.setmonitor(None)
if self.monitor:
print _("Monitoring printer.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Monitoring printer.")
else:
print _("Done monitoring.")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Done monitoring.")
@ -1329,7 +1331,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
except:
print "attempted to write invalid text to console"
pass
if webavail:
if self.webInterface:
self.webInterface.AppendLog(text)
def setloud(self,e):
@ -1361,10 +1363,10 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
#string+=(self.tempreport.replace("\r","").replace("T:",_("Hotend") + ":").replace("B:",_("Bed") + ":").replace("\n","").replace("ok ",""))+" "
wx.CallAfter(self.tempdisp.SetLabel,self.tempreport.strip().replace("ok ",""))
try:
#self.hottgauge.SetValue(float(filter(lambda x:x.startswith("T:"),self.tempreport.split())[0].split(":")[1]))
wx.CallAfter(self.graph.SetExtruder0Temperature,float(filter(lambda x:x.startswith("T:"),self.tempreport.split())[0].split(":")[1]))
#self.bedtgauge.SetValue(float(filter(lambda x:x.startswith("B:"),self.tempreport.split())[0].split(":")[1]))
wx.CallAfter(self.graph.SetBedTemperature,float(filter(lambda x:x.startswith("B:"),self.tempreport.split())[0].split(":")[1]))
#self.hottgauge.SetValue(parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetExtruder0Temperature, parse_temperature_report(self.tempreport, "T:"))
#self.bedtgauge.SetValue(parse_temperature_report(self.tempreport, "B:"))
wx.CallAfter(self.graph.SetBedTemperature, parse_temperature_report(self.tempreport, "B:"))
except:
pass
fractioncomplete = 0.0
@ -1401,6 +1403,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
wx.CallAfter(self.status.SetStatusText,_("Not connected to printer."))
except:
pass #if window has been closed
def capture(self, func, *args, **kwargs):
stdout=sys.stdout
cout=None
@ -1425,11 +1428,11 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.tempreport=l
wx.CallAfter(self.tempdisp.SetLabel,self.tempreport.strip().replace("ok ",""))
try:
#self.hottgauge.SetValue(float(filter(lambda x:x.startswith("T:"),self.tempreport.split())[0].split(":")[1]))
wx.CallAfter(self.graph.SetExtruder0Temperature,float(filter(lambda x:x.startswith("T:"),self.tempreport.split())[0].split(":")[1]))
wx.CallAfter(self.graph.SetBedTemperature,float(filter(lambda x:x.startswith("B:"),self.tempreport.split())[0].split(":")[1]))
#self.hottgauge.SetValue(parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetExtruder0Temperature, parse_temperature_report(self.tempreport, "T:"))
wx.CallAfter(self.graph.SetBedTemperature, parse_temperature_report(self.tempreport, "B:"))
except:
pass
traceback.print_exc()
tstring=l.rstrip()
#print tstring
if (tstring!="ok") and (tstring!="wait") and ("ok T:" not in tstring) and (not self.p.loud):
@ -1477,8 +1480,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
except:
pass
def filesloaded(self):
dlg=wx.SingleChoiceDialog(self, _("Select the file to print"), _("Pick SD file"), self.sdfiles)
if(dlg.ShowModal()==wx.ID_OK):
@ -1486,9 +1487,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
if len(target):
self.recvlisteners+=[self.waitforsdresponse]
self.p.send_now("M23 "+target.lower())
#print self.sdfiles
pass
def getfiles(self):
if not self.p.online:
@ -1505,7 +1504,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
import shlex
param = self.expandcommand(self.settings.slicecommand).encode()
print "Slicing: ",param
if webavail:
if self.webInterface:
self.webInterface.AddLog("Slicing: "+param)
pararray=[i.replace("$s",self.filename).replace("$o",self.filename.replace(".stl","_export.gcode").replace(".STL","_export.gcode")).encode() for i in shlex.split(param.replace("\\","\\\\").encode())]
#print pararray
@ -1518,7 +1517,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.stopsf=1
except:
print _("Failed to execute slicing software: ")
if webavail:
if self.webInterface:
self.webInterface.AddLog("Failed to execute slicing software: ")
self.stopsf=1
traceback.print_exc(file=sys.stdout)
@ -1550,7 +1549,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.skeining=0
self.skeinp=None
def skein(self,filename):
wx.CallAfter(self.loadbtn.SetLabel,_("Cancel"))
print _("Slicing ") + filename
@ -1612,7 +1610,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
Xtot,Ytot,Ztot,Xmin,Xmax,Ymin,Ymax,Zmin,Zmax = pronsole.measurements(self.f)
print pronsole.totalelength(self.f), _("mm of filament used in this print\n")
print _("the print goes from %f mm to %f mm in X\nand is %f mm wide\n") % (Xmin, Xmax, Xtot)
if webavail:
if self.webInterface:
self.webInterface.AddLog(_("the print goes from %f mm to %f mm in X\nand is %f mm wide\n") % (Xmin, Xmax, Xtot))
print _("the print goes from %f mm to %f mm in Y\nand is %f mm wide\n") % (Ymin, Ymax, Ytot)
print _("the print goes from %f mm to %f mm in Z\nand is %f mm high\n") % (Zmin, Zmax, Ztot)
@ -1706,7 +1704,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.p.resume()
wx.CallAfter(self.pausebtn.SetLabel, _("Pause"))
def sdprintfile(self,event):
self.on_startprint()
threading.Thread(target=self.getfiles).start()
@ -1742,7 +1739,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.set("baudrate",str(baud))
threading.Thread(target=self.statuschecker).start()
def disconnect(self,event):
print _("Disconnected.")
self.p.disconnect()
@ -1770,7 +1766,6 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
if self.sdprinting:
self.p.send_now("M26 S0")
def reset(self,event):
print _("Reset.")
dlg=wx.MessageDialog(self, _("Are you sure you want to reset the printer?"), _("Reset?"), wx.YES|wx.NO)
@ -1858,8 +1853,6 @@ class macroed(wx.Dialog):
if position == -1 :
# ShowMessage(self,-1, "Not found!")
titletext = wx.TextCtrl(self.panel,-1,"Not Found!")
else:
# self.title.SetValue("Position : "+str(position))
@ -1885,7 +1878,7 @@ class macroed(wx.Dialog):
self.callback(self.e.GetValue().split("\n"))
def close(self,ev):
self.Destroy()
if webavail:
if self.webInterface:
webinterface.KillWebInterfaceThread()
def unindent(self,text):
self.indent_chars = text[:len(text)-len(text.lstrip())]
@ -1970,6 +1963,7 @@ class ButtonEdit(wx.Dialog):
topsizer.Add( (0,0),1)
topsizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL),0,wx.ALIGN_CENTER)
self.SetSizer(topsizer)
def macrob_enabler(self,e):
macro = self.command.GetValue()
valid = False
@ -1994,6 +1988,7 @@ class ButtonEdit(wx.Dialog):
else:
valid = True
self.macrob.Enable(valid)
def macrob_handler(self,e):
macro = self.command.GetValue()
macro = self.pronterface.edit_macro(macro)
@ -2002,6 +1997,7 @@ class ButtonEdit(wx.Dialog):
self.name.SetValue(macro)
class TempGauge(wx.Panel):
def __init__(self,parent,size=(200,22),title="",maxval=240,gaugeColour=None):
wx.Panel.__init__(self,parent,-1,size=size)
self.Bind(wx.EVT_PAINT,self.paint)
@ -2013,17 +2009,21 @@ class TempGauge(wx.Panel):
self.value=0
self.setpoint=0
self.recalc()
def recalc(self):
mmax=max(int(self.setpoint*1.05),self.max)
self.scale=float(self.width-2)/float(mmax)
self.ypt=max(16,int(self.scale*max(self.setpoint,self.max/6)))
def SetValue(self,value):
self.value=value
wx.CallAfter(self.Refresh)
def SetTarget(self,value):
self.setpoint=value
self.recalc()
wx.CallAfter(self.Refresh)
def interpolatedColour(self,val,vmin,vmid,vmax,cmin,cmid,cmax):
if val < vmin: return cmin
if val > vmax: return cmax
@ -2035,6 +2035,7 @@ class TempGauge(wx.Panel):
rgb=lo.Red()+(hi.Red()-lo.Red())*vv,lo.Green()+(hi.Green()-lo.Green())*vv,lo.Blue()+(hi.Blue()-lo.Blue())*vv
rgb=map(lambda x:x*0.8,rgb)
return wx.Colour(*map(int,rgb))
def paint(self,ev):
x0,y0,x1,y1,xE,yE = 1,1,self.ypt+1,1,self.width+1-2,20
dc=wx.PaintDC(self)

152
setup.py Executable file
View File

@ -0,0 +1,152 @@
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
# Printrun 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.
#
# Printrun 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/>.
import sys, os, glob
import subprocess
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
INSTALLED_FILES = "installed_files"
class install (_install):
def run (self):
_install.run (self)
outputs = self.get_outputs ()
length = 0
if self.root:
length += len (self.root)
if self.prefix:
length += len (self.prefix)
if length:
for counter in xrange (len (outputs)):
outputs[counter] = outputs[counter][length:]
data = "\n".join (outputs)
try:
file = open (INSTALLED_FILES, "w")
except:
self.warn ("Could not write installed files list %s" % \
INSTALLED_FILES)
return
file.write (data)
file.close ()
class install_data (_install_data):
def run (self):
def chmod_data_file (file):
try:
os.chmod (file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
except:
self.warn ("Could not chmod data file %s" % file)
_install_data.run (self)
map (chmod_data_file, self.get_outputs ())
class uninstall (_install):
def run (self):
try:
file = open (INSTALLED_FILES, "r")
except:
self.warn ("Could not read installed files list %s" % \
INSTALLED_FILES)
return
files = file.readlines ()
file.close ()
prepend = ""
if self.root:
prepend += self.root
if self.prefix:
prepend += self.prefix
if len (prepend):
for counter in xrange (len (files)):
files[counter] = prepend + files[counter].rstrip ()
for file in files:
print "Uninstalling %s" % file
try:
os.unlink (file)
except:
self.warn ("Could not remove file %s" % file)
ops = ("install", "build", "sdist", "uninstall", "clean")
if len (sys.argv) < 2 or sys.argv[1] not in ops:
print "Please specify operation : %s" % " | ".join (ops)
raise SystemExit
prefix = None
if len (sys.argv) > 2:
i = 0
for o in sys.argv:
if o.startswith ("--prefix"):
if o == "--prefix":
if len (sys.argv) >= i:
prefix = sys.argv[i + 1]
sys.argv.remove (prefix)
elif o.startswith ("--prefix=") and len (o[9:]):
prefix = o[9:]
sys.argv.remove (o)
i += 1
if not prefix and "PREFIX" in os.environ:
prefix = os.environ["PREFIX"]
if not prefix or not len (prefix):
prefix = "/usr/local"
if sys.argv[1] in ("install", "uninstall") and len (prefix):
sys.argv += ["--prefix", prefix]
target_images_path = "share/pronterface/images/"
data_files = [('share/pixmaps/', ['P-face.ico','plater.ico'])]
for basedir, subdirs, files in os.walk("images"):
images = []
for filename in files:
if filename.find(".svg") or filename.find(".png"):
file_path = os.path.join(basedir, filename)
images.append(file_path)
data_files.append((target_images_path + basedir[len("images/"):], images))
for basedir, subdirs, files in os.walk("locale"):
if not basedir.endswith("LC_MESSAGES"):
continue
destpath = os.path.join("share", "pronterface", basedir)
files = filter(lambda x: x.endswith(".mo"), files)
files = map(lambda x: os.path.join(basedir, x), files)
data_files.append ((destpath, files))
extra_data_dirs = ["css"]
for extra_data_dir in extra_data_dirs:
for basedir, subdirs, files in os.walk(extra_data_dir):
files = map(lambda x: os.path.join(basedir, x), files)
destpath = os.path.join("share", "pronterface", basedir)
data_files.append ((destpath, files))
setup (
name = "Printrun",
description = "Host software for 3D printers",
author = "Kliment Yanev",
url = "http://github.com/kliment/Printrun/",
license = "GPLv3",
data_files = data_files,
packages = ["printrun", "printrun.svg"],
scripts = ["pronsole.py", "pronterface.py", "plater.py"],
cmdclass = {"uninstall" : uninstall,
"install" : install,
"install_data" : install_data}
)