Mercurial > libervia-backend
diff src/plugins/plugin_misc_file.py @ 1626:63cef4dbf2a4
core, plugins file, XEP-0234, bridge: progression api enhancement:
- progressStarted have a new metadata parameter, useful to know the kind of progression, direction, etc. Check bridge doc
- progressGetAllMetadata can be used to retrieve this data and discover on currently running progressions
- progressFinished also have a new metadata parameter, used to e.g. indicate that hash is checked
- core: fixed progressGetAll
- file, XEP-0234: implemented the API modifications, hash is returned on progressFinished
- file: SatFile.checkSize allows to check size independently of close (be sure that all the data have been transfered though)
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 19 Nov 2015 18:13:26 +0100 |
parents | 3ec7511dbf28 |
children | 591e04f0103c |
line wrap: on
line diff
--- a/src/plugins/plugin_misc_file.py Thu Nov 19 11:15:06 2015 +0100 +++ b/src/plugins/plugin_misc_file.py Thu Nov 19 18:13:26 2015 +0100 @@ -71,16 +71,52 @@ self.size = size self.data_cb = data_cb self.profile = profile - self.host.registerProgressCb(self.uid, self.getProgress, profile) - self.host.bridge.progressStarted(self.uid, self.profile) + metadata = self.getProgressMetadata() + self.host.registerProgressCb(self.uid, self.getProgress, metadata, profile=profile) + self.host.bridge.progressStarted(self.uid, metadata, self.profile) - def close(self): + def checkSize(self): + """Check that current size correspond to given size + + must be used when the transfer is supposed to be finished + @return (bool): True if the position is the same as given size + @raise exceptions.NotFound: size has not be specified + """ position = self._file.tell() + if self.size is None: + raise exceptions.NotFound + return position == self.size + + + def close(self, progress_metadata=None, error=None): + """Close the current file + + @param progress_metadata(None, dict): metadata to send with _onProgressFinished message + @param error(None, unicode): set to an error message if progress was not successful + mutually exclusive with progress_metadata + error can happen even if error is None, if current size differ from given size + """ + 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 + self._file.close() - if not self.size or self.size == position: - self.host.bridge.progressFinished(self.uid, self.profile) + + if error is None: + if progress_metadata is None: + progress_metadata = {} + self.host.bridge.progressFinished(self.uid, progress_metadata, self.profile) else: - self.host.bridge.progressError(self.uid, u"size doesn't match", self.profile) + assert progress_metadata is None + self.host.bridge.progressError(self.uid, error, self.profile) + self.host.removeProgressCb(self.uid, self.profile) def flush(self): @@ -103,6 +139,32 @@ def tell(self): return self._file.tell() + def mode(self): + return self._file.mode() + + def getProgressMetadata(self): + """Return progression metadata as given to progressStarted + + @return (dict): metadata (check bridge for documentation) + """ + metadata = {'type': C.META_TYPE_FILE} + + mode = self._file.mode + if '+' in mode: + pass # we have no direction in read/write modes + elif mode in ('r', 'rb'): + metadata['direction'] = 'out' + elif mode in ('w', 'wb'): + metadata['direction'] = 'in' + elif 'U' in mode: + metadata['direction'] = 'out' + else: + raise exceptions.InternalError + + metadata['name'] = self._file.name + + return metadata + def getProgress(self, progress_id, profile): ret = {'position': self._file.tell()} if self.size: