Ticket #1198: 0001-use-sugar.datastore.-instead-of-direct-DBus-access.patch

File 0001-use-sugar.datastore.-instead-of-direct-DBus-access.patch, 21.2 KB (added by sascha_silbe, 12 years ago)

use sugar.datastore.* instead of direct DBus access (updated)

  • src/jarabe/desktop/favoritesview.py

    From 88dbdd61c9905ac2226bdd9bd06dfe4b8b6db767 Mon Sep 17 00:00:00 2001
    From: Sascha Silbe <sascha@silbe.org>
    Date: Wed, 19 Aug 2009 22:28:19 +0200
    Subject: [PATCH] use sugar.datastore.* instead of direct DBus access
    
    ---
     src/jarabe/desktop/favoritesview.py   |   87 +++++++++++---------------------
     src/jarabe/frame/activitiestray.py    |   74 ++++++++++------------------
     src/jarabe/journal/journalactivity.py |   28 +++++------
     src/jarabe/journal/listview.py        |   16 ++----
     src/jarabe/journal/model.py           |   66 ++++++-------------------
     5 files changed, 91 insertions(+), 180 deletions(-)
    
    diff --git a/src/jarabe/desktop/favoritesview.py b/src/jarabe/desktop/favoritesview.py
    index 6ca8732..ead7b0e 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): 
    9192
    9293        self._layout = None
    9394        self._alert = None
    94         self._datastore_listener = DatastoreListener()
     95        self._datastore_listener = datastore.get_datastore_listener()
    9596
    9697        # More DND stuff
    9798        self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
    class FavoritesView(hippo.Canvas): 
    335336    def __register_alert_response_cb(self, alert, response_id):
    336337        self.remove_alert()
    337338
    338 DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
    339 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
    340 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
    341 
    342 class DatastoreListener(object):
    343     def __init__(self):
    344         bus = dbus.SessionBus()
    345         remote_object = bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH)
    346         self._datastore = dbus.Interface(remote_object, DS_DBUS_INTERFACE)
    347         self._datastore.connect_to_signal('Created',
    348                                           self.__datastore_created_cb)
    349         self._datastore.connect_to_signal('Updated',
    350                                           self.__datastore_updated_cb)
    351         self._datastore.connect_to_signal('Deleted',
    352                                           self.__datastore_deleted_cb)
    353 
    354         self.updated = dispatch.Signal()
    355         self.deleted = dispatch.Signal()
    356 
    357     def __datastore_created_cb(self, object_id):
    358         metadata = self._datastore.get_properties(object_id, byte_arrays=True)
    359         self.updated.send(self, metadata=metadata)
    360 
    361     def __datastore_updated_cb(self, object_id):
    362         metadata = self._datastore.get_properties(object_id, byte_arrays=True)
    363         self.updated.send(self, metadata=metadata)
    364 
    365     def __datastore_deleted_cb(self, object_id):
    366         self.deleted.send(self, object_id=object_id)
    367 
    368     def get_last_activity_async(self, bundle_id, properties, callback_cb):
    369         query = {'activity': bundle_id,
    370                  'limit': 5,
    371                  'order_by': ['+timestamp']}
    372 
    373         reply_handler = lambda entries, total_count: self.__reply_handler_cb(
    374                 entries, total_count, callback_cb)
    375 
    376         error_handler = lambda error: self.__error_handler_cb(
    377                 error, callback_cb)
    378 
    379         self._datastore.find(query, properties, byte_arrays=True,
    380                              reply_handler=reply_handler,
    381                              error_handler=error_handler)
    382 
    383     def __reply_handler_cb(self, entries, total_count, callback_cb):
    384         logging.debug('__reply_handler_cb')
    385         callback_cb(entries)
    386 
    387     def __error_handler_cb(self, error, callback_cb):
    388         logging.debug('__error_handler_cb')
    389         callback_cb(None, error)
    390339
    391340class ActivityIcon(CanvasIcon):
    392341    __gtype_name__ = 'SugarFavoriteActivityIcon'
    class ActivityIcon(CanvasIcon): 
    404353        self.connect('hovering-changed', self.__hovering_changed_event_cb)
    405354        self.connect('button-release-event', self.__button_release_event_cb)
    406355
    407         self._datastore_listener = datastore_listener
     356        datastore_listener.created.connect(self.__datastore_listener_updated_cb)
    408357        datastore_listener.updated.connect(self.__datastore_listener_updated_cb)
    409358        datastore_listener.deleted.connect(self.__datastore_listener_deleted_cb)
    410359
    class ActivityIcon(CanvasIcon): 
    415364        bundle_id = self._activity_info.get_bundle_id()
    416365        properties = ['uid', 'title', 'icon-color', 'activity', 'activity_id',
    417366                      'mime_type', 'mountpoint']
    418         self._datastore_listener.get_last_activity_async(bundle_id, properties,
     367        self._get_last_activity_async(bundle_id, properties,
    419368                self.__get_last_activity_async_cb)
    420369
    421370    def __datastore_listener_updated_cb(self, **kwargs):
    class ActivityIcon(CanvasIcon): 
    438387        # to this activity.
    439388        checked_entries = []
    440389        for entry in entries:
    441             if entry['activity'] == self.bundle_id:
    442                 checked_entries.append(entry)
     390            metadata = entry.metadata.copy()
     391            entry.destroy()
     392            if metadata['activity'] == self.bundle_id:
     393                checked_entries.append(metadata)
    443394
    444395        self._journal_entries = checked_entries
    445396        self._update()
    class ActivityIcon(CanvasIcon): 
    548499        return registry.get_bundle_position(self.bundle_id, self.version)
    549500    fixed_position = property(_get_fixed_position, None)
    550501
     502    def _get_last_activity_async(self, bundle_id, properties, callback_cb):
     503        query = {'activity': bundle_id}
     504
     505        reply_handler = lambda entries, total_count: self.__reply_handler_cb(
     506                entries, total_count, callback_cb)
     507
     508        error_handler = lambda error: self.__error_handler_cb(
     509                error, callback_cb)
     510
     511        datastore.find(query, sorting='-mtime', limit=5, properties=properties,
     512                               reply_handler=reply_handler,
     513                               error_handler=error_handler)
     514
     515    def __reply_handler_cb(self, entries, total_count, callback_cb):
     516        logging.debug('__reply_handler_cb')
     517        callback_cb(entries)
     518
     519    def __error_handler_cb(self, error, callback_cb):
     520        logging.debug('__error_handler_cb')
     521        callback_cb(None, error)
     522
     523
    551524class FavoritePalette(ActivityPalette):
    552525    __gtype_name__ = 'SugarFavoritePalette'
    553526
  • src/jarabe/frame/activitiestray.py

    diff --git a/src/jarabe/frame/activitiestray.py b/src/jarabe/frame/activitiestray.py
    index 0025403..b88782d 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')
    531             self._metadata['progress'] = '100'
     526            self._jobject.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                self._jobject.destroy()
     539                datastore.delete(object_id)
    548540
    549541    def __notify_transferred_bytes_cb(self, file_transfer, pspec):
    550542        progress = file_transfer.props.transferred_bytes /      \
    551543                   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)
     544        self._jobject.metadata['progress'] = str(progress * 100)
     545        datastore.write(self._jobject, update_mtime=False)
    566546
    567547    def __reply_handler_cb(self):
    568         logging.debug('__reply_handler_cb %r' % self._object_id)
     548        logging.debug('__reply_handler_cb %r' % self._jobject.object_id)
    569549
    570550    def __error_handler_cb(self, error):
    571         logging.debug('__error_handler_cb %r %s' % (self._object_id, error))
     551        logging.debug('__error_handler_cb %r %s' % (self._jobject.object_id, error))
    572552
    573553    def __dismiss_clicked_cb(self, palette):
    574554        self.remove()
  • 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 332edc9..7842de8 100644
    a b from sugar.graphics import style 
    2828from sugar.graphics.icon import CanvasIcon, Icon, CellRendererIcon
    2929from sugar.graphics.xocolor import XoColor
    3030from sugar import util
     31from sugar.datastore import datastore
    3132
    3233from jarabe.journal.listmodel import ListModel
    3334from jarabe.journal.palettes import ObjectPalette, BuddyPalette
    class BaseListView(gtk.Bin): 
    105106        self._refresh_idle_handler = None
    106107        self._update_dates_timer = None
    107108
    108         model.created.connect(self.__model_created_cb)
    109         model.updated.connect(self.__model_updated_cb)
    110         model.deleted.connect(self.__model_deleted_cb)
     109        datastore_listener = datastore.get_datastore_listener()
     110        datastore_listener.created.connect(self.__datastore_changed_cb),
     111        datastore_listener.updated.connect(self.__datastore_changed_cb),
     112        datastore_listener.deleted.connect(self.__datastore_changed_cb),
    111113
    112     def __model_created_cb(self, sender, **kwargs):
    113         self._set_dirty()
    114 
    115     def __model_updated_cb(self, sender, **kwargs):
    116         self._set_dirty()
    117 
    118     def __model_deleted_cb(self, sender, **kwargs):
     114    def __datastore_changed_cb(self, *args, **kwargs):
    119115        self._set_dirty()
    120116
    121117    def _add_columns(self):
  • src/jarabe/journal/model.py

    diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
    index e710464..aa29a07 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_filename(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