From d97ee793009b2ac9c94c11895eee23fc18be16ee Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Wed, 19 Aug 2009 20:36:07 +0000 Subject: use sugar.datastore.* instead of direct DBus access --- diff --git a/src/sugar/activity/activityfactory.py b/src/sugar/activity/activityfactory.py index dcd840f..462a0f9 100644 --- a/src/sugar/activity/activityfactory.py +++ b/src/sugar/activity/activityfactory.py @@ -30,6 +30,7 @@ from sugar.presence import presenceservice from sugar.activity.activityhandle import ActivityHandle from sugar import util from sugar import env +from sugar.datastore import datastore from errno import EEXIST, ENOSPC @@ -42,10 +43,6 @@ _SHELL_SERVICE = "org.laptop.Shell" _SHELL_PATH = "/org/laptop/Shell" _SHELL_IFACE = "org.laptop.Shell" -_DS_SERVICE = "org.laptop.sugar.DataStore" -_DS_INTERFACE = "org.laptop.sugar.DataStore" -_DS_PATH = "/org/laptop/sugar/DataStore" - _ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory" # helper method to close all filedescriptors @@ -210,13 +207,9 @@ class ActivityCreationHandler(gobject.GObject): self._shell = dbus.Interface(bus_object, _SHELL_IFACE) if handle.activity_id is not None and handle.object_id is None: - datastore = dbus.Interface( - bus.get_object(_DS_SERVICE, _DS_PATH), _DS_INTERFACE) datastore.find({'activity_id': self._handle.activity_id}, - [], reply_handler=self._find_object_reply_handler, - error_handler=self._find_object_error_handler, - byte_arrays=True) + error_handler=self._find_object_error_handler) else: self._launch_activity() diff --git a/src/sugar/datastore/datastore.py b/src/sugar/datastore/datastore.py index 80d5936..e45367d 100644 --- a/src/sugar/datastore/datastore.py +++ b/src/sugar/datastore/datastore.py @@ -28,6 +28,7 @@ import gobject from sugar.datastore import dbus_helpers from sugar import mime +from sugar import dispatch class DSMetadata(gobject.GObject): __gsignals__ = { @@ -40,7 +41,7 @@ class DSMetadata(gobject.GObject): if not props: self._props = {} else: - self._props = props + self._props = dict(props) default_keys = ['activity', 'activity_id', 'mime_type', 'title_set_by_user'] @@ -67,7 +68,10 @@ class DSMetadata(gobject.GObject): def keys(self): return self._props.keys() - + + def items(self): + return self._props.items() + def get_dictionary(self): return self._props @@ -75,10 +79,12 @@ class DSMetadata(gobject.GObject): return DSMetadata(self._props.copy()) def get(self, key, default=None): - if self._props.has_key(key): - return self._props[key] - else: - return default + return self._props.get(key, default) + + def update(self, d): + for (k, v) in d.items(): + self[k] = v + class DSObject(object): def __init__(self, object_id, metadata=None, file_path=None): @@ -90,7 +96,7 @@ class DSObject(object): def get_metadata(self): if self._metadata is None and not self.object_id is None: - metadata = DSMetadata(dbus_helpers.get_properties(self.object_id)) + metadata = DSMetadata(get_properties(self.object_id)) self._metadata = metadata return self._metadata @@ -137,8 +143,8 @@ class DSObject(object): return DSObject(None, self._metadata.copy(), self._file_path) def get(object_id): - logging.debug('datastore.get') - metadata = dbus_helpers.get_properties(object_id) + logging.debug('datastore.get %r', object_id) + metadata = get_properties(object_id) ds_object = DSObject(object_id, DSMetadata(metadata), None) # TODO: register the object for updates @@ -186,9 +192,13 @@ def write(ds_object, update_mtime=True, transfer_ownership=False, logging.debug('Written object %s to the datastore.' % ds_object.object_id) def delete(object_id): - logging.debug('datastore.delete') + logging.debug('datastore.delete %r', object_id) dbus_helpers.delete(object_id) +def get_properties(object_id): + logging.debug('dbus_helpers.get_properties: %r', object_id) + return dbus_helpers.get_properties(object_id) + def find(query, sorting=None, limit=None, offset=None, properties=None, reply_handler=None, error_handler=None): @@ -203,19 +213,27 @@ def find(query, sorting=None, limit=None, offset=None, properties=None, query['limit'] = limit if offset: query['offset'] = offset - - props_list, total_count = dbus_helpers.find(query, properties, - reply_handler, error_handler) - + + if reply_handler and error_handler: + f_reply_handler = (lambda entries, total_count: + reply_handler(_metadata_to_dsobjects(entries), total_count)) + + return dbus_helpers.find(query, properties, f_reply_handler, + error_handler) + + entries, total_count = dbus_helpers.find(query, properties) + return _metadata_to_dsobjects(entries), total_count + +def _metadata_to_dsobjects(entries) : objects = [] - for props in props_list: - object_id = props['uid'] - del props['uid'] + for properties in entries: + object_id = properties['uid'] + del properties['uid'] - ds_object = DSObject(object_id, DSMetadata(props), None) + ds_object = DSObject(object_id, DSMetadata(properties)) objects.append(ds_object) - return objects, total_count + return objects def copy(jobject, mount_point): @@ -252,3 +270,54 @@ def complete_indexing(): def get_unique_values(key): return dbus_helpers.get_unique_values(key) + + +class DatastoreListener(object): + + _sig_names = ['created', 'updated', 'deleted', 'stopped'] + + def __init__(self): + # pylint: disable-msg=W0212 + self._datastore = dbus_helpers._get_data_store() + self._signal_handlers = [ + self._datastore.connect_to_signal( + sig_name[0].upper() + sig_name[1:], + getattr(self, "_datastore_%s_cb" % (sig_name, ))) + for sig_name in self._sig_names] + for sig_name in self._sig_names: + setattr(self, sig_name, dispatch.Signal()) + + def __del__(self): + try : + for handler in self._signal_handlers: + handler.remove() + # pylint: disable-msg=W0704 + except Exception: + # Ignore errors during garbage collection - the signal handlers + # might have already been collected. + pass + + def _datastore_created_cb(self, object_id): + metadata = get_properties(object_id) + self.created.send(self, metadata=metadata) + + def _datastore_updated_cb(self, object_id): + metadata = get_properties(object_id) + self.updated.send(self, metadata=metadata) + + def _datastore_deleted_cb(self, object_id): + self.deleted.send(self, object_id=object_id) + + def _datastore_stopped_cb(self): + self.stopped.send(self) + + +_DATASTORE_LISTENER = None +def get_datastore_listener() : + global _DATASTORE_LISTENER + + if not _DATASTORE_LISTENER : + _DATASTORE_LISTENER = DatastoreListener() + + return _DATASTORE_LISTENER + diff --git a/src/sugar/datastore/dbus_helpers.py b/src/sugar/datastore/dbus_helpers.py index 9115382..e9e0dda 100644 --- a/src/sugar/datastore/dbus_helpers.py +++ b/src/sugar/datastore/dbus_helpers.py @@ -31,6 +31,7 @@ DS_DBUS_PATH = "/org/laptop/sugar/DataStore" _data_store = None +# also used by sugar.datastore.datastore def _get_data_store(): global _data_store @@ -77,7 +78,7 @@ def get_filename(uid): logging.debug('dbus_helpers.get_filename: %s, %s' % (uid, filename)) return filename -def find(query, properties, reply_handler, error_handler): +def find(query, properties, reply_handler=None, error_handler=None): logging.debug('dbus_helpers.find: %r %r' % (query, properties)) if reply_handler and error_handler: return _get_data_store().find(query, properties, -- cgit v0.9.1