Merge branch 'fix/uploadWhileOffline' into devel
Conflicts: src/octoprint/static/js/app/dataupdater.js src/octoprint/static/js/app/viewmodels/files.js
This commit is contained in:
commit
9d924be5f9
3 changed files with 183 additions and 149 deletions
|
|
@ -47,11 +47,11 @@ which is a custom SD card image that includes OctoPrint plus dependencies.
|
|||
The generic steps that should basically be done regardless of operating system
|
||||
and runtime environment are the following (as *regular
|
||||
user*, please keep your hands *off* of the `sudo` command here!) - this assumes
|
||||
you already have Python 2.7, pip and virtualenv set up:
|
||||
you already have Python 2.7, pip and virtualenv set up on your system:
|
||||
|
||||
1. Checkout OctoPrint: `git clone https://github.com/foosel/OctoPrint.git`
|
||||
2. Change into the OctoPrint folder: `cd OctoPrint`
|
||||
3. Create a user-owned virtual environment therein: `virtualenv --system-site-packages venv`
|
||||
3. Create a user-owned virtual environment therein: `virtualenv venv`
|
||||
4. Install OctoPrint *into that virtual environment*: `./venv/bin/python setup.py install`
|
||||
|
||||
You may then start the OctoPrint server via `/path/to/OctoPrint/venv/bin/octoprint`, see [Usage](#usage)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function DataUpdater(allViewModels) {
|
|||
self.allViewModels,
|
||||
"onServerDisconnect",
|
||||
function() { return !handled; },
|
||||
function(method) { handled = !method() || handled; }
|
||||
function(method) { var result = method(); handled = (result !== undefined && !result) || handled; }
|
||||
);
|
||||
|
||||
if (handled) {
|
||||
|
|
@ -45,7 +45,7 @@ function DataUpdater(allViewModels) {
|
|||
self.allViewModels,
|
||||
"onServerDisconnect",
|
||||
function() { return !handled; },
|
||||
function(method) { handled = !method() || handled; }
|
||||
function(method) { var result = method(); handled = (result !== undefined && !result) || handled; }
|
||||
);
|
||||
|
||||
if (handled) {
|
||||
|
|
@ -78,11 +78,14 @@ function DataUpdater(allViewModels) {
|
|||
// hide it, plus reload the camera feed if it's currently displayed
|
||||
if ($("#offline_overlay").is(":visible")) {
|
||||
hideOfflineOverlay();
|
||||
callViewModels(self.allViewModels, "onServerReconnect");
|
||||
callViewModels(self.allViewModels, "onDataUpdaterReconnect");
|
||||
|
||||
if ($('#tabs li[class="active"] a').attr("href") == "#control") {
|
||||
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
|
||||
}
|
||||
} else {
|
||||
callViewModels(self.allViewModels, "onServerConnect");
|
||||
}
|
||||
|
||||
// if the version, the plugin hash or the config hash changed, we
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ $(function() {
|
|||
|
||||
self.uploadButton = undefined;
|
||||
self.uploadSdButton = undefined;
|
||||
self.uploadProgressBar = undefined;
|
||||
self.localTarget = undefined;
|
||||
self.sdTarget = undefined;
|
||||
|
||||
self.addFolderDialog = undefined;
|
||||
self.addFolderName = ko.observable(undefined);
|
||||
|
|
@ -455,10 +458,6 @@ $(function() {
|
|||
return false;
|
||||
};
|
||||
|
||||
self.onDataUpdaterReconnect = function() {
|
||||
self.requestData(undefined, undefined, self.currentPath());
|
||||
};
|
||||
|
||||
self.onUserLoggedIn = function(user) {
|
||||
self.uploadButton.fileupload("enable");
|
||||
if (self.uploadSdButton) {
|
||||
|
|
@ -504,158 +503,23 @@ $(function() {
|
|||
self.uploadSdButton = undefined;
|
||||
}
|
||||
|
||||
var uploadProgress = $("#gcode_upload_progress");
|
||||
var uploadProgressBar = uploadProgress.find(".bar");
|
||||
self.uploadProgress = $("#gcode_upload_progress");
|
||||
self.uploadProgressBar = $(".bar", self.uploadProgress);
|
||||
|
||||
var localTarget = CONFIG_SD_SUPPORT ? $("#drop_locally") : $("#drop");
|
||||
var sdTarget = $("#drop_sd");
|
||||
|
||||
function setProgressBar(percentage, text, active) {
|
||||
uploadProgressBar
|
||||
.css("width", percentage + "%")
|
||||
.text(text);
|
||||
|
||||
if (active) {
|
||||
uploadProgress
|
||||
.addClass("progress-striped active");
|
||||
} else {
|
||||
uploadProgress
|
||||
.removeClass("progress-striped active");
|
||||
}
|
||||
}
|
||||
|
||||
function gcode_upload_done(e, data) {
|
||||
var filename = undefined;
|
||||
var location = undefined;
|
||||
if (data.result.files.hasOwnProperty("sdcard")) {
|
||||
filename = data.result.files.sdcard.name;
|
||||
location = "sdcard";
|
||||
} else if (data.result.files.hasOwnProperty("local")) {
|
||||
filename = data.result.files.local.name;
|
||||
location = "local";
|
||||
}
|
||||
self.requestData(filename, location, self.currentPath());
|
||||
|
||||
if (_.endsWith(filename.toLowerCase(), ".stl")) {
|
||||
self.slicing.show(location, filename);
|
||||
}
|
||||
|
||||
if (data.result.done) {
|
||||
setProgressBar(0, "", false);
|
||||
}
|
||||
}
|
||||
|
||||
function gcode_upload_fail(e, data) {
|
||||
var error = "<p>" + gettext("Could not upload the file. Make sure that it is a GCODE file and has the extension \".gcode\" or \".gco\" or that it is an STL file with the extension \".stl\".") + "</p>";
|
||||
error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
|
||||
new PNotify({
|
||||
title: "Upload failed",
|
||||
text: error,
|
||||
type: "error",
|
||||
hide: false
|
||||
});
|
||||
setProgressBar(0, "", false);
|
||||
}
|
||||
|
||||
function gcode_upload_progress(e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
var uploaded = progress >= 100;
|
||||
|
||||
setProgressBar(progress, uploaded ? gettext("Saving ...") : gettext("Uploading ..."), uploaded);
|
||||
}
|
||||
|
||||
function setDropzone(dropzone, enable) {
|
||||
var button = (dropzone == "local") ? self.uploadButton : self.uploadSdButton;
|
||||
var drop = (dropzone == "local") ? localTarget : sdTarget;
|
||||
var url = API_BASEURL + "files/" + dropzone;
|
||||
|
||||
if (button === undefined)
|
||||
return;
|
||||
|
||||
button.fileupload({
|
||||
url: url,
|
||||
dataType: "json",
|
||||
dropZone: enable ? drop : null,
|
||||
drop: function(e, data) {
|
||||
|
||||
},
|
||||
done: gcode_upload_done,
|
||||
fail: gcode_upload_fail,
|
||||
progressall: gcode_upload_progress
|
||||
}).bind('fileuploadsubmit', function(e, data) {
|
||||
if (self.currentPath() != "")
|
||||
data.formData = { path: self.currentPath() };
|
||||
});
|
||||
}
|
||||
self.localTarget = CONFIG_SD_SUPPORT ? $("#drop_locally") : $("#drop");
|
||||
self.sdTarget = $("#drop_sd");
|
||||
|
||||
function evaluateDropzones() {
|
||||
var enableLocal = self.loginState.isUser();
|
||||
var enableSd = enableLocal && CONFIG_SD_SUPPORT && self.printerState.isSdReady();
|
||||
|
||||
setDropzone("local", enableLocal);
|
||||
setDropzone("sdcard", enableSd);
|
||||
self._setDropzone("local", enableLocal);
|
||||
self._setDropzone("sdcard", enableSd);
|
||||
}
|
||||
self.loginState.isUser.subscribe(evaluateDropzones);
|
||||
self.printerState.isSdReady.subscribe(evaluateDropzones);
|
||||
evaluateDropzones();
|
||||
|
||||
$(document).bind("dragover", function (e) {
|
||||
var dropOverlay = $("#drop_overlay");
|
||||
var dropZone = $("#drop");
|
||||
var dropZoneLocal = $("#drop_locally");
|
||||
var dropZoneSd = $("#drop_sd");
|
||||
var dropZoneBackground = $("#drop_background");
|
||||
var dropZoneLocalBackground = $("#drop_locally_background");
|
||||
var dropZoneSdBackground = $("#drop_sd_background");
|
||||
var timeout = window.dropZoneTimeout;
|
||||
|
||||
if (!timeout) {
|
||||
dropOverlay.addClass("in");
|
||||
} else {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
var foundLocal = false;
|
||||
var foundSd = false;
|
||||
var found = false;
|
||||
var node = e.target;
|
||||
do {
|
||||
if (dropZoneLocal && node === dropZoneLocal[0]) {
|
||||
foundLocal = true;
|
||||
break;
|
||||
} else if (dropZoneSd && node === dropZoneSd[0]) {
|
||||
foundSd = true;
|
||||
break;
|
||||
} else if (dropZone && node === dropZone[0]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
node = node.parentNode;
|
||||
} while (node != null);
|
||||
|
||||
if (foundLocal) {
|
||||
dropZoneLocalBackground.addClass("hover");
|
||||
dropZoneSdBackground.removeClass("hover");
|
||||
} else if (foundSd && self.printerState.isSdReady()) {
|
||||
dropZoneSdBackground.addClass("hover");
|
||||
dropZoneLocalBackground.removeClass("hover");
|
||||
} else if (found) {
|
||||
dropZoneBackground.addClass("hover");
|
||||
} else {
|
||||
if (dropZoneLocalBackground) dropZoneLocalBackground.removeClass("hover");
|
||||
if (dropZoneSdBackground) dropZoneSdBackground.removeClass("hover");
|
||||
if (dropZoneBackground) dropZoneBackground.removeClass("hover");
|
||||
}
|
||||
|
||||
window.dropZoneTimeout = setTimeout(function () {
|
||||
window.dropZoneTimeout = null;
|
||||
dropOverlay.removeClass("in");
|
||||
if (dropZoneLocal) dropZoneLocalBackground.removeClass("hover");
|
||||
if (dropZoneSd) dropZoneSdBackground.removeClass("hover");
|
||||
if (dropZone) dropZoneBackground.removeClass("hover");
|
||||
}, 100);
|
||||
});
|
||||
|
||||
self.requestData();
|
||||
};
|
||||
|
||||
|
|
@ -680,6 +544,173 @@ $(function() {
|
|||
self.onEventTransferDone = function(payload) {
|
||||
self.requestData(payload.remote, "sdcard");
|
||||
};
|
||||
|
||||
self.onServerConnect = function(payload) {
|
||||
self._enableDragNDrop(true);
|
||||
self.requestData(undefined, undefined, self.currentPath());
|
||||
};
|
||||
|
||||
self.onServerReconnect = function(payload) {
|
||||
self._enableDragNDrop(true);
|
||||
self.requestData(undefined, undefined, self.currentPath());
|
||||
};
|
||||
|
||||
self.onServerDisconnect = function(payload) {
|
||||
self._enableDragNDrop(false);
|
||||
};
|
||||
|
||||
self._setDropzone = function(dropzone, enable) {
|
||||
var button = (dropzone == "local") ? self.uploadButton : self.uploadSdButton;
|
||||
var drop = (dropzone == "local") ? self.localTarget : self.sdTarget;
|
||||
var url = API_BASEURL + "files/" + dropzone;
|
||||
|
||||
if (button === undefined)
|
||||
return;
|
||||
|
||||
button.fileupload({
|
||||
url: url,
|
||||
dataType: "json",
|
||||
dropZone: enable ? drop : null,
|
||||
drop: function(e, data) {
|
||||
|
||||
},
|
||||
done: self._handleUploadDone,
|
||||
fail: self._handleUploadFail,
|
||||
progressall: self._handleUploadProgress
|
||||
}).bind('fileuploadsubmit', function(e, data) {
|
||||
if (self.currentPath() != "")
|
||||
data.formData = { path: self.currentPath() };
|
||||
});
|
||||
};
|
||||
|
||||
self._enableDragNDrop = function(enable) {
|
||||
if (enable) {
|
||||
$(document).bind("dragover", self._handleDragNDrop);
|
||||
log.debug("Enabled drag-n-drop");
|
||||
} else {
|
||||
$(document).unbind("dragover", self._handleDragNDrop);
|
||||
log.debug("Disabled drag-n-drop");
|
||||
}
|
||||
};
|
||||
|
||||
self._setProgressBar = function(percentage, text, active) {
|
||||
self.uploadProgressBar
|
||||
.css("width", percentage + "%")
|
||||
.text(text);
|
||||
|
||||
if (active) {
|
||||
self.uploadProgress
|
||||
.addClass("progress-striped active");
|
||||
} else {
|
||||
self.uploadProgress
|
||||
.removeClass("progress-striped active");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self._handleUploadDone = function(e, data) {
|
||||
var filename = undefined;
|
||||
var location = undefined;
|
||||
if (data.result.files.hasOwnProperty("sdcard")) {
|
||||
filename = data.result.files.sdcard.name;
|
||||
location = "sdcard";
|
||||
} else if (data.result.files.hasOwnProperty("local")) {
|
||||
filename = data.result.files.local.name;
|
||||
location = "local";
|
||||
}
|
||||
self.requestData(filename, location, self.currentPath());
|
||||
|
||||
if (data.result.done) {
|
||||
selef._setProgressBar(0, "", false);
|
||||
}
|
||||
};
|
||||
|
||||
self._handleUploadFail = function(e, data) {
|
||||
var error = "<p>" + gettext("Could not upload the file. Make sure that it is a GCODE file and has the extension \".gcode\" or \".gco\" or that it is an STL file with the extension \".stl\".") + "</p>";
|
||||
error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
|
||||
new PNotify({
|
||||
title: "Upload failed",
|
||||
text: error,
|
||||
type: "error",
|
||||
hide: false
|
||||
});
|
||||
self.setProgressBar(0, "", false);
|
||||
};
|
||||
|
||||
self._handleUploadProgress = function(e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
var uploaded = progress >= 100;
|
||||
|
||||
self.setProgressBar(progress, uploaded ? gettext("Saving ...") : gettext("Uploading ..."), uploaded);
|
||||
};
|
||||
|
||||
self._handleDragNDrop = function (e) {
|
||||
var dropOverlay = $("#drop_overlay");
|
||||
var dropZone = $("#drop");
|
||||
var dropZoneLocal = $("#drop_locally");
|
||||
var dropZoneSd = $("#drop_sd");
|
||||
var dropZoneBackground = $("#drop_background");
|
||||
var dropZoneLocalBackground = $("#drop_locally_background");
|
||||
var dropZoneSdBackground = $("#drop_sd_background");
|
||||
var timeout = window.dropZoneTimeout;
|
||||
|
||||
var dataTransfer = undefined;
|
||||
if (e.dataTransfer) {
|
||||
dataTransfer = e.dataTransfer;
|
||||
} else if (e.originalEvent && e.originalEvent.dataTransfer) {
|
||||
dataTransfer = e.originalEvent.dataTransfer;
|
||||
}
|
||||
|
||||
if (!dataTransfer || !dataTransfer.items || dataTransfer.items.length > 1 || dataTransfer.items[0].kind != "file") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
dropOverlay.addClass('in');
|
||||
} else {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
var foundLocal = false;
|
||||
var foundSd = false;
|
||||
var found = false;
|
||||
var node = e.target;
|
||||
do {
|
||||
if (dropZoneLocal && node === dropZoneLocal[0]) {
|
||||
foundLocal = true;
|
||||
break;
|
||||
} else if (dropZoneSd && node === dropZoneSd[0]) {
|
||||
foundSd = true;
|
||||
break;
|
||||
} else if (dropZone && node === dropZone[0]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
node = node.parentNode;
|
||||
} while (node != null);
|
||||
|
||||
if (foundLocal) {
|
||||
dropZoneLocalBackground.addClass("hover");
|
||||
dropZoneSdBackground.removeClass("hover");
|
||||
} else if (foundSd && self.printerState.isSdReady()) {
|
||||
dropZoneSdBackground.addClass("hover");
|
||||
dropZoneLocalBackground.removeClass("hover");
|
||||
} else if (found) {
|
||||
dropZoneBackground.addClass("hover");
|
||||
} else {
|
||||
if (dropZoneLocalBackground) dropZoneLocalBackground.removeClass("hover");
|
||||
if (dropZoneSdBackground) dropZoneSdBackground.removeClass("hover");
|
||||
if (dropZoneBackground) dropZoneBackground.removeClass("hover");
|
||||
}
|
||||
|
||||
window.dropZoneTimeout = setTimeout(function () {
|
||||
window.dropZoneTimeout = null;
|
||||
dropOverlay.removeClass("in");
|
||||
if (dropZoneLocal) dropZoneLocalBackground.removeClass("hover");
|
||||
if (dropZoneSd) dropZoneSdBackground.removeClass("hover");
|
||||
if (dropZone) dropZoneBackground.removeClass("hover");
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
|
|
|
|||
Loading…
Reference in a new issue