diff options
author | Sascha Silbe <silbe@activitycentral.com> | 2011-11-02 22:05:36 (GMT) |
---|---|---|
committer | Sascha Silbe <silbe@activitycentral.com> | 2012-03-13 19:10:43 (GMT) |
commit | 9fd345f4b87c074cf50e82376020b66667585eac (patch) | |
tree | a523ec84908904f10c9cdb72e4769026f7b9df2b | |
parent | 23fe6f8896c0b6747bae79ab33826376307cfc2c (diff) |
Ensure we return valid internal / calculated properties
The copy in the metadata storage can get corrupted, e.g. due to low level
crashes or running out of battery (see OLPC#11372 [1] for a real-life
example).
This is especially problematic for the uid property, since without it the
caller (i.e. the Journal) can't even figure out which entry to delete.
We now determine and fill in the 'filesize' and 'uid' properties in find()
and get_properties(), instead of relying on the on-disk copy in
.../metadata/{filesize,uid}.
[1] https://dev.laptop.org/ticket/11372
Reported-by: Gary Martin <garycmartin@googlemail.com>
Signed-off-by: Sascha Silbe <silbe@activitycentral.com>
Acked-by: Simon Schampijer <simon@laptop.org>
-rw-r--r-- | src/carquinyol/datastore.py | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/carquinyol/datastore.py b/src/carquinyol/datastore.py index 41ec2c3..de79500 100644 --- a/src/carquinyol/datastore.py +++ b/src/carquinyol/datastore.py @@ -310,6 +310,7 @@ class DataStore(dbus.service.Object): return self._find_all(query, properties) metadata = self._metadata_store.retrieve(uid, properties) + self._fill_internal_props(metadata, uid, properties) entries.append(metadata) logger.debug('find(): %r', time.time() - t) @@ -327,10 +328,28 @@ class DataStore(dbus.service.Object): entries = [] for uid in uids: metadata = self._metadata_store.retrieve(uid, properties) + self._fill_internal_props(metadata, uid, properties) entries.append(metadata) return entries, count + def _fill_internal_props(self, metadata, uid, names=None): + """Fill in internal / computed properties in metadata + + Properties are only set if they appear in names or if names is + empty. + """ + if not names or 'uid' in names: + metadata['uid'] = uid + + if not names or 'filesize' in names: + file_path = self._file_store.get_file_path(uid) + if os.path.exists(file_path): + stat = os.stat(file_path) + metadata['filesize'] = str(stat.st_size) + else: + metadata['filesize'] = '0' + @dbus.service.method(DS_DBUS_INTERFACE, in_signature='s', out_signature='s', @@ -353,6 +372,7 @@ class DataStore(dbus.service.Object): def get_properties(self, uid): logging.debug('datastore.get_properties %r', uid) metadata = self._metadata_store.retrieve(uid) + self._fill_internal_props(metadata, uid) return metadata @dbus.service.method(DS_DBUS_INTERFACE, |