changeset 1639:baac2e120600

plugin file[SatFile]: auto_end_signals flag can be False if the progressFinished and progressError signals are managed by caller.
author Goffi <goffi@goffi.org>
date Sun, 22 Nov 2015 17:27:27 +0100
parents 9e17690fb187
children d470affbe65c
files src/plugins/plugin_misc_file.py
diffstat 1 files changed, 25 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_misc_file.py	Sat Nov 21 13:58:30 2015 +0100
+++ b/src/plugins/plugin_misc_file.py	Sun Nov 22 17:27:27 2015 +0100
@@ -55,7 +55,7 @@
     """A file-like object to have high level files manipulation"""
     # TODO: manage "with" statement
 
-    def __init__(self, host, path, mode='rb', uid=None, size=None, data_cb=None, profile=C.PROF_KEY_NONE):
+    def __init__(self, host, path, mode='rb', uid=None, size=None, data_cb=None, auto_end_signals=True, profile=C.PROF_KEY_NONE):
         """
         @param host: %(doc_host)s
         @param path(str): path of the file to get
@@ -66,6 +66,9 @@
         @param size(None, int): size of the file
         @param data_cb(None, callable): method to call on each data read/write
             mainly useful to do things like calculating hash
+        @param auto_end_signals(bool): if True, progressFinished and progressError signals are automatically sent
+            if False, you'll have to call self.progressFinished and self.progressError yourself
+            progressStarted signal is always sent automatically
         """
         self.host = host
         self.uid = uid or unicode(uuid.uuid4())
@@ -73,6 +76,7 @@
         self.size = size
         self.data_cb = data_cb
         self.profile = profile
+        self.auto_end_signals = auto_end_signals
         metadata = self.getProgressMetadata()
         self.host.registerProgressCb(self.uid, self.getProgress, metadata, profile=profile)
         self.host.bridge.progressStarted(self.uid, metadata, self.profile)
@@ -98,29 +102,37 @@
             mutually exclusive with progress_metadata
             error can happen even if error is None, if current size differ from given size
         """
+        if self._file.closed:
+            return # avoid double close (which is allowed) error
         if error is None:
             try:
                 size_ok = self.checkSize()
             except exceptions.NotFound:
                 size_ok = True
-            finally:
-                if not size_ok:
-                    error = u'declared size and actual mismatch'
-                    log.warning(u"successful close was requested, but there is a size mismatch")
-                    progress_metadata = None
+            if not size_ok:
+                error = u'declared and actual size mismatch'
+                log.warning(error)
+                progress_metadata = None
 
         self._file.close()
 
-        if error is None:
-            if progress_metadata is None:
-                progress_metadata = {}
-            self.host.bridge.progressFinished(self.uid, progress_metadata, self.profile)
-        else:
-            assert progress_metadata is None
-            self.host.bridge.progressError(self.uid, error, self.profile)
+        if self.auto_end_signals:
+            if error is None:
+                self.progressFinished(progress_metadata)
+            else:
+                assert progress_metadata is None
+                self.progress_errror(error)
 
         self.host.removeProgressCb(self.uid, self.profile)
 
+    def progressFinished(self, metadata=None):
+        if metadata is None:
+            metadata = {}
+        self.host.bridge.progressFinished(self.uid, metadata, self.profile)
+
+    def progressError(self, error):
+        self.host.bridge.progressError(self.uid, error, self.profile)
+
     def flush(self):
         self._file.flush()