From ecdf02b7aa3ba3248ecfe9df80888027f2b57099 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Mon, 13 Sep 2010 19:02:21 +0000 Subject: more Sugar 0.82 compatibility tricks --- diff --git a/restore.py b/restore.py index dbf562c..1f378e3 100644 --- a/restore.py +++ b/restore.py @@ -20,6 +20,7 @@ import gettext import logging import os import select +import shutil import sys import tempfile import time @@ -141,6 +142,7 @@ class AsyncRestore(gobject.GObject): self._pipe_from_child_watch_id = None self._data_store = None self._data_store_version = None + self._data_store_mount_id = None def start(self): """Start the restore process.""" @@ -329,12 +331,14 @@ class AsyncRestore(gobject.GObject): data_fd, data_file_name = tempfile.mkstemp(prefix='Restore', dir=self._tmp_dir) data_file = os.fdopen(data_fd, 'w') - os.chmod(data_file_name, 0640) + os.chmod(data_file_name, 0644) try: - # TODO: handle large files better (i.e. use external tool) # TODO: predict disk-full - data_file.write(self._bundle.read( - os.path.join(object_id, object_id))) + in_file = self._bundle.open(os.path.join(object_id, object_id)) + try: + shutil.copyfileobj(in_file, data_file) + finally: + in_file.close() return data_file_name finally: data_file.close() @@ -420,13 +424,32 @@ class AsyncRestore(gobject.GObject): timeout=DS_DBUS_SIMPLE_FIND_TIMEOUT) if 'uri' in self._data_store.mounts()[0]: self._data_store_version = 82 + data_store_path = '/home/olpc/.sugar/default/datastore' + self._data_store_mount_id = [mount['id'] + for mount in self._data_store.mounts() + if mount['uri'] == data_store_path][0] logging.info('0.82 data store found') else: logging.info('0.84+ data store without version support found') self._data_store_version = 84 + def _get_timestamp(self, metadata): + if 'timestamp' in metadata: + return float(metadata['timestamp']) + elif 'mtime' in metadata: + return time.mktime(time.strptime(metadata['mtime'], CTIME_FORMAT)) + elif 'ctime' in metadata: + return time.mktime(time.strptime(metadata['ctime'], CTIME_FORMAT)) + + logging.warning('Entry without any kind of timestamp: %r', metadata) + return 0 + def _save_entry(self, metadata, data_path): """Store object in data store.""" + timestamp = self._get_timestamp(metadata) + # workaround for SL#1590 + metadata['timestamp'] = str(int(timestamp)) + if self._data_store.dbus_interface == DS_DBUS_INTERFACE2: tree_id = metadata.get('tree_id') or metadata['uid'] version_id = metadata.get('version_id', '') @@ -436,22 +459,13 @@ class AsyncRestore(gobject.GObject): version_id) return - # workaround for SL#1590 - timestamp = metadata.get('timestamp') or \ - time.mktime(time.strptime(metadata['ctime'], CTIME_FORMAT)) - metadata['timestamp'] = str(int(float(timestamp))) self._data_store.save(tree_id, parent_id, metadata, data_path, True, timeout=DS_DBUS_SAVE_TIMEOUT) else: uid = metadata.get('uid') or metadata['tree_id'] - timestamp = metadata.get('timestamp') or \ - time.mktime(time.strptime(metadata['ctime'], CTIME_FORMAT)) - timestamp = float(timestamp) entry = self._find_entry_v1(uid) if entry: - ds_timestamp = entry.get('timestamp') or \ - time.mktime(time.strptime(entry['ctime'], CTIME_FORMAT)) - ds_timestamp = float(ds_timestamp) + ds_timestamp = self._get_timestamp(entry) if ds_timestamp >= timestamp: logging.info('Skipping outdated entry for %r', uid) @@ -461,12 +475,12 @@ class AsyncRestore(gobject.GObject): else: logging.info('Restoring entry %r', uid) - # workaround for SL#1590 - metadata['timestamp'] = str(int(timestamp)) - if self._data_store_version == 82: metadata['uid'] = uid metadata.pop('mountpoint', None) + metadata['mtime'] = time.strftime(CTIME_FORMAT, time.localtime(timestamp)) + + if self._data_store_version == 82 and not entry: self._data_store.create(metadata, data_path, True, timeout=DS_DBUS_SAVE_TIMEOUT) else: @@ -477,7 +491,7 @@ class AsyncRestore(gobject.GObject): """Retrieve given entry from v1 data store if it exists. """ try: - return self._data_store.get_properties(uid, byte_arrays=True, + entry = self._data_store.get_properties(uid, byte_arrays=True, timeout=DS_DBUS_SIMPLE_FIND_TIMEOUT) except dbus.DBusException, exception: @@ -487,6 +501,12 @@ class AsyncRestore(gobject.GObject): raise + if self._data_store_version == 82 and \ + entry['mountpoint'] != self._data_store_mount_id: + return None + + return entry + def _find_entry_v2(self, tree_id, version_id): """Retrieve given entry from v2 data store if it exists. """ -- cgit v0.9.1