From 32ecdd8ad628edd6affa6a0d4496a121b5a67a53 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Thu, 04 Oct 2007 20:46:32 +0000 Subject: Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar --- diff --git a/services/shell/activityregistryservice.py b/services/shell/activityregistryservice.py index 44c9969..c379071 100644 --- a/services/shell/activityregistryservice.py +++ b/services/shell/activityregistryservice.py @@ -32,13 +32,14 @@ class ActivityRegistry(dbus.service.Object): bundle_registry = bundleregistry.get_registry() bundle_registry.connect('bundle-added', self._bundle_added_cb) + bundle_registry.connect('bundle-removed', self._bundle_removed_cb) @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='b') def AddBundle(self, bundle_path): '''Register the activity bundle with the global registry - bundle_path -- path to the activity bundle's root directory, + bundle_path -- path to the root directory of the activity bundle, that is, the directory with activity/activity.info as a child of the directory. @@ -49,6 +50,16 @@ class ActivityRegistry(dbus.service.Object): return registry.add_bundle(bundle_path) @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, + in_signature='s', out_signature='b') + def RemoveBundle(self, bundle_path): + '''Unregister the activity bundle with the global registry + + bundle_path -- path to the activity bundle root directory + ''' + registry = bundleregistry.get_registry() + return registry.remove_bundle(bundle_path) + + @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='', out_signature='aa{sv}') def GetActivities(self): result = [] @@ -94,6 +105,10 @@ class ActivityRegistry(dbus.service.Object): def ActivityAdded(self, activity_info): pass + @dbus.service.signal(_ACTIVITY_REGISTRY_IFACE, signature='a{sv}') + def ActivityRemoved(self, activity_info): + pass + def _bundle_to_dict(self, bundle): return {'name': bundle.get_name(), 'icon': bundle.get_icon(), @@ -104,6 +119,9 @@ class ActivityRegistry(dbus.service.Object): def _bundle_added_cb(self, bundle_registry, bundle): self.ActivityAdded(self._bundle_to_dict(bundle)) + def _bundle_removed_cb(self, bundle_registry, bundle): + self.ActivityRemoved(self._bundle_to_dict(bundle)) + _instance = None def get_instance(): diff --git a/services/shell/bundleregistry.py b/services/shell/bundleregistry.py index 9a1cda6..54d5297 100644 --- a/services/shell/bundleregistry.py +++ b/services/shell/bundleregistry.py @@ -73,12 +73,17 @@ class _ServiceManager(object): util.write_service(bundle.get_service_name(), bundle.get_command(), self._path) + def remove(self, bundle): + util.delete_service(bundle.get_service_name(), self._path) + class BundleRegistry(gobject.GObject): """Service that tracks the available activity bundles""" __gsignals__ = { 'bundle-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) + ([gobject.TYPE_PYOBJECT])), + 'bundle-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) } def __init__(self): @@ -133,6 +138,15 @@ class BundleRegistry(gobject.GObject): self.emit('bundle-added', bundle) return True + def remove_bundle(self, bundle_path): + for bundle in self._bundles: + if bundle.get_path() == bundle_path: + self._bundles.remove(bundle) + self._service_manager.remove(bundle) + self.emit('bundle-removed', bundle) + return True + return False + def get_activities_for_type(self, mime_type): result = [] for bundle in self._bundles: diff --git a/shell/view/frame/activitiestray.py b/shell/view/frame/activitiestray.py index e4bbffc..e2a89dd 100644 --- a/shell/view/frame/activitiestray.py +++ b/shell/view/frame/activitiestray.py @@ -65,6 +65,7 @@ class ActivitiesTray(hippo.CanvasBox): registry.get_activities_async(reply_handler=self._get_activities_cb) registry.connect('activity-added', self._activity_added_cb) + registry.connect('activity-removed', self._activity_removed_cb) for invite in self._invites: self.add_invite(invite) @@ -120,16 +121,22 @@ class ActivitiesTray(hippo.CanvasBox): def _invite_removed_cb(self, invites, invite): self.remove_invite(invite) - def _activity_removed_cb(self, item): + def _remove_activity_cb(self, item): self._tray.remove_item(item) def _activity_added_cb(self, activity_registry, activity_info): self.add_activity(activity_info) + def _activity_removed_cb(self, activity_registry, activity_info): + for item in self._tray.get_children(): + if item.get_bundle_id() == activity_info.service_name: + self._tray.remove_item(item) + return + def add_activity(self, activity_info): item = ActivityButton(activity_info) item.connect('clicked', self._activity_clicked_cb) - item.connect('remove_activity', self._activity_removed_cb) + item.connect('remove_activity', self._remove_activity_cb) self._tray.add_item(item, -1) item.show() diff --git a/sugar/activity/registry.py b/sugar/activity/registry.py index 39c2b3c..8b1d440 100644 --- a/sugar/activity/registry.py +++ b/sugar/activity/registry.py @@ -43,6 +43,8 @@ class ActivityInfo(object): class ActivityRegistry(gobject.GObject): __gsignals__ = { 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'activity-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])) } def __init__(self): @@ -60,6 +62,7 @@ class ActivityRegistry(gobject.GObject): follow_name_owner_changes = True) self._registry = dbus.Interface(bus_object, _ACTIVITY_REGISTRY_IFACE) self._registry.connect_to_signal('ActivityAdded', self._activity_added_cb) + self._registry.connect_to_signal('ActivityRemoved', self._activity_removed_cb) # Two caches fo saving some travel across dbus. self._service_name_to_activity_info = {} @@ -133,6 +136,15 @@ class ActivityRegistry(gobject.GObject): self._mime_type_to_activities.clear() self.emit('activity-added', _activity_info_from_dict(info_dict)) + def remove_bundle(self, bundle_path): + return self._registry.RemoveBundle(bundle_path) + + def _activity_removed_cb(self, info_dict): + logging.debug('ActivityRegistry._activity_removed_cb: flushing caches') + self._service_name_to_activity_info.clear() + self._mime_type_to_activities.clear() + self.emit('activity-removed', _activity_info_from_dict(info_dict)) + _registry = None def get_registry(): diff --git a/sugar/bundle/activitybundle.py b/sugar/bundle/activitybundle.py index f77bdb7..0d5a5b4 100644 --- a/sugar/bundle/activitybundle.py +++ b/sugar/bundle/activitybundle.py @@ -252,8 +252,13 @@ class ActivityBundle(Bundle): raise RegistrationException def uninstall(self): - if not self.is_installed(): - raise NotInstalledException + if self._unpacked: + install_path = self._path + else: + if not self.is_installed(): + raise NotInstalledException + install_path = os.path.join(env.get_user_activities_path(), + self._zip_root_dir) xdg_data_home = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share')) @@ -271,10 +276,11 @@ class ActivityBundle(Bundle): for file in os.listdir(installed_icons_dir): path = os.path.join(installed_icons_dir, file) if os.path.islink(path) and \ - os.readlink(path).startswith(self._path): + os.readlink(path).startswith(install_path): os.remove(path) - self._uninstall() - - # FIXME: notify shell + self._uninstall(install_path) + + if not activity.get_registry().remove_bundle(install_path): + raise RegistrationException diff --git a/sugar/bundle/bundle.py b/sugar/bundle/bundle.py index 2657846..8ce3dda 100644 --- a/sugar/bundle/bundle.py +++ b/sugar/bundle/bundle.py @@ -130,19 +130,17 @@ class Bundle: zip.write(filename, os.path.join(base_dir, filename)) zip.close() - def _uninstall(self): - ext = os.path.splitext(self._path)[1] - if self._unpacked: - if not os.path.isdir(self._path) or ext != self._unzipped_extension: - raise InvalidPathException - for root, dirs, files in os.walk(self._path, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - os.rmdir(os.path.join(root, name)) - os.rmdir(self._path) - else: - if not os.path.isfile(self._path) or ext != self._zipped_extension: + def _uninstall(self, install_path): + if not os.path.isdir(install_path): + raise InvalidPathException + if self._unzipped_extension is not None: + ext = os.path.splitext(install_path)[1] + if ext != self._unzipped_extension: raise InvalidPathException - os.remove(self._path) - + + for root, dirs, files in os.walk(install_path, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + os.rmdir(install_path) diff --git a/sugar/bundle/contentbundle.py b/sugar/bundle/contentbundle.py index 7f9fddb..517ee9a 100644 --- a/sugar/bundle/contentbundle.py +++ b/sugar/bundle/contentbundle.py @@ -21,7 +21,7 @@ from ConfigParser import ConfigParser import os from sugar import env -from sugar.bundle.bundle import Bundle +from sugar.bundle.bundle import Bundle, NotInstalledException class ContentBundle(Bundle): """A Sugar content bundle @@ -178,5 +178,12 @@ class ContentBundle(Bundle): self._run_indexer() def uninstall(self): - self._uninstall() + if self._unpacked: + if not self.is_installed(): + raise NotInstalledException + install_dir = self._path + else: + install_dir = os.path.join(env.get_user_library_path(), + self._zip_root_dir) + self._uninstall(install_dir) self._run_indexer() diff --git a/sugar/util.py b/sugar/util.py index 5f01848..2780427 100644 --- a/sugar/util.py +++ b/sugar/util.py @@ -106,6 +106,20 @@ def write_service(name, bin, path): service_cp.write(fileobject) fileobject.close() +def delete_service(name, path): + """Delete a D-BUS service definition file + + Deletes a D-BUS service file previously + created by write_service(). + + name -- D-BUS service name, must be a valid + filename/D-BUS name + path -- directory containing the name.service + file + """ + + os.remove(os.path.join(path, name + '.service')) + def set_proc_title(title): """Sets the process title so ps and top show more descriptive names. This does not modify argv[0] -- cgit v0.9.1