def cancel(self, reason=None): if reason: msg = "download stream cancelled: %s" % reason else: msg = "download stream cancelled" if self.data_downloading_deferred and not self.data_downloading_deferred.called: self.data_downloading_deferred.errback(DownloadCanceledError(msg))
def stop(self): if self.running: for d in reversed(self.deferreds): d.cancel() for writer in self.writers: writer.close(DownloadCanceledError()) self.running = False self.blob_hashes = []
def close(self, reason=None): # if we've already called finished_cb because we either finished writing # or closed already, do nothing if self.finished_cb_d is not None: return if reason is None: reason = Failure(DownloadCanceledError()) self.finished_cb_d = self.finished_cb(self, reason)
def _save_verified_blob(self, writer): if not self.data_buffer: self.data_buffer = writer.write_handle.getvalue() writer.write_handle.close() writer.write_handle = None return defer.succeed(True) else: return defer.fail(Failure(DownloadCanceledError()))
def _save_verified_blob(self, writer): if self.saved_verified_blob is False: writer.write_handle.seek(0) out_path = os.path.join(self.blob_dir, self.blob_hash) producer = FileBodyProducer(writer.write_handle) yield producer.startProducing(open(out_path, 'wb')) self.saved_verified_blob = True defer.returnValue(True) else: raise DownloadCanceledError()
def move_file(): with self.setting_verified_blob_lock: if self.moved_verified_blob is False: temp_file_name = writer.write_handle.name writer.write_handle.close() shutil.move(temp_file_name, self.file_path) writer.write_handle = None self.moved_verified_blob = True return True else: raise DownloadCanceledError()
def stop(self): for d in reversed(self.deferreds): d.cancel() while self.writers: writer = self.writers.pop() writer.close(DownloadCanceledError()) self.blob_hashes = [] if self.looping_call.running: self.looping_call.stop() if self.lc_deferred and not self.lc_deferred.called: self.lc_deferred.cancel() if not self.finished_deferred.called: self.finished_deferred.cancel()
def writer_finished(self, writer, err=None): def fire_finished_deferred(): self.verified = True for p, (w, finished_deferred) in self.writers.items(): if w == writer: finished_deferred.callback(self) del self.writers[p] return True log.warning( "Somehow, the writer that was accepted as being valid was already removed. writer: %s", str(writer)) return False def errback_finished_deferred(err): for p, (w, finished_deferred) in self.writers.items(): if w == writer: finished_deferred.errback(err) del self.writers[p] def cancel_other_downloads(): for p, (w, finished_deferred) in self.writers.items(): w.cancel() if err is None: if writer.len_so_far == self.length and writer.hashsum.hexdigest( ) == self.blob_hash: if self.verified is False: d = self._save_verified_blob(writer) d.addCallbacks(lambda _: fire_finished_deferred(), errback_finished_deferred) d.addCallback(lambda _: cancel_other_downloads()) else: errback_finished_deferred(Failure(DownloadCanceledError())) d = defer.succeed(True) else: err_string = "length vs expected: {0}, {1}, hash vs expected: {2}, {3}" err_string = err_string.format(self.length, writer.len_so_far, self.blob_hash, writer.hashsum.hexdigest()) errback_finished_deferred(Failure( InvalidDataError(err_string))) d = defer.succeed(True) else: errback_finished_deferred(err) d = defer.succeed(True) d.addBoth(lambda _: self._close_writer(writer)) return d
def cancel(self, reason=None): if reason is None: reason = Failure(DownloadCanceledError()) self.finished_cb(self, reason)