Merge branch 'richardjm-devel' into devel

Conflicts:
	octoprint/server.py
	octoprint/settings.py
	octoprint/templates/index.jinja2
master
Gina Häußge 2013-06-23 16:09:31 +02:00
commit c6e15a7d32
5 changed files with 80 additions and 1 deletions

View File

@ -24,6 +24,7 @@ import octoprint.events as events
SUCCESS = {}
BASEURL = "/ajax/"
APIBASEURL = "/api/"
app = Flask("octoprint")
# Only instantiated by the Server().run() method
@ -319,6 +320,7 @@ def uploadGcodeFile():
eventManager.fire("Upload", filename)
return jsonify(files=gcodeManager.getAllFileData(), filename=filename)
@app.route(BASEURL + "gcodefiles/load", methods=["POST"])
@login_required
def loadGcodeFile():
@ -349,10 +351,47 @@ def deleteGcodeFile():
return readGcodeFiles()
@app.route(BASEURL + "gcodefiles/refresh", methods=["POST"])
@login_required
def refreshFiles():
printer.updateSdFiles()
return jsonify(SUCCESS)
#-- very simple api routines
@app.route(APIBASEURL + "load", methods=["POST"])
@login_required
def apiLoad():
filename = None
s = settings()
if not s.get(["api", "allow"]):
return jsonify(success=False, message="API calls not enabled")
if not "apikey" in request.values.keys():
return jsonify(success=False, message="apikey not present")
if request.values["apikey"] <> s.get(["api", "key"]):
return jsonify(success=False, message="apikey incorrect" + s.get(["api","key"]) + " " + request.values["apikey"])
if "file" in request.files.keys():
# Perform an upload
file = request.files["file"]
filename = gcodeManager.addFile(file)
if filename is None:
return jsonify(success=False, message="failure loading gcode")
else:
logger = logging.getLogger(__name__)
logger.info("loaded " + filename)
# Immediately perform a loadGcode and possibly print too
printAfterLoading = False
if "print" in request.values.keys() and request.values["print"] in valid_boolean_trues:
printAfterLoading = True
filepath = gcodeManager.getAbsolutePath(filename)
if filepath is not None:
printer.loadGcode(filepath, printAfterLoading)
else:
return jsonify(success=False, message="gcode file not present")
return jsonify(SUCCESS)
#~~ timelapse handling
@app.route(BASEURL + "timelapse", methods=["GET"])
@ -427,6 +466,10 @@ def getSettings():
[movementSpeedX, movementSpeedY, movementSpeedZ, movementSpeedE] = s.get(["printerParameters", "movementSpeed", ["x", "y", "z", "e"]])
return jsonify({
"api": {
"allow": s.getBoolean(["api", "allow"]),
"key": s.get(["api", "key"])
},
"appearance": {
"name": s.get(["appearance", "name"]),
"color": s.get(["appearance", "color"])
@ -476,6 +519,10 @@ def setSettings():
data = request.json
s = settings()
if "api" in data.keys():
if "allow" in data["api"].keys(): s.set(["api", "allow"], data["api"]["allow"])
if "key" in data["api"].keys(): s.set(["api", "key"], data["api"]["key"], True)
if "appearance" in data.keys():
if "name" in data["appearance"].keys(): s.set(["appearance", "name"], data["appearance"]["name"])
if "color" in data["appearance"].keys(): s.set(["appearance", "color"], data["appearance"]["color"])

View File

@ -7,6 +7,7 @@ import os
import yaml
import logging
import re
import uuid
APPNAME="OctoPrint"
@ -89,6 +90,10 @@ default_settings = {
"gcodeCommandTrigger": {
"enabled": False
}
},
"api": {
"allow": False,
"key": ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)
}
}

View File

@ -1310,6 +1310,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.loginState = loginStateViewModel;
self.users = usersViewModel;
self.api_allow = ko.observable(undefined);
self.api_key = ko.observable(undefined);
self.appearance_name = ko.observable(undefined);
self.appearance_color = ko.observable(undefined);
@ -1362,6 +1365,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
}
self.fromResponse = function(response) {
self.api_allow(response.api.allow);
self.api_key(response.api.key);
self.appearance_name(response.appearance.name);
self.appearance_color(response.appearance.color);
@ -1396,6 +1402,10 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.saveData = function() {
var data = {
"api" : {
"allow": self.api_allow(),
"key": self.api_key()
},
"appearance" : {
"name": self.appearance_name(),
"color": self.appearance_color()

View File

@ -580,7 +580,6 @@
{% include 'settings.jinja2' %}
{% include 'dialogs.jinja2' %}
<!--<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>-->
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery/jquery.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script>

View File

@ -13,6 +13,7 @@
<li><a href="#settings_temperature" data-toggle="tab">Temperature</a></li>
<li><a href="#settings_appearance" data-toggle="tab">Appearance</a></li>
{% if enableAccessControl %}<li><a href="#settings_users" data-toggle="tab">Users</a></li>{% endif %}
<li><a href="#settings_api" data-toggle="tab">Api</a></li>
</ul>
<div class="tab-content span8">
@ -218,6 +219,23 @@
</div>
</form>
</div>
<div class="tab-pane" id="settings_api">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" id="settings-apiallow" data-bind="checked: api_allow"> Allow
</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-apikey">Apikey</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: api_key" id="settings-apikey">
</div>
</div>
</form>
</div>
{% if enableAccessControl %}
<div class="tab-pane" id="settings_users">