Allow cancelling file transfers

Cancelling also deletes the incomplete file on the printer's SD.
This commit is contained in:
Gina Häußge 2017-07-28 13:08:28 +02:00
parent ec55890c55
commit 60be6349f5
4 changed files with 78 additions and 23 deletions

View file

@ -62,6 +62,7 @@ class Events(object):
# SD Upload
TRANSFER_STARTED = "TransferStarted"
TRANSFER_DONE = "TransferDone"
TRANSFER_FAILED = "TransferFailed"
# print job
PRINT_STARTED = "PrintStarted"

View file

@ -71,6 +71,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
self._sdStreaming = False
self._sdFilelistAvailable = threading.Event()
self._streamingFinishedCallback = None
self._streamingFailedCallback = None
self._selectedFileMutex = threading.RLock()
self._selectedFile = None
@ -579,12 +580,13 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
return []
return map(lambda x: (x[0][1:], x[1]), self._comm.getSdFiles())
def add_sd_file(self, filename, absolutePath, streamingFinishedCallback):
def add_sd_file(self, filename, absolutePath, on_success=None, on_failure=None):
if not self._comm or self._comm.isBusy() or not self._comm.isSdReady():
self._logger.error("No connection to printer or printer is busy")
return
self._streamingFinishedCallback = streamingFinishedCallback
self._streamingFinishedCallback = on_success
self._streamingFailedCallback = on_failure
self.refresh_sd_files(blocking=True)
existingSdFiles = map(lambda x: x[0], self._comm.getSdFiles())
@ -1171,19 +1173,26 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
self._updateProgressData(completion=0.0, filepos=0, printTime=0)
self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()})
def on_comm_file_transfer_done(self, filename):
def on_comm_file_transfer_done(self, filename, failed=False):
self._sdStreaming = False
if self._streamingFinishedCallback is not None:
# in case of SD files, both filename and absolutePath are the same, so we set the (remote) filename for
# both parameters
self._streamingFinishedCallback(filename, filename, FileDestinations.SDCARD)
# in case of SD files, both filename and absolutePath are the same, so we set the (remote) filename for
# both parameters
if failed:
if self._streamingFailedCallback is not None:
self._streamingFailedCallback(filename, filename, FileDestinations.SDCARD)
else:
if self._streamingFinishedCallback is not None:
self._streamingFinishedCallback(filename, filename, FileDestinations.SDCARD)
self._setCurrentZ(None)
self._setJobData(None, None, None)
self._updateProgressData()
self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()})
def on_comm_file_transfer_failed(self, filename):
self.on_comm_file_transfer_done(filename, failed=True)
def on_comm_force_disconnect(self):
self.disconnect()

View file

@ -954,6 +954,23 @@ $(function() {
self.requestData({focus: {location: "sdcard", path: payload.remote}});
};
self.onEventTransferFailed = function(payload) {
self.uploadProgress
.removeClass("progress-striped")
.removeClass("active");
self.uploadProgressBar
.css("width", "0");
self.uploadProgressText("");
new PNotify({
title: gettext("Streaming failed"),
text: _.sprintf(gettext("Did not finish streaming %(local)s to %(remote)s on SD"), payload),
type: "error"
});
self.requestData();
};
self.onServerConnect = self.onServerReconnect = function(payload) {
self._enableDragNDrop(true);
self.requestData();

View file

@ -877,7 +877,7 @@ class MachineCom(object):
def startFileTransfer(self, filename, localFilename, remoteFilename):
if not self.isOperational() or self.isBusy():
logging.info("Printer is not operational or busy")
self._logger.info("Printer is not operational or busy")
return
with self._jobLock:
@ -890,6 +890,39 @@ class MachineCom(object):
eventManager().fire(Events.TRANSFER_STARTED, {"local": localFilename, "remote": remoteFilename})
self._callback.on_comm_file_transfer_started(remoteFilename, self._currentFile.getFilesize())
def cancelFileTransfer(self):
if not self.isOperational() or not self.isStreaming():
self._logger.info("Printer is not operational or not streaming")
return
self._finishFileTransfer(failed=True)
def _finishFileTransfer(self, failed=False):
with self._jobLock:
remote = self._currentFile.getRemoteFilename()
self._sendCommand("M29")
if failed:
self.deleteSdFile(remote)
payload = {
"local": self._currentFile.getLocalFilename(),
"remote": remote,
"time": self.getPrintTime()
}
self._currentFile = None
self._changeState(self.STATE_OPERATIONAL)
if failed:
self._callback.on_comm_file_transfer_failed(remote)
eventManager().fire(Events.TRANSFER_FAILED, payload)
else:
self._callback.on_comm_file_transfer_done(remote)
eventManager().fire(Events.TRANSFER_DONE, payload)
self.refreshSdFiles()
def selectFile(self, filename, sd):
if self.isBusy():
return
@ -920,13 +953,18 @@ class MachineCom(object):
self._callback.on_comm_print_job_cancelled()
def cancelPrint(self, firmware_error=None):
if not self.isOperational() or self.isStreaming():
if not self.isOperational():
return
if not self.isBusy() or self._currentFile is None:
# we aren't even printing, nothing to cancel...
return
if self.isStreaming():
# we are streaming, we handle cancelling that differently...
self.cancelFileTransfer()
return
def _on_M400_sent():
# we don't call on_print_job_cancelled on our callback here
# because we do this only after our M114 has been answered
@ -1964,20 +2002,7 @@ class MachineCom(object):
line = self._currentFile.getNext()
if line is None:
if self.isStreaming():
self._sendCommand("M29")
remote = self._currentFile.getRemoteFilename()
payload = {
"local": self._currentFile.getLocalFilename(),
"remote": remote,
"time": self.getPrintTime()
}
self._currentFile = None
self._changeState(self.STATE_OPERATIONAL)
self._callback.on_comm_file_transfer_done(remote)
eventManager().fire(Events.TRANSFER_DONE, payload)
self.refreshSdFiles()
self._finishFileTransfer()
else:
self._callback.on_comm_print_job_done()
self._changeState(self.STATE_OPERATIONAL)
@ -2726,6 +2751,9 @@ class MachineComPrintCallback(object):
def on_comm_file_transfer_done(self, filename):
pass
def on_comm_file_transfer_failed(self, filename):
pass
def on_comm_force_disconnect(self):
pass