From 375fffdd3fd439276f44e11380f66328e8280762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 27 Dec 2012 00:04:12 +0100 Subject: [PATCH] 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.md --- Cura/webui/__init__.py | 47 +++++++++++++++++++++++------- Cura/webui/printer.py | 4 +-- Cura/webui/static/img/favicon.ico | Bin 0 -> 353118 bytes Cura/webui/templates/index.html | 2 ++ README.md | 11 +++++++ 5 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 Cura/webui/static/img/favicon.ico diff --git a/Cura/webui/__init__.py b/Cura/webui/__init__.py index 2114d86..fa9bd9e 100644 --- a/Cura/webui/__init__.py +++ b/Cura/webui/__init__.py @@ -2,16 +2,36 @@ # coding=utf-8 __author__ = 'Gina Häußge ' -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 +import sys import os import fnmatch -BASEURL='/ajax/' +APPNAME="Cura" +BASEURL="/ajax/" 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") printer = Printer() @@ -63,7 +83,7 @@ def printerMessages(): return jsonify(messages=printer.messages) @app.route(BASEURL + 'state/log', methods=['GET']) -def printerMessages(): +def printerLogs(): return jsonify(log=printer.log) @app.route(BASEURL + 'state/temperatures', methods=['GET']) @@ -164,8 +184,9 @@ def readGcodeFiles(): @app.route(BASEURL + 'gcodefiles/upload', methods=['POST']) def uploadGcodeFile(): file = request.files['gcode_file'] - if file != None: - filename = UPLOAD_FOLDER + os.sep + file.filename + if file and allowed_file(file.filename): + secure = secure_filename(file.filename) + filename = os.path.join(UPLOAD_FOLDER, secure) file.save(filename) return readGcodeFiles() @@ -177,8 +198,12 @@ def loadGcodeFile(): @app.route(BASEURL + 'gcodefiles/delete', methods=['POST']) def deleteGcodeFile(): - filename = request.values["filename"] - os.remove(UPLOAD_FOLDER + os.sep + filename) + if request.values.has_key("filename"): + filename = request.values["filename"] + if allowed_file(filename): + secure = UPLOAD_FOLDER + os.sep + secure_filename(filename) + if os.path.exists(secure): + os.remove(secure) return readGcodeFiles() def sizeof_fmt(num): @@ -191,6 +216,8 @@ def sizeof_fmt(num): num /= 1024.0 return "%3.1f%s" % (num, 'TB') +def allowed_file(filename): + return "." in filename and filename.rsplit(".", 1)[1] in ALLOWED_EXTENSIONS + def run(): - app.debug = True - app.run(host="0.0.0.0") + app.run(host="0.0.0.0", port=5000) diff --git a/Cura/webui/printer.py b/Cura/webui/printer.py index 2111107..808e1c4 100644 --- a/Cura/webui/printer.py +++ b/Cura/webui/printer.py @@ -38,7 +38,7 @@ class Printer(): def connect(self): if self.comm != None: self.comm.close() - self.comm = machineCom.MachineCom(port="COM4", baudrate=115200, callbackObject=self) + self.comm = machineCom.MachineCom(callbackObject=self) def disconnect(self): if self.comm != None: @@ -193,5 +193,5 @@ class Printer(): if self.comm == None: return self.comm.cancelPrint() - self.comm.sendCommand("M84") + self.comm.sendCommands(["M84", "M104 S0", "M140 S0"]) # disable motors, switch off heaters diff --git a/Cura/webui/static/img/favicon.ico b/Cura/webui/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1340f5d4c459c3d4c779f4cf7380cc964db4a5dd GIT binary patch literal 353118 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 F{{gLN`VRmA literal 0 HcmV?d00001 diff --git a/Cura/webui/templates/index.html b/Cura/webui/templates/index.html index c0501b4..c44a24b 100644 --- a/Cura/webui/templates/index.html +++ b/Cura/webui/templates/index.html @@ -3,6 +3,8 @@ Cura WebUI + + diff --git a/README.md b/README.md index 5ace7af..41ff889 100644 --- a/README.md +++ b/README.md @@ -83,3 +83,14 @@ At time of writing, pyobjc 2.5 is not available at pypi. You have to clone repo ###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. + +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`. \ No newline at end of file