Upload location is now platform dependent
win32 defaults to %APPDATA%/Cura/uploads macos defaults to ~/Library/Application Support/Cura/uploads (I hope, can't test it...) linux defaults to ~/.cura/uploads Server now also checks if file to be uploaded or deleted ends on .gcode and makes filename secure before doing anything on the filesystem Also added favicon ;) and some bla to the README.mdmaster
parent
909278897c
commit
375fffdd3f
|
@ -2,16 +2,36 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
__author__ = 'Gina Häußge <osd@foosel.net>'
|
__author__ = 'Gina Häußge <osd@foosel.net>'
|
||||||
|
|
||||||
from flask import Flask, request, render_template, jsonify
|
from flask import Flask, request, render_template, jsonify, make_response
|
||||||
|
from werkzeug import secure_filename
|
||||||
|
|
||||||
from printer import Printer
|
from printer import Printer
|
||||||
|
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
|
||||||
BASEURL='/ajax/'
|
APPNAME="Cura"
|
||||||
|
BASEURL="/ajax/"
|
||||||
SUCCESS={}
|
SUCCESS={}
|
||||||
UPLOAD_FOLDER="uploads"
|
|
||||||
|
# taken from http://stackoverflow.com/questions/1084697/how-do-i-store-desktop-application-data-in-a-cross-platform-way-for-python
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
from AppKit import NSSearchPathForDirectoriesInDomains
|
||||||
|
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
||||||
|
# NSApplicationSupportDirectory = 14
|
||||||
|
# NSUserDomainMask = 1
|
||||||
|
# True for expanding the tilde into a fully qualified path
|
||||||
|
appdata = os.path.join(NSSearchPathForDirectoriesInDomains(14, 1, True)[0], APPNAME)
|
||||||
|
elif sys.platform == 'win32':
|
||||||
|
appdata = os.path.join(os.environ['APPDATA'], APPNAME)
|
||||||
|
else:
|
||||||
|
appdata = os.path.expanduser(os.path.join("~", "." + APPNAME.lower()))
|
||||||
|
|
||||||
|
UPLOAD_FOLDER = appdata + os.sep + "uploads"
|
||||||
|
if not os.path.isdir(UPLOAD_FOLDER):
|
||||||
|
os.makedirs(UPLOAD_FOLDER)
|
||||||
|
ALLOWED_EXTENSIONS = set(["gcode"])
|
||||||
|
|
||||||
app = Flask("Cura.webui")
|
app = Flask("Cura.webui")
|
||||||
printer = Printer()
|
printer = Printer()
|
||||||
|
@ -63,7 +83,7 @@ def printerMessages():
|
||||||
return jsonify(messages=printer.messages)
|
return jsonify(messages=printer.messages)
|
||||||
|
|
||||||
@app.route(BASEURL + 'state/log', methods=['GET'])
|
@app.route(BASEURL + 'state/log', methods=['GET'])
|
||||||
def printerMessages():
|
def printerLogs():
|
||||||
return jsonify(log=printer.log)
|
return jsonify(log=printer.log)
|
||||||
|
|
||||||
@app.route(BASEURL + 'state/temperatures', methods=['GET'])
|
@app.route(BASEURL + 'state/temperatures', methods=['GET'])
|
||||||
|
@ -164,8 +184,9 @@ def readGcodeFiles():
|
||||||
@app.route(BASEURL + 'gcodefiles/upload', methods=['POST'])
|
@app.route(BASEURL + 'gcodefiles/upload', methods=['POST'])
|
||||||
def uploadGcodeFile():
|
def uploadGcodeFile():
|
||||||
file = request.files['gcode_file']
|
file = request.files['gcode_file']
|
||||||
if file != None:
|
if file and allowed_file(file.filename):
|
||||||
filename = UPLOAD_FOLDER + os.sep + file.filename
|
secure = secure_filename(file.filename)
|
||||||
|
filename = os.path.join(UPLOAD_FOLDER, secure)
|
||||||
file.save(filename)
|
file.save(filename)
|
||||||
return readGcodeFiles()
|
return readGcodeFiles()
|
||||||
|
|
||||||
|
@ -177,8 +198,12 @@ def loadGcodeFile():
|
||||||
|
|
||||||
@app.route(BASEURL + 'gcodefiles/delete', methods=['POST'])
|
@app.route(BASEURL + 'gcodefiles/delete', methods=['POST'])
|
||||||
def deleteGcodeFile():
|
def deleteGcodeFile():
|
||||||
|
if request.values.has_key("filename"):
|
||||||
filename = request.values["filename"]
|
filename = request.values["filename"]
|
||||||
os.remove(UPLOAD_FOLDER + os.sep + filename)
|
if allowed_file(filename):
|
||||||
|
secure = UPLOAD_FOLDER + os.sep + secure_filename(filename)
|
||||||
|
if os.path.exists(secure):
|
||||||
|
os.remove(secure)
|
||||||
return readGcodeFiles()
|
return readGcodeFiles()
|
||||||
|
|
||||||
def sizeof_fmt(num):
|
def sizeof_fmt(num):
|
||||||
|
@ -191,6 +216,8 @@ def sizeof_fmt(num):
|
||||||
num /= 1024.0
|
num /= 1024.0
|
||||||
return "%3.1f%s" % (num, 'TB')
|
return "%3.1f%s" % (num, 'TB')
|
||||||
|
|
||||||
|
def allowed_file(filename):
|
||||||
|
return "." in filename and filename.rsplit(".", 1)[1] in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
app.debug = True
|
app.run(host="0.0.0.0", port=5000)
|
||||||
app.run(host="0.0.0.0")
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Printer():
|
||||||
def connect(self):
|
def connect(self):
|
||||||
if self.comm != None:
|
if self.comm != None:
|
||||||
self.comm.close()
|
self.comm.close()
|
||||||
self.comm = machineCom.MachineCom(port="COM4", baudrate=115200, callbackObject=self)
|
self.comm = machineCom.MachineCom(callbackObject=self)
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
if self.comm != None:
|
if self.comm != None:
|
||||||
|
@ -193,5 +193,5 @@ class Printer():
|
||||||
if self.comm == None:
|
if self.comm == None:
|
||||||
return
|
return
|
||||||
self.comm.cancelPrint()
|
self.comm.cancelPrint()
|
||||||
self.comm.sendCommand("M84")
|
self.comm.sendCommands(["M84", "M104 S0", "M140 S0"]) # disable motors, switch off heaters
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 345 KiB |
|
@ -3,6 +3,8 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Cura WebUI</title>
|
<title>Cura WebUI</title>
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}">
|
||||||
|
|
||||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet" media="screen">
|
||||||
<link href="{{ url_for('static', filename='css/jquery.fileupload-ui.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/jquery.fileupload-ui.css') }}" rel="stylesheet" media="screen">
|
||||||
<link href="{{ url_for('static', filename='css/ui.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/ui.css') }}" rel="stylesheet" media="screen">
|
||||||
|
|
11
README.md
11
README.md
|
@ -83,3 +83,14 @@ At time of writing, pyobjc 2.5 is not available at pypi. You have to clone repo
|
||||||
|
|
||||||
###Packaging
|
###Packaging
|
||||||
To package Cura into application bundle simply do `python setup.py py2app`. Resulting bundle is self-contained -- it includes Python and all needed packages.
|
To package Cura into application bundle simply do `python setup.py py2app`. Resulting bundle is self-contained -- it includes Python and all needed packages.
|
||||||
|
|
||||||
|
WebUI
|
||||||
|
=====
|
||||||
|
|
||||||
|
This fork of Cura includes a WebUI for remote printing via the browser. It depends on the Python module "flask" and
|
||||||
|
its dependencies "werkzeug", "jinja2" and "itsdangerous", so you'll need those in order to run the WebUI. A simple
|
||||||
|
`pip install -r requirements.txt` or `pip install flask` should take care of that.
|
||||||
|
|
||||||
|
Once installed, you can startup the WebUI instead of the regular Cura UI via the command-line option `--web` or `-w`. The
|
||||||
|
web interface will then be available on port 5000. If you want to change that (or the IP address the server binds to,
|
||||||
|
which currently is `0.0.0.0`), please take a look at the source code of `Cura/webui/__init__.py`.
|
Loading…
Reference in New Issue