Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2012-08-15 17:34:02 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2012-08-15 17:34:02 (GMT)
commita5cdc8bf6be0a6651365366499b6440fa150a79a (patch)
treedd6721a281ba79802f09732825172f022a87d1aa
parente8b7340a50f4aaffe605e475098f6f1c200a3f69 (diff)
Install/uninstall bundles
-rw-r--r--plugin/bundleregistry.py133
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)