Allow activity up- and downgrades #4906, also fix #5382

This commit is contained in:
Reinier Heeres 2007-12-18 13:43:34 +01:00
parent b57ff156f7
commit d35c19b6aa
5 changed files with 54 additions and 7 deletions

View File

@ -29,15 +29,17 @@ def _activity_info_from_dict(info_dict):
if not info_dict: if not info_dict:
return None return None
return ActivityInfo(info_dict['name'], info_dict['icon'], return ActivityInfo(info_dict['name'], info_dict['icon'],
info_dict['bundle_id'], info_dict['path'], info_dict['bundle_id'], info_dict['version'],
info_dict['show_launcher'], info_dict['command']) info_dict['path'], info_dict['show_launcher'],
info_dict['command'])
class ActivityInfo(object): class ActivityInfo(object):
def __init__(self, name, icon, bundle_id, def __init__(self, name, icon, bundle_id, version,
path, show_launcher, command): path, show_launcher, command):
self.name = name self.name = name
self.icon = icon self.icon = icon
self.bundle_id = bundle_id self.bundle_id = bundle_id
self.version = version
self.path = path self.path = path
self.command = command self.command = command
self.show_launcher = show_launcher self.show_launcher = show_launcher
@ -146,6 +148,8 @@ class ActivityRegistry(gobject.GObject):
self._mime_type_to_activities.clear() self._mime_type_to_activities.clear()
def remove_bundle(self, bundle_path): def remove_bundle(self, bundle_path):
self._service_name_to_activity_info.clear()
self._mime_type_to_activities.clear()
return self._registry.RemoveBundle(bundle_path) return self._registry.RemoveBundle(bundle_path)
def _activity_removed_cb(self, info_dict): def _activity_removed_cb(self, info_dict):

View File

@ -22,10 +22,15 @@ import locale
import os import os
import tempfile import tempfile
from sugar.bundle.bundle import Bundle, MalformedBundleException from sugar.bundle.bundle import Bundle, MalformedBundleException, \
AlreadyInstalledException, RegistrationException, \
NotInstalledException
from sugar import activity from sugar import activity
from sugar import env from sugar import env
import logging
class ActivityBundle(Bundle): class ActivityBundle(Bundle):
"""A Sugar activity bundle """A Sugar activity bundle
@ -204,8 +209,16 @@ class ActivityBundle(Bundle):
else: else:
return False return False
def need_upgrade(self):
act = activity.get_registry().get_activity(self._bundle_id)
if act is None or act.version != self._activity_version:
return True
else:
return False
def install(self): def install(self):
if self.is_installed(): act = activity.get_registry().get_activity(self._bundle_id)
if act is not None and act.path.startswith(env.get_user_activities_path()):
raise AlreadyInstalledException raise AlreadyInstalledException
install_dir = env.get_user_activities_path() install_dir = env.get_user_activities_path()
@ -250,12 +263,21 @@ class ActivityBundle(Bundle):
if not activity.get_registry().add_bundle(install_path): if not activity.get_registry().add_bundle(install_path):
raise RegistrationException raise RegistrationException
def uninstall(self): def uninstall(self, force=False):
if self._unpacked: if self._unpacked:
install_path = self._path install_path = self._path
else: else:
if not self.is_installed(): if not self.is_installed():
raise NotInstalledException raise NotInstalledException
act = activity.get_registry().get_activity(self._bundle_id)
if not force and act.version != self._activity_version:
logging.warning('Not uninstalling because different bundle present')
return
elif not act.path.startswith(env.get_user_activities_path()):
logging.warning('Not uninstalling system activity')
return
install_path = os.path.join(env.get_user_activities_path(), install_path = os.path.join(env.get_user_activities_path(),
self._zip_root_dir) self._zip_root_dir)
@ -283,3 +305,17 @@ class ActivityBundle(Bundle):
if not activity.get_registry().remove_bundle(install_path): if not activity.get_registry().remove_bundle(install_path):
raise RegistrationException raise RegistrationException
def upgrade(self):
act = activity.get_registry().get_activity(self._bundle_id)
if act is None:
logging.warning('Activity not installed')
elif act.path.startswith(env.get_user_activities_path()):
try:
self.uninstall(force=True)
except Exception, e:
logging.warning('Uninstall failed (%s), still trying to install newer bundle', e)
else:
logging.warning('Unable to uninstall system activity, installing upgraded version in user activities')
self.install()

View File

@ -160,10 +160,16 @@ class DSObject(object):
if bundle_id is not None: if bundle_id is not None:
raise ValueError('Object is a bundle, cannot be resumed as an activity.') raise ValueError('Object is a bundle, cannot be resumed as an activity.')
logging.debug('Creating activity bundle')
bundle = ActivityBundle(self.file_path) bundle = ActivityBundle(self.file_path)
if not bundle.is_installed(): if not bundle.is_installed():
logging.debug('Installing activity bundle')
bundle.install() bundle.install()
elif bundle.need_upgrade():
logging.debug('Upgrading activity bundle')
bundle.upgrade()
logging.debug('activityfactory.creating bundle with id %r', bundle.get_bundle_id())
activityfactory.create(bundle.get_bundle_id()) activityfactory.create(bundle.get_bundle_id())
else: else:
if not self.get_activities() and bundle_id is None: if not self.get_activities() and bundle_id is None:

View File

@ -113,6 +113,7 @@ class ActivityRegistry(dbus.service.Object):
return {'name': bundle.get_name(), return {'name': bundle.get_name(),
'icon': bundle.get_icon(), 'icon': bundle.get_icon(),
'bundle_id': bundle.get_bundle_id(), 'bundle_id': bundle.get_bundle_id(),
'version': bundle.get_activity_version(),
'path': bundle.get_path(), 'path': bundle.get_path(),
'command': bundle.get_command(), 'command': bundle.get_command(),
'show_launcher': bundle.get_show_launcher()} 'show_launcher': bundle.get_show_launcher()}

View File

@ -129,7 +129,7 @@ class ActivitiesTray(hippo.CanvasBox):
def _activity_removed_cb(self, activity_registry, activity_info): def _activity_removed_cb(self, activity_registry, activity_info):
for item in self._tray.get_children(): for item in self._tray.get_children():
if item.get_bundle_id() == activity_info.service_name: if item.get_bundle_id() == activity_info.bundle_id:
self._tray.remove_item(item) self._tray.remove_item(item)
return return