comparison src/plugins/plugin_misc_file.py @ 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 591e04f0103c
children 7f0c8856e4e1
comparison
equal deleted inserted replaced
1638:9e17690fb187 1639:baac2e120600
53 53
54 class SatFile(object): 54 class SatFile(object):
55 """A file-like object to have high level files manipulation""" 55 """A file-like object to have high level files manipulation"""
56 # TODO: manage "with" statement 56 # TODO: manage "with" statement
57 57
58 def __init__(self, host, path, mode='rb', uid=None, size=None, data_cb=None, profile=C.PROF_KEY_NONE): 58 def __init__(self, host, path, mode='rb', uid=None, size=None, data_cb=None, auto_end_signals=True, profile=C.PROF_KEY_NONE):
59 """ 59 """
60 @param host: %(doc_host)s 60 @param host: %(doc_host)s
61 @param path(str): path of the file to get 61 @param path(str): path of the file to get
62 @param mode(str): same as for built-in "open" function 62 @param mode(str): same as for built-in "open" function
63 @param uid(unicode, None): unique id identifing this progressing element 63 @param uid(unicode, None): unique id identifing this progressing element
64 This uid will be used with self.host.progressGet 64 This uid will be used with self.host.progressGet
65 will be automaticaly generated if None 65 will be automaticaly generated if None
66 @param size(None, int): size of the file 66 @param size(None, int): size of the file
67 @param data_cb(None, callable): method to call on each data read/write 67 @param data_cb(None, callable): method to call on each data read/write
68 mainly useful to do things like calculating hash 68 mainly useful to do things like calculating hash
69 @param auto_end_signals(bool): if True, progressFinished and progressError signals are automatically sent
70 if False, you'll have to call self.progressFinished and self.progressError yourself
71 progressStarted signal is always sent automatically
69 """ 72 """
70 self.host = host 73 self.host = host
71 self.uid = uid or unicode(uuid.uuid4()) 74 self.uid = uid or unicode(uuid.uuid4())
72 self._file = open(path, mode) 75 self._file = open(path, mode)
73 self.size = size 76 self.size = size
74 self.data_cb = data_cb 77 self.data_cb = data_cb
75 self.profile = profile 78 self.profile = profile
79 self.auto_end_signals = auto_end_signals
76 metadata = self.getProgressMetadata() 80 metadata = self.getProgressMetadata()
77 self.host.registerProgressCb(self.uid, self.getProgress, metadata, profile=profile) 81 self.host.registerProgressCb(self.uid, self.getProgress, metadata, profile=profile)
78 self.host.bridge.progressStarted(self.uid, metadata, self.profile) 82 self.host.bridge.progressStarted(self.uid, metadata, self.profile)
79 83
80 def checkSize(self): 84 def checkSize(self):
96 @param progress_metadata(None, dict): metadata to send with _onProgressFinished message 100 @param progress_metadata(None, dict): metadata to send with _onProgressFinished message
97 @param error(None, unicode): set to an error message if progress was not successful 101 @param error(None, unicode): set to an error message if progress was not successful
98 mutually exclusive with progress_metadata 102 mutually exclusive with progress_metadata
99 error can happen even if error is None, if current size differ from given size 103 error can happen even if error is None, if current size differ from given size
100 """ 104 """
105 if self._file.closed:
106 return # avoid double close (which is allowed) error
101 if error is None: 107 if error is None:
102 try: 108 try:
103 size_ok = self.checkSize() 109 size_ok = self.checkSize()
104 except exceptions.NotFound: 110 except exceptions.NotFound:
105 size_ok = True 111 size_ok = True
106 finally: 112 if not size_ok:
107 if not size_ok: 113 error = u'declared and actual size mismatch'
108 error = u'declared size and actual mismatch' 114 log.warning(error)
109 log.warning(u"successful close was requested, but there is a size mismatch") 115 progress_metadata = None
110 progress_metadata = None
111 116
112 self._file.close() 117 self._file.close()
113 118
114 if error is None: 119 if self.auto_end_signals:
115 if progress_metadata is None: 120 if error is None:
116 progress_metadata = {} 121 self.progressFinished(progress_metadata)
117 self.host.bridge.progressFinished(self.uid, progress_metadata, self.profile) 122 else:
118 else: 123 assert progress_metadata is None
119 assert progress_metadata is None 124 self.progress_errror(error)
120 self.host.bridge.progressError(self.uid, error, self.profile)
121 125
122 self.host.removeProgressCb(self.uid, self.profile) 126 self.host.removeProgressCb(self.uid, self.profile)
127
128 def progressFinished(self, metadata=None):
129 if metadata is None:
130 metadata = {}
131 self.host.bridge.progressFinished(self.uid, metadata, self.profile)
132
133 def progressError(self, error):
134 self.host.bridge.progressError(self.uid, error, self.profile)
123 135
124 def flush(self): 136 def flush(self):
125 self._file.flush() 137 self._file.flush()
126 138
127 def write(self, buf): 139 def write(self, buf):