Keep track of files that are currently being used (file being printed, source and destination for slicing) so that they can't be deleted
Also added logging to exception branches where the exception was formerly just swallowed.
This commit is contained in:
parent
0ab5369635
commit
6e62ecc8c1
8 changed files with 59 additions and 19 deletions
|
|
@ -187,6 +187,15 @@ class FileManager(object):
|
|||
finally:
|
||||
os.remove(tmp_path)
|
||||
|
||||
source_job_key = (source_location, source_path)
|
||||
dest_job_key = (dest_location, dest_path)
|
||||
|
||||
with self._slicing_jobs_mutex:
|
||||
if source_job_key in self._slicing_jobs:
|
||||
del self._slicing_jobs[source_job_key]
|
||||
if dest_job_key in self._slicing_jobs:
|
||||
del self._slicing_jobs[dest_job_key]
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
eventManager().fire(Events.SLICING_STARTED, {"stl": source_path, "gcode": dest_path})
|
||||
|
|
@ -197,13 +206,15 @@ class FileManager(object):
|
|||
f.close()
|
||||
|
||||
with self._slicing_jobs_mutex:
|
||||
if dest_location in self._slicing_jobs:
|
||||
job_slicer_name, job_absolute_source_path, job_temp_path = self._slicing_jobs[dest_location]
|
||||
source_job_key = (source_location, source_path)
|
||||
dest_job_key = (dest_location, dest_path)
|
||||
if dest_job_key in self._slicing_jobs:
|
||||
job_slicer_name, job_absolute_source_path, job_temp_path = self._slicing_jobs[dest_job_key]
|
||||
|
||||
self._slicing_manager.cancel_slicing(job_slicer_name, job_absolute_source_path, job_temp_path)
|
||||
del self._slicing_jobs[dest_location]
|
||||
del self._slicing_jobs[dest_job_key]
|
||||
|
||||
self._slicing_jobs[dest_location] = (slicer_name, absolute_source_path, temp_path)
|
||||
self._slicing_jobs[dest_job_key] = self._slicing_jobs[source_job_key] = (slicer_name, absolute_source_path, temp_path)
|
||||
|
||||
args = (source_location, source_path, temp_path, dest_location, dest_path, start_time, callback, callback_args)
|
||||
return self._slicing_manager.slice(
|
||||
|
|
@ -229,7 +240,10 @@ class FileManager(object):
|
|||
|
||||
for callback in self._slicing_progress_callbacks:
|
||||
try: callback.sendSlicingProgress(slicer, source_location, source_path, dest_location, dest_path, progress_int)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while pushing slicing progress")
|
||||
|
||||
def get_busy_files(self):
|
||||
return self._slicing_jobs.keys()
|
||||
|
||||
def file_exists(self, destination, path):
|
||||
return self._storage(destination).file_exists(path)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ class Printer():
|
|||
def __init__(self, fileManager, analysisQueue):
|
||||
from collections import deque
|
||||
|
||||
self._logger = logging.getLogger(__name__)
|
||||
|
||||
self._analysisQueue = analysisQueue
|
||||
self._fileManager = fileManager
|
||||
|
||||
|
|
@ -120,32 +122,32 @@ class Printer():
|
|||
def _sendAddTemperatureCallbacks(self, data):
|
||||
for callback in self._callbacks:
|
||||
try: callback.addTemperature(data)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while adding temperature data point")
|
||||
|
||||
def _sendAddLogCallbacks(self, data):
|
||||
for callback in self._callbacks:
|
||||
try: callback.addLog(data)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while adding communication log entry")
|
||||
|
||||
def _sendAddMessageCallbacks(self, data):
|
||||
for callback in self._callbacks:
|
||||
try: callback.addMessage(data)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while adding printer message")
|
||||
|
||||
def _sendCurrentDataCallbacks(self, data):
|
||||
for callback in self._callbacks:
|
||||
try: callback.sendCurrentData(copy.deepcopy(data))
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while pushing current data")
|
||||
|
||||
def _sendTriggerUpdateCallbacks(self, type):
|
||||
for callback in self._callbacks:
|
||||
try: callback.sendEvent(type)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while pushing trigger update")
|
||||
|
||||
def _sendFeedbackCommandOutput(self, name, output):
|
||||
for callback in self._callbacks:
|
||||
try: callback.sendFeedbackCommandOutput(name, output)
|
||||
except: pass
|
||||
except: self._logger.exception("Exception while pushing feedback command output")
|
||||
|
||||
#~~ callback from metadata analysis event
|
||||
|
||||
|
|
@ -248,7 +250,7 @@ class Printer():
|
|||
|
||||
def selectFile(self, filename, sd, printAfterSelect=False):
|
||||
if self._comm is None or (self._comm.isBusy() or self._comm.isStreaming()):
|
||||
logging.info("Cannot load file: printer not connected or currently busy")
|
||||
self._logger.info("Cannot load file: printer not connected or currently busy")
|
||||
return
|
||||
|
||||
self._printAfterSelect = printAfterSelect
|
||||
|
|
@ -559,7 +561,7 @@ class Printer():
|
|||
|
||||
def addSdFile(self, filename, absolutePath, streamingFinishedCallback):
|
||||
if not self._comm or self._comm.isBusy() or not self._comm.isSdReady():
|
||||
logging.error("No connection to printer or printer is busy")
|
||||
self._logger.error("No connection to printer or printer is busy")
|
||||
return
|
||||
|
||||
self._streamingFinishedCallback = streamingFinishedCallback
|
||||
|
|
|
|||
|
|
@ -370,11 +370,14 @@ def deleteGcodeFile(filename, target):
|
|||
if not _verifyFileExists(target, filename):
|
||||
return make_response("File not found on '%s': %s" % (target, filename), 404)
|
||||
|
||||
# prohibit deleting the file that is currently being printed
|
||||
# prohibit deleting files that are currently in use
|
||||
currentOrigin, currentFilename = _getCurrentFile()
|
||||
if currentFilename == filename and currentOrigin == target and (printer.isPrinting() or printer.isPaused()):
|
||||
make_response("Trying to delete file that is currently being printed: %s" % filename, 409)
|
||||
|
||||
if (target, filename) in fileManager.get_busy_files():
|
||||
make_response("Trying to delete a file that is currently in use: %s" % filename, 409)
|
||||
|
||||
# deselect the file if it's currently selected
|
||||
if currentFilename is not None and filename == currentFilename:
|
||||
printer.unselectFile()
|
||||
|
|
|
|||
|
|
@ -83,10 +83,18 @@ class PrinterStateConnection(sockjs.tornado.SockJSConnection):
|
|||
messages = self._messageBacklog
|
||||
self._messageBacklog = []
|
||||
|
||||
busy_files = [dict(origin=v[0], name=v[1]) for v in self._fileManager.get_busy_files()]
|
||||
if "job" in data and data["job"] is not None \
|
||||
and "file" in data["job"] and "name" in data["job"]["file"] and "origin" in data["job"]["file"] \
|
||||
and data["job"]["file"]["name"] is not None and data["job"]["file"]["origin"] is not None \
|
||||
and (self._printer.isPrinting() or self._printer.isPaused()):
|
||||
busy_files.append(dict(origin=data["job"]["file"]["origin"], name=data["job"]["file"]["name"]))
|
||||
|
||||
data.update({
|
||||
"temps": temperatures,
|
||||
"logs": logs,
|
||||
"messages": messages
|
||||
"messages": messages,
|
||||
"busyFiles": busy_files,
|
||||
})
|
||||
self._emit("current", data)
|
||||
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ class SlicingManager(object):
|
|||
|
||||
if not ok:
|
||||
callback_kwargs.update(dict(_error=result))
|
||||
callback(*callback_args, **callback_kwargs)
|
||||
except SlicingCancelled:
|
||||
callback_kwargs.update(dict(_cancelled=True))
|
||||
finally:
|
||||
callback(*callback_args, **callback_kwargs)
|
||||
|
||||
import threading
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel, slicing
|
|||
};
|
||||
|
||||
self.getEntryId = function(data) {
|
||||
return "gcode_file_" + md5(data["name"] + ":" + data["origin"]);
|
||||
return "gcode_file_" + md5(data["origin"] + ":" + data["name"]);
|
||||
};
|
||||
|
||||
self.getEntryElement = function(data) {
|
||||
|
|
@ -253,7 +253,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel, slicing
|
|||
};
|
||||
|
||||
self.enableRemove = function(data) {
|
||||
return self.loginState.isUser() && !(self.listHelper.isSelected(data) && (self.isPrinting() || self.isPaused()));
|
||||
return self.loginState.isUser() && !_.contains(self.printerState.busyFiles(), data.origin + ":" + data.name);
|
||||
};
|
||||
|
||||
self.enableSelect = function(data, printAfterSelect) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ function PrinterStateViewModel(loginStateViewModel) {
|
|||
self.sd = ko.observable(undefined);
|
||||
self.timelapse = ko.observable(undefined);
|
||||
|
||||
self.busyFiles = ko.observableArray([]);
|
||||
|
||||
self.filament = ko.observableArray([]);
|
||||
self.estimatedPrintTime = ko.observable(undefined);
|
||||
self.lastPrintTime = ko.observable(undefined);
|
||||
|
|
@ -109,6 +111,7 @@ function PrinterStateViewModel(loginStateViewModel) {
|
|||
self._processJobData(data.job);
|
||||
self._processProgressData(data.progress);
|
||||
self._processZData(data.currentZ);
|
||||
self._processBusyFiles(data.busyFiles);
|
||||
};
|
||||
|
||||
self._processStateData = function(data) {
|
||||
|
|
@ -177,6 +180,16 @@ function PrinterStateViewModel(loginStateViewModel) {
|
|||
self.currentHeight(data);
|
||||
};
|
||||
|
||||
self._processBusyFiles = function(data) {
|
||||
var busyFiles = [];
|
||||
_.each(data, function(entry) {
|
||||
if (entry.hasOwnProperty("name") && entry.hasOwnProperty("origin")) {
|
||||
busyFiles.push(entry.origin + ":" + entry.name);
|
||||
}
|
||||
});
|
||||
self.busyFiles(busyFiles);
|
||||
};
|
||||
|
||||
self.print = function() {
|
||||
var restartCommand = function() {
|
||||
self._jobCommand("restart");
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ def notifyCallbacks(timelapse):
|
|||
config = timelapse.configData()
|
||||
for callback in updateCallbacks:
|
||||
try: callback.sendTimelapseConfig(config)
|
||||
except: pass
|
||||
except: logging.getLogger(__name__).exception("Exception while pushing timelapse configuration")
|
||||
|
||||
|
||||
def configureTimelapse(config=None, persist=False):
|
||||
|
|
|
|||
Loading…
Reference in a new issue