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
Richard Mitchell 2013-05-18 17:47:31 +00:00
parent 3f79faf55b
commit c1760c9940
4 changed files with 82 additions and 3 deletions

View File

@ -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"])

View File

@ -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)
}
}

View File

@ -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()

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">
@ -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">