Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <silbe@activitycentral.com>2011-11-02 22:05:36 (GMT)
committer Sascha Silbe <silbe@activitycentral.com>2012-03-13 19:10:43 (GMT)
commit9fd345f4b87c074cf50e82376020b66667585eac (patch)
treea523ec84908904f10c9cdb72e4769026f7b9df2b
parent23fe6f8896c0b6747bae79ab33826376307cfc2c (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.py20
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,