Ticket #1198: sugar-0001-use-sugar.datastore.datastore-or-at-least-sugar.data.patch

File sugar-0001-use-sugar.datastore.datastore-or-at-least-sugar.data.patch, 21.0 KB (added by sascha_silbe, 15 years ago)

use sugar.datastore.* instead of direct DBus access

  • src/jarabe/desktop/favoritesview.py

    From 2dab833c1af76762ed33cc10348d84c90e7788d5 Mon Sep 17 00:00:00 2001
    From: Sascha Silbe <sascha@silbe.org>
    Date: Tue, 18 Aug 2009 01:42:13 +0200
    Subject: [PATCH] use sugar.datastore.datastore or at least sugar.datastore.dbus_helpers instead of direct DBus calls
    
    ---
     src/jarabe/desktop/favoritesview.py   |   87 +++++++++++---------------------
     src/jarabe/frame/activitiestray.py    |   70 ++++++++++-----------------
     src/jarabe/journal/journalactivity.py |   28 +++++------
     src/jarabe/journal/listview.py        |   16 ++----
     src/jarabe/journal/model.py           |   66 ++++++-------------------
     5 files changed, 90 insertions(+), 177 deletions(-)
    
    diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py
    index 4037fae..46dc498 100644
    a b from sugar.graphics.xocolor import XoColor 
    3333from sugar.activity import activityfactory
    3434from sugar.activity.activityhandle import ActivityHandle
    3535from sugar.presence import presenceservice
     36from sugar.datastore import datastore
    3637from sugar import dispatch
    3738
    3839from jarabe.view.palettes import JournalPalette
    class FavoritesView(hippo.Canvas): 
    9697
    9798        self._layout = None
    9899        self._alert = None
    99         self._datastore_listener = DatastoreListener()
     100        self._datastore_listener = datastore.get_datastore_listener()
    100101
    101102        # More DND stuff
    102103        self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
    class FavoritesView(hippo.Canvas): 
    344345    def __register_alert_response_cb(self, alert, response_id):
    345346        self.remove_alert()
    346347
    347 DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
    348 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
    349 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
    350 
    351 class DatastoreListener(object):
    352     def __init__(self):
    353         bus = dbus.SessionBus()
    354         remote_object = bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH)
    355         self._datastore = dbus.Interface(remote_object, DS_DBUS_INTERFACE)
    356         self._datastore.connect_to_signal('Created',
    357                                           self.__datastore_created_cb)
    358         self._datastore.connect_to_signal('Updated',
    359                                           self.__datastore_updated_cb)
    360         self._datastore.connect_to_signal('Deleted',
    361                                           self.__datastore_deleted_cb)
    362 
    363         self.updated = dispatch.Signal()
    364         self.deleted = dispatch.Signal()
    365 
    366     def __datastore_created_cb(self, object_id):
    367         metadata = self._datastore.get_properties(object_id, byte_arrays=True)
    368         self.updated.send(self, metadata=metadata)
    369 
    370     def __datastore_updated_cb(self, object_id):
    371         metadata = self._datastore.get_properties(object_id, byte_arrays=True)
    372         self.updated.send(self, metadata=metadata)
    373 
    374     def __datastore_deleted_cb(self, object_id):
    375         self.deleted.send(self, object_id=object_id)
    376 
    377     def get_last_activity_async(self, bundle_id, properties, callback_cb):
    378         query = {'activity': bundle_id,
    379                  'limit': 5,
    380                  'order_by': ['+timestamp']}
    381 
    382         reply_handler = lambda entries, total_count: self.__reply_handler_cb(
    383                 entries, total_count, callback_cb)
    384 
    385         error_handler = lambda error: self.__error_handler_cb(
    386                 error, callback_cb)
    387 
    388         self._datastore.find(query, properties, byte_arrays=True,
    389                              reply_handler=reply_handler,
    390                              error_handler=error_handler)
    391 
    392     def __reply_handler_cb(self, entries, total_count, callback_cb):
    393         logging.debug('__reply_handler_cb')
    394         callback_cb(entries)
    395 
    396     def __error_handler_cb(self, error, callback_cb):
    397         logging.debug('__error_handler_cb')
    398         callback_cb(None, error)
    399348
    400349class ActivityIcon(CanvasIcon):
    401350    __gtype_name__ = 'SugarFavoriteActivityIcon'
    class ActivityIcon(CanvasIcon): 
    418367        self.connect('hovering-changed', self.__hovering_changed_event_cb)
    419368        self.connect('button-release-event', self.__button_release_event_cb)
    420369
    421         self._datastore_listener = datastore_listener
     370        datastore_listener.created.connect(self.__datastore_listener_updated_cb)
    422371        datastore_listener.updated.connect(self.__datastore_listener_updated_cb)
    423372        datastore_listener.deleted.connect(self.__datastore_listener_deleted_cb)
    424373
    class ActivityIcon(CanvasIcon): 
    429378        bundle_id = self._activity_info.get_bundle_id()
    430379        properties = ['uid', 'title', 'icon-color', 'activity', 'activity_id',
    431380                      'mime_type', 'mountpoint']
    432         self._datastore_listener.get_last_activity_async(bundle_id, properties,
     381        self._get_last_activity_async(bundle_id, properties,
    433382                self.__get_last_activity_async_cb)
    434383
    435384    def __datastore_listener_updated_cb(self, **kwargs):
    class ActivityIcon(CanvasIcon): 
    452401        # to this activity.
    453402        checked_entries = []
    454403        for entry in entries:
    455             if entry['activity'] == self.bundle_id:
    456                 checked_entries.append(entry)
     404            metadata = entry.metadata.copy()
     405            entry.destroy()
     406            if metadata['activity'] == self.bundle_id:
     407                checked_entries.append(metadata)
    457408
    458409        self._journal_entries = checked_entries
    459410        self._update()
    class ActivityIcon(CanvasIcon): 
    566517        return registry.get_bundle_position(self.bundle_id, self.version)
    567518    fixed_position = property(_get_fixed_position, None)
    568519
     520    def _get_last_activity_async(self, bundle_id, properties, callback_cb):
     521        query = {'activity': bundle_id}
     522
     523        reply_handler = lambda entries, total_count: self.__reply_handler_cb(
     524                entries, total_count, callback_cb)
     525
     526        error_handler = lambda error: self.__error_handler_cb(
     527                error, callback_cb)
     528
     529        datastore.find(query, sorting='-mtime', limit=5, properties=properties,
     530                               reply_handler=reply_handler,
     531                               error_handler=error_handler)
     532
     533    def __reply_handler_cb(self, entries, total_count, callback_cb):
     534        logging.debug('__reply_handler_cb')
     535        callback_cb(entries)
     536
     537    def __error_handler_cb(self, error, callback_cb):
     538        logging.debug('__error_handler_cb')
     539        callback_cb(None, error)
     540
     541
    569542class FavoritePalette(ActivityPalette):
    570543    __gtype_name__ = 'SugarFavoritePalette'
    571544
  • src/jarabe/frame/activitiestray.py

    diff --git a/src/jarabe/frame/activitiestray.py b/src/jarabe/frame/activitiestray.py
    index 0025403..9f4f45a 100644
    a b from sugar.graphics.menuitem import MenuItem 
    3737from sugar.activity.activityhandle import ActivityHandle
    3838from sugar.activity import activityfactory
    3939from sugar import mime
     40from sugar.datastore import datastore
    4041
    4142from jarabe.model import shell
    4243from jarabe.model import neighborhood
    from jarabe.frame.frameinvoker import FrameWidgetInvoker 
    5051from jarabe.frame.notification import NotificationIcon
    5152import jarabe.frame
    5253
    53 DS_DBUS_SERVICE = "org.laptop.sugar.DataStore"
    54 DS_DBUS_INTERFACE = "org.laptop.sugar.DataStore"
    55 DS_DBUS_PATH = "/org/laptop/sugar/DataStore"
    5654
    5755class ActivityButton(RadioToolButton):
    5856    def __init__(self, home_activity, group):
    class IncomingTransferButton(BaseTransferButton): 
    476474    def __init__(self, file_transfer):
    477475        BaseTransferButton.__init__(self, file_transfer)
    478476
    479         self._object_id = None
    480         self._metadata = {}
     477        self._jobject = datastore.create()
    481478
    482479        file_transfer.connect('notify::state', self.__notify_state_cb)
    483480        file_transfer.connect('notify::transferred-bytes',
    class IncomingTransferButton(BaseTransferButton): 
    511508    def __notify_state_cb(self, file_transfer, pspec):
    512509        if file_transfer.props.state == filetransfer.FT_STATE_OPEN:
    513510            logging.debug('__notify_state_cb OPEN')
    514             self._metadata['title'] = file_transfer.title
    515             self._metadata['description'] = file_transfer.description
    516             self._metadata['progress'] = '0'
    517             self._metadata['keep'] = '0'
    518             self._metadata['buddies'] = ''
    519             self._metadata['preview'] = ''
    520             self._metadata['icon-color'] = file_transfer.buddy.props.color
    521             self._metadata['mime_type'] = file_transfer.mime_type
    522 
    523             datastore = self._get_datastore()
    524             file_path = ''
    525             transfer_ownership = True
    526             self._object_id = datastore.create(self._metadata, file_path,
    527                                                transfer_ownership)
     511            self._jobject.metadata.update({
     512                'title': file_transfer.title,
     513                'description': file_transfer.description,
     514                'progress': '0',
     515                'keep': '0',
     516                'buddies': '',
     517                'preview': '',
     518                'icon-color': file_transfer.buddy.props.color,
     519                'mime_type': file_transfer.mime_type,
     520            })
     521
     522            # not writing yet as we don't have any data
    528523
    529524        elif file_transfer.props.state == filetransfer.FT_STATE_COMPLETED:
    530525            logging.debug('__notify_state_cb COMPLETED')
    531526            self._metadata['progress'] = '100'
    532527
    533             datastore = self._get_datastore()
    534             file_path = file_transfer.destination_path
     528            self._jobject.file_path = file_transfer.destination_path
    535529            transfer_ownership = True
    536             datastore.update(self._object_id, self._metadata, file_path,
    537                              transfer_ownership,
    538                              reply_handler=self.__reply_handler_cb,
    539                              error_handler=self.__error_handler_cb)
     530            datastore.write(self._jobject, True,
     531                reply_handler=self.__reply_handler_cb,
     532                error_handler=self.__error_handler_cb)
    540533
    541534        elif file_transfer.props.state == filetransfer.FT_STATE_CANCELLED:
    542535            logging.debug('__notify_state_cb CANCELLED')
    543             if self._object_id is not None:
    544                 datastore.delete(self._object_id,
    545                                  reply_handler=self.__reply_handler_cb,
    546                                  error_handler=self.__error_handler_cb)
    547                 self._object_id = None
     536            object_id = self._jobject.object_id
     537            if object_id is not None:
     538                datastore.delete(object_id,
     539                    reply_handler=self.__reply_handler_cb,
     540                    error_handler=self.__error_handler_cb)
     541                self._jobject.destroy()
    548542
    549543    def __notify_transferred_bytes_cb(self, file_transfer, pspec):
    550544        progress = file_transfer.props.transferred_bytes /      \
    551545                   file_transfer.file_size
    552         self._metadata['progress'] = str(progress * 100)
    553 
    554         datastore = self._get_datastore()
    555         file_path = ''
    556         transfer_ownership = True
    557         datastore.update(self._object_id, self._metadata, file_path,
    558                          transfer_ownership,
    559                          reply_handler=self.__reply_handler_cb,
    560                          error_handler=self.__error_handler_cb)
    561 
    562     def _get_datastore(self):
    563         bus = dbus.SessionBus()
    564         remote_object = bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH)
    565         return dbus.Interface(remote_object, DS_DBUS_INTERFACE)
     546        self._jobject.metadata['progress'] = str(progress * 100)
     547        datastore.write_metadata(self._jobject)
    566548
    567549    def __reply_handler_cb(self):
    568550        logging.debug('__reply_handler_cb %r' % self._object_id)
  • src/jarabe/journal/journalactivity.py

    diff --git a/src/jarabe/journal/journalactivity.py b/src/jarabe/journal/journalactivity.py
    index 80204a1..f8f3847 100644
    a b from sugar.bundle.bundle import ZipExtractException, RegistrationException 
    3131from sugar import env
    3232from sugar.activity import activityfactory
    3333from sugar import wm
     34from sugar.datastore import datastore
    3435
    3536from jarabe.model import bundleregistry
    3637from jarabe.journal.journaltoolbox import MainToolbox, DetailToolbox
    class JournalActivity(Window): 
    127128        self.connect('key-press-event', self._key_press_event_cb)
    128129        self.connect('focus-in-event', self._focus_in_event_cb)
    129130
    130         model.created.connect(self.__model_created_cb)
    131         model.updated.connect(self.__model_updated_cb)
    132         model.deleted.connect(self.__model_deleted_cb)
     131        datastore.get_datastore_listener().created.connect(self.__datastore_changed_cb)
     132        datastore.get_datastore_listener().updated.connect(self.__datastore_changed_cb)
     133        datastore.get_datastore_listener().deleted.connect(self.__datastore_deleted_cb)
    133134
    134135        self._dbus_service = JournalActivityDBusService(self)       
    135136
    class JournalActivity(Window): 
    240241        self._main_toolbox.search_toolbar.set_mount_point(mount_point)
    241242        self._main_toolbox.set_current_toolbar(0)
    242243
    243     def __model_created_cb(self, sender, **kwargs):
    244         self._check_for_bundle(kwargs['object_id'])
     244    def __datastore_changed_cb(self, metadata, **kwargs):
     245        self._check_for_bundle(metadata['uid'])
    245246        self._main_toolbox.search_toolbar.refresh_filters()
     247        self._check_update_secondary(metadata['uid'])
    246248        self._check_available_space()
    247249
    248     def __model_updated_cb(self, sender, **kwargs):
    249         self._check_for_bundle(kwargs['object_id'])
     250    def __datastore_deleted_cb(self, object_id, **kwargs):
     251        self._check_update_secondary(object_id)
    250252
    251         if self.canvas == self._secondary_view and \
    252                 kwargs['object_id'] == self._detail_view.props.metadata['uid']:
     253    def _check_update_secondary(self, object_id):
     254        if (self.canvas == self._secondary_view) and \
     255                object_id == self._detail_view.props.metadata['uid']:
    253256            self._detail_view.refresh()
    254257
    255         self._check_available_space()
    256 
    257     def __model_deleted_cb(self, sender, **kwargs):
    258         if self.canvas == self._secondary_view and \
    259                 kwargs['object_id'] == self._detail_view.props.metadata['uid']:
    260             self.show_main_view()
    261 
    262258    def _focus_in_event_cb(self, window, event):
    263259        self.search_grab_focus()
    264260        self._list_view.update_dates()
  • src/jarabe/journal/listview.py

    diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
    index 5e20577..ef73edb 100644
    a b from sugar.graphics import style 
    3030from sugar.graphics.icon import CanvasIcon, Icon, CellRendererIcon
    3131from sugar.graphics.xocolor import XoColor
    3232from sugar import util
     33from sugar.datastore import datastore
    3334
    3435from jarabe.journal.listmodel import ListModel
    3536from jarabe.journal.palettes import ObjectPalette, BuddyPalette
    class BaseListView(gtk.Bin): 
    106107        self._refresh_idle_handler = None
    107108        self._update_dates_timer = None
    108109
    109         model.created.connect(self.__model_created_cb)
    110         model.updated.connect(self.__model_updated_cb)
    111         model.deleted.connect(self.__model_deleted_cb)
     110        datastore_listener = datastore.get_datastore_listener()
     111        datastore_listener.created.connect(self.__datastore_changed_cb),
     112        datastore_listener.updated.connect(self.__datastore_changed_cb),
     113        datastore_listener.deleted.connect(self.__datastore_changed_cb),
    112114
    113     def __model_created_cb(self, sender, **kwargs):
    114         self._set_dirty()
    115 
    116     def __model_updated_cb(self, sender, **kwargs):
    117         self._set_dirty()
    118 
    119     def __model_deleted_cb(self, sender, **kwargs):
     115    def __datastore_changed_cb(self, *args, **kwargs):
    120116        self._set_dirty()
    121117
    122118    def _add_columns(self):
  • src/jarabe/journal/model.py

    diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
    index 7517d78..349530d 100644
    a b import traceback 
    2424import re
    2525
    2626import gobject
    27 import dbus
    2827import gconf
    2928import gio
    3029
    3130from sugar import dispatch
    3231from sugar import mime
    3332from sugar import util
     33from sugar.datastore import datastore
     34from sugar.datastore import dbus_helpers
    3435
    35 DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
    36 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
    37 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
    3836
    3937# Properties the journal cares about.
    4038PROPERTIES = ['uid', 'title', 'mtime', 'timestamp', 'keep', 'buddies',
    class DatastoreResultSet(BaseResultSet): 
    219217        BaseResultSet.__init__(self, query, page_size)
    220218
    221219    def find(self, query):
    222         entries, total_count = _get_datastore().find(query, PROPERTIES,
    223                                                      byte_arrays=True)
     220        entries, total_count = dbus_helpers.find(query, PROPERTIES)
    224221
    225222        for entry in entries:
    226223            entry['mountpoint'] = '/'
    def _get_file_metadata(path, stat): 
    350347            'icon-color': client.get_string('/desktop/sugar/user/color'),
    351348            'description': path}
    352349
    353 _datastore = None
    354 def _get_datastore():
    355     global _datastore
    356     if _datastore is None:
    357         bus = dbus.SessionBus()
    358         remote_object = bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH)
    359         _datastore = dbus.Interface(remote_object, DS_DBUS_INTERFACE)
    360 
    361         _datastore.connect_to_signal('Created', _datastore_created_cb)
    362         _datastore.connect_to_signal('Updated', _datastore_updated_cb)
    363         _datastore.connect_to_signal('Deleted', _datastore_deleted_cb)
    364 
    365     return _datastore
    366 
    367 def _datastore_created_cb(object_id):
    368     created.send(None, object_id=object_id)
    369 
    370 def _datastore_updated_cb(object_id):
    371     updated.send(None, object_id=object_id)
    372 
    373 def _datastore_deleted_cb(object_id):
    374     deleted.send(None, object_id=object_id)
    375 
    376350def find(query, page_size):
    377351    """Returns a ResultSet
    378352    """
    def get(object_id): 
    404378        metadata = _get_file_metadata(object_id, stat)
    405379        metadata['mountpoint'] = _get_mount_point(object_id)
    406380    else:
    407         metadata = _get_datastore().get_properties(object_id, byte_arrays=True)
     381        metadata = datastore.get_properties(object_id)
    408382        metadata['mountpoint'] = '/'
    409383    return metadata
    410384
    def get_file(object_id): 
    415389        logging.debug('get_file asked for file with path %r' % object_id)
    416390        return object_id
    417391    else:
    418         logging.debug('get_file asked for entry with id %r' % object_id)
    419         file_path = _get_datastore().get_filename(object_id)
     392        logging.debug('get_file asked for entry with id %r', object_id)
     393        file_path = dbus_helpers.get_data(object_id)
    420394        if file_path:
    421395            return util.TempFilePath(file_path)
    422396        else:
    def get_file(object_id): 
    425399def get_unique_values(key):
    426400    """Returns a list with the different values a property has taken
    427401    """
    428     empty_dict = dbus.Dictionary({}, signature='ss')
    429     return _get_datastore().get_uniquevaluesfor(key, empty_dict)
     402    return datastore.get_unique_values(key)
    430403
    431404def delete(object_id):
    432405    """Removes an object from persistent storage
    def delete(object_id): 
    434407    if os.path.exists(object_id):
    435408        os.unlink(object_id)
    436409    else:
    437         _get_datastore().delete(object_id)
     410        datastore.delete(object_id)
    438411
    439412def copy(metadata, mount_point):
    440413    """Copies an object to another mount point
    def copy(metadata, mount_point): 
    450423def write(metadata, file_path='', update_mtime=True):
    451424    """Creates or updates an entry for that id
    452425    """
    453     logging.debug('model.write %r %r %r' % (metadata.get('uid', ''), file_path,
    454                                             update_mtime))
     426    logging.debug('model.write %r %r %r', metadata.get('uid', ''), file_path,
     427                                            update_mtime)
    455428    if update_mtime:
    456429        metadata['mtime'] = datetime.now().isoformat()
    457430        metadata['timestamp'] = int(time.time())
    458431
    459432    if metadata.get('mountpoint', '/') == '/':
    460         if metadata.get('uid', ''):
    461             object_id = _get_datastore().update(metadata['uid'],
    462                                                  dbus.Dictionary(metadata),
    463                                                  file_path,
    464                                                  True)
    465         else:
    466             object_id = _get_datastore().create(dbus.Dictionary(metadata),
    467                                                  file_path,
    468                                                  True)
     433        jobject = datastore.DSObject(metadata.get('uid'),
     434            datastore.DSMetadata(metadata), file_path)
     435        datastore.write(jobject, transfer_ownership=True)
     436        object_id = jobject.object_id
     437
    469438    else:
     439        # mounted filesystem
    470440        if not os.path.exists(file_path):
    471441            raise ValueError('Entries without a file cannot be copied to '
    472442                             'removable devices')
    def _get_unique_file_name(mount_point, file_name): 
    516486
    517487    return file_name
    518488
    519 created = dispatch.Signal()
    520 updated = dispatch.Signal()
    521 deleted = dispatch.Signal()
    522