A very simple API endpoint for loading and printing files direct. This is by default turned off and it "allowed" via the settings
From within Slic3r adding a post-processing script .bat containing c:\curl\curl "http://192.168.0.7:5000/api/load?apikey=D96FA6A216CB44F78705D4506689D0EC&print=true" -F file=@%*master
parent
3f79faf55b
commit
c1760c9940
|
@ -22,6 +22,7 @@ import octoprint.users as users
|
|||
|
||||
SUCCESS = {}
|
||||
BASEURL = "/ajax/"
|
||||
APIBASEURL = "/api/"
|
||||
|
||||
app = Flask("octoprint")
|
||||
# Only instantiated by the Server().run() method
|
||||
|
@ -272,6 +273,7 @@ def uploadGcodeFile():
|
|||
filename = gcodeManager.addFile(file)
|
||||
return jsonify(files=gcodeManager.getAllFileData(), filename=filename)
|
||||
|
||||
|
||||
@app.route(BASEURL + "gcodefiles/load", methods=["POST"])
|
||||
@login_required
|
||||
def loadGcodeFile():
|
||||
|
@ -279,9 +281,9 @@ def loadGcodeFile():
|
|||
printAfterLoading = False
|
||||
if "print" in request.values.keys() and request.values["print"] in valid_boolean_trues:
|
||||
printAfterLoading = True
|
||||
filename = gcodeManager.getAbsolutePath(request.values["filename"])
|
||||
if filename is not None:
|
||||
printer.loadGcode(filename, printAfterLoading)
|
||||
filepath = gcodeManager.getAbsolutePath(request.values["filename"])
|
||||
if filepath is not None:
|
||||
printer.loadGcode(filepath, printAfterLoading)
|
||||
return jsonify(SUCCESS)
|
||||
|
||||
@app.route(BASEURL + "gcodefiles/delete", methods=["POST"])
|
||||
|
@ -292,6 +294,42 @@ def deleteGcodeFile():
|
|||
gcodeManager.removeFile(filename)
|
||||
return readGcodeFiles()
|
||||
|
||||
#-- 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(files=gcodeManager.getAllFileData(), filename=filename)
|
||||
|
||||
#~~ timelapse handling
|
||||
|
||||
@app.route(BASEURL + "timelapse", methods=["GET"])
|
||||
|
@ -361,6 +399,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"])
|
||||
|
@ -404,6 +446,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 sys
|
|||
import os
|
||||
import yaml
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
APPNAME="OctoPrint"
|
||||
|
||||
|
@ -74,6 +75,10 @@ default_settings = {
|
|||
"enabled": False,
|
||||
"userManager": "octoprint.users.FilebasedUserManager",
|
||||
"userfile": None
|
||||
},
|
||||
"api": {
|
||||
"allow": False,
|
||||
"key": ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1248,6 +1248,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);
|
||||
|
||||
|
@ -1295,6 +1298,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);
|
||||
|
||||
|
@ -1324,6 +1330,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()
|
||||
|
|
|
@ -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">
|
||||
|
@ -185,6 +186,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