Merge branch 'richardjm-devel' into devel
Conflicts: octoprint/server.py octoprint/settings.py octoprint/templates/index.jinja2master
commit
c6e15a7d32
|
@ -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"])
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue