diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-08-15 17:34:02 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-08-15 17:34:02 (GMT) |
commit | a5cdc8bf6be0a6651365366499b6440fa150a79a (patch) | |
tree | dd6721a281ba79802f09732825172f022a87d1aa | |
parent | e8b7340a50f4aaffe605e475098f6f1c200a3f69 (diff) |
Install/uninstall bundles
-rw-r--r-- | plugin/bundleregistry.py | 133 |
1 files changed, 99 insertions, 34 deletions
diff --git a/plugin/bundleregistry.py b/plugin/bundleregistry.py index d20329f..44f8b41 100644 --- a/plugin/bundleregistry.py +++ b/plugin/bundleregistry.py @@ -14,6 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os +import shutil import logging from os.path import lexists from gettext import gettext as _ @@ -23,8 +24,12 @@ import gobject from sugar_network import checkins, sugar from sugar.bundle.activitybundle import ActivityBundle - +from sugar.bundle.contentbundle import ContentBundle +from sugar.bundle.bundleversion import NormalizedVersion +from sugar.bundle.bundle import AlreadyInstalledException +from jarabe.model import mimeregistry from jarabe.plugins.sn import SN_BROWSER_NAME, get_client +from jarabe.journal.journalentrybundle import JournalEntryBundle _logger = logging.getLogger('plugins.sn.bundleregistry') @@ -80,12 +85,23 @@ class BundleRegistry(gobject.GObject): return result def get_activities_for_type(self, mime_type): - # TODO - return [] + result = [] - def is_installed(self, bundle): - return hasattr(bundle, 'get_bundle_id') and \ - bundle.get_bundle_id() in self._bundles + mime = mimeregistry.get_registry() + default_bundle_id = mime.get_default_activity(mime_type) + default_bundle = None + + for bundle in self._bundles.values(): + if mime_type in (bundle.get_mime_types() or []): + if bundle.get_bundle_id() == default_bundle_id: + default_bundle = bundle + else: + result.append(bundle) + + if default_bundle is not None: + result.insert(0, default_bundle) + + return result def is_bundle_favorite(self, bundle_id, version): bundle = self._bundles.get(bundle_id) @@ -115,22 +131,50 @@ class BundleRegistry(gobject.GObject): get_client().Update('~', 'context', bundle_id, {'position': position}) self.emit('bundle-changed', bundle) - def get_default_for_type(self, mime_type): - # TODO - pass - def is_activity_protected(self, bundle_id): - # TODO + # No need, is_user_activity() is enough return False + def is_installed(self, bundle): + if isinstance(bundle, ContentBundle) or \ + isinstance(bundle, JournalEntryBundle): + return bundle.is_installed() + + installed = self._bundles.get(bundle.get_bundle_id()) + return installed is not None and \ + NormalizedVersion(bundle.get_activity_version()) == \ + NormalizedVersion(installed.get_activity_version()) + def install(self, bundle, uid=None, force_downgrade=False): - raise NotImplementedError('Not yet supported') + if isinstance(bundle, JournalEntryBundle): + bundle.install(uid) + return + elif isinstance(bundle, ContentBundle): + bundle.install() + return + + installed = self._bundles.get(bundle.get_bundle_id()) + if installed is not None: + if not force_downgrade and \ + NormalizedVersion(bundle.get_activity_version()) <= \ + NormalizedVersion(installed.get_activity_version()): + raise AlreadyInstalledException + installed.uninstall() + + bundle.install() def uninstall(self, bundle, force=False, delete_profile=False): - raise NotImplementedError('Not yet supported') + if isinstance(bundle, ContentBundle) or \ + isinstance(bundle, JournalEntryBundle): + if bundle.is_installed(): + bundle.uninstall() + else: + bundle = self._bundles.get(bundle.get_bundle_id()) + if bundle is not None: + bundle.uninstall() def upgrade(self, bundle): - raise NotImplementedError('Not yet supported') + self.install(bundle) def _populate(self): @@ -138,9 +182,7 @@ class BundleRegistry(gobject.GObject): for props in entries: if props['guid'] in self._bundles: continue - bundle = self._add_bundle(props['guid'], props) - if bundle is not None: - self.emit('bundle-added', bundle) + self._add_bundle(props['guid'], props) def error_handler(error): _logger.warning('Cannot call Find(): %s', error) @@ -151,18 +193,32 @@ class BundleRegistry(gobject.GObject): {'keep_impl': 2, 'limit': 1024}, reply_handler=reply_handler, error_handler=error_handler) - def _add_bundle(self, bundle_id, props): + def _add_bundle(self, bundle_id, props=None): + bundle = None for path in checkins(bundle_id): try: - bundle = self._bundles[bundle_id] = \ - _BundleInfo(ActivityBundle(path), props) - _logger.info('Add %r bundle', bundle_id) - return bundle + bundle = _BundleInfo(ActivityBundle(path)) + break except Exception: _logger.exception('Cannot load %r bundle from %r', bundle_id, path) - else: + + if bundle is None: _logger.info('No bundles for %r', bundle_id) + return None + + if props: + bundle.props = props + self._bundles[bundle.get_bundle_id()] = bundle + _logger.info('Add %r bundle', bundle.get_bundle_id()) + self.emit('bundle-added', bundle) + + def _remove_bundle(self, bundle_id): + if bundle_id not in self._bundles: + return + _logger.info('Remove %r bundle', bundle_id) + bundle = self._bundles.pop(bundle_id) + self.emit('bundle-removed', bundle) def _set_keep(self, bundle_id, keep): bundle = self._bundles.get(bundle_id) @@ -175,15 +231,14 @@ class BundleRegistry(gobject.GObject): if keep_impl: bundle = self._bundles.get(bundle_id) if bundle is None: - props = get_client().Get('~', 'context', bundle_id, - ['guid', 'keep', 'keep_impl', 'position']) - bundle = self._add_bundle(bundle_id, props) + bundle = self._add_bundle(bundle_id) + else: + self.emit('bundle-changed', bundle) if bundle is not None: - self.emit('bundle-added', bundle) + bundle.props = get_client().Get('~', 'context', bundle_id, + ['guid', 'keep', 'keep_impl', 'position']) else: - if bundle_id in self._bundles: - bundle = self._bundles.pop(bundle_id) - self.emit('bundle-removed', bundle) + self._remove_bundle(bundle_id) def __Event_cb(self, event): if 'mountpoint' in event and event['mountpoint'] != '~' or \ @@ -249,20 +304,30 @@ class _ContextInfo(object): return '' def is_user_activity(self): - # Doesn't matter with Sweets' features enabled - return False + return True def get_path(self): return '/' + def get_mime_types(self): + return [] + class _BundleInfo(object): - def __init__(self, bundle, props): - self.props = props + def __init__(self, bundle): + self.props = { + 'guid': bundle.get_bundle_id, + 'keep': False, + 'position': (-1, -1), + } self.mountpoint = '~' self._bundle = bundle + def uninstall(self): + _logger.debug('Uninstall %r', self._bundle.get_bundle_id()) + shutil.rmtree(self._bundle.get_path(), ignore_errors=True) + def __getattr__(self, name): return getattr(self._bundle, name) |