diff options
author | Marco Pesenti Gritti <marco@localhost.localdomain> | 2007-05-27 18:24:10 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <marco@localhost.localdomain> | 2007-05-27 18:24:10 (GMT) |
commit | 42fef182f4a2853cd7da0c550f77a81c5f749d90 (patch) | |
tree | 6366c97d5c324918ce63668f2af4e18c17d835dd /shell | |
parent | 8c70ff2d8647bc6378398aeecf0e8a74a4c5a82c (diff) |
Refactor the bundle registry. Move it inside
the shell and expose the parts that should be
public to the shell dbus service.
Diffstat (limited to 'shell')
-rw-r--r-- | shell/model/Makefile.am | 1 | ||||
-rw-r--r-- | shell/model/MeshModel.py | 3 | ||||
-rw-r--r-- | shell/model/bundleregistry.py | 118 | ||||
-rw-r--r-- | shell/model/homemodel.py | 2 | ||||
-rw-r--r-- | shell/shellservice.py | 59 | ||||
-rw-r--r-- | shell/view/Shell.py | 8 | ||||
-rw-r--r-- | shell/view/frame/ActivitiesBox.py | 3 | ||||
-rw-r--r-- | shell/view/home/FriendView.py | 5 |
8 files changed, 181 insertions, 18 deletions
diff --git a/shell/model/Makefile.am b/shell/model/Makefile.am index 9e24dc4..fcc936b 100644 --- a/shell/model/Makefile.am +++ b/shell/model/Makefile.am @@ -4,6 +4,7 @@ sugardir = $(pkgdatadir)/shell/model sugar_PYTHON = \ __init__.py \ accesspointmodel.py \ + bundleregistry.py \ BuddyModel.py \ Friends.py \ Invites.py \ diff --git a/shell/model/MeshModel.py b/shell/model/MeshModel.py index 93e2a23..ed92ae0 100644 --- a/shell/model/MeshModel.py +++ b/shell/model/MeshModel.py @@ -18,7 +18,8 @@ import gobject from sugar.graphics.xocolor import XoColor from sugar.presence import presenceservice -from sugar.activity import bundleregistry + +from model import bundleregistry from model.BuddyModel import BuddyModel from model.accesspointmodel import AccessPointModel from hardware import hardwaremanager diff --git a/shell/model/bundleregistry.py b/shell/model/bundleregistry.py new file mode 100644 index 0000000..1771fa8 --- /dev/null +++ b/shell/model/bundleregistry.py @@ -0,0 +1,118 @@ +# Copyright (C) 2006, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os + +import gobject + +from sugar.activity.bundle import Bundle +from sugar import env +from sugar import util + +# http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html +def _get_data_dirs(): + if os.environ.has_key('XDG_DATA_DIRS'): + return os.environ['XDG_DATA_DIRS'].split(':') + else: + return [ '/usr/local/share/', '/usr/share/' ] + +class _ServiceManager(object): + """Internal class responsible for creating dbus service files + + DBUS services are defined in files which bind a service name + to the name of an executable which provides the service name. + + In Sugar, the service files are automatically generated from + the activity registry (by this class). When an activity's + dbus launch service is requested, dbus will launch the + specified executable in order to allow it to provide the + requested activity-launching service. + + In the case of activities which provide a "class", instead of + an "exec" attribute in their activity.info, the + sugar-activity-factory script is used with an appropriate + argument to service that bundle. + """ + SERVICE_DIRECTORY = '~/.local/share/dbus-1/services' + def __init__(self): + service_dir = os.path.expanduser(self.SERVICE_DIRECTORY) + if not os.path.isdir(service_dir): + os.makedirs(service_dir) + + self._path = service_dir + + def add(self, bundle): + util.write_service(bundle.get_service_name(), + bundle.get_exec(), 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])) + } + + def __init__(self): + gobject.GObject.__init__(self) + + self._bundles = {} + self._search_path = [] + self._service_manager = _ServiceManager() + + def get_bundle(self, service_name): + """Returns an bundle given his service name""" + if self._bundles.has_key(service_name): + return self._bundles[service_name] + else: + return None + + def add_search_path(self, path): + """Add a directory to the bundles search path""" + self._search_path.append(path) + self._scan_directory(path) + + def __iter__(self): + return self._bundles.values().__iter__() + + def _scan_directory(self, path): + if os.path.isdir(path): + for f in os.listdir(path): + bundle_dir = os.path.join(path, f) + if os.path.isdir(bundle_dir) and \ + bundle_dir.endswith('.activity'): + self.add_bundle(bundle_dir) + + def add_bundle(self, bundle_path): + bundle = Bundle(bundle_path) + if bundle.is_valid(): + self._bundles[bundle.get_service_name()] = bundle + self._service_manager.add(bundle) + self.emit('bundle-added', bundle) + return True + else: + return False + +def get_registry(): + return _bundle_registry + +_bundle_registry = BundleRegistry() + +for path in _get_data_dirs(): + bundles_path = os.path.join(path, 'activities') + _bundle_registry.add_search_path(bundles_path) + +_bundle_registry.add_search_path(env.get_user_activities_path()) diff --git a/shell/model/homemodel.py b/shell/model/homemodel.py index 92afc23..9b99518 100644 --- a/shell/model/homemodel.py +++ b/shell/model/homemodel.py @@ -22,7 +22,7 @@ import dbus from model.homeactivity import HomeActivity from model.homerawwindow import HomeRawWindow -from sugar.activity import bundleregistry +from model import bundleregistry _SERVICE_NAME = "org.laptop.Activity" _SERVICE_PATH = "/org/laptop/Activity" diff --git a/shell/shellservice.py b/shell/shellservice.py index 3b42940..4e8f469 100644 --- a/shell/shellservice.py +++ b/shell/shellservice.py @@ -1,11 +1,30 @@ +# Copyright (C) 2006, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + """D-bus service providing access to the shell's functionality""" import dbus -from sugar.activity import bundleregistry +from sugar.activity import ActivityRegistry +from sugar.activity import ActivityInfo + +from model import bundleregistry _DBUS_SERVICE = "org.laptop.Shell" -_DBUS_INTERFACE = "org.laptop.Shell" -_DBUS_OWNER_INTERFACE = "org.laptop.Shell.Owner" +_DBUS_ACTIVITY_REGISTRY_IFACE = "org.laptop.Shell.ActivityRegistry" +_DBUS_OWNER_IFACE = "org.laptop.Shell.Owner" _DBUS_PATH = "/org/laptop/Shell" class ShellService(dbus.service.Object): @@ -35,14 +54,16 @@ class ShellService(dbus.service.Object): self._owner.connect('color-changed', self._owner_color_changed_cb) self._home_model = self._shell_model.get_home() - self._home_model.connect('active-activity-changed', self._cur_activity_changed_cb) + self._home_model.connect('active-activity-changed', + self._cur_activity_changed_cb) bus = dbus.SessionBus() bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus) dbus.service.Object.__init__(self, bus_name, _DBUS_PATH) - @dbus.service.method(_DBUS_INTERFACE, in_signature="s", out_signature="b") - def add_bundle(self, bundle_path): + @dbus.service.method(_DBUS_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, @@ -55,28 +76,42 @@ class ShellService(dbus.service.Object): registry = bundleregistry.get_registry() return registry.add_bundle(bundle_path) - @dbus.service.signal(_DBUS_OWNER_INTERFACE, signature="s") + @dbus.service.method(_DBUS_ACTIVITY_REGISTRY_IFACE, + in_signature="s", out_signature="aa{sv}") + def GetActivitiesForName(self, name): + result = [] + key = name.lower() + + for bundle in bundleregistry.get_registry(): + name = bundle.get_name().lower() + service_name = bundle.get_service_name().lower() + if name.find(key) != -1 or service_name.find(key) != -1: + result.append(self._get_activity_info(bundle).to_dict()) + + return result + + @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") def ColorChanged(self, color): pass def _owner_color_changed_cb(self, new_color): self.ColorChanged(new_color.to_string()) - @dbus.service.signal(_DBUS_OWNER_INTERFACE, signature="s") + @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") def NickChanged(self, nick): pass def _owner_nick_changed_cb(self, new_nick): self.NickChanged(new_nick) - @dbus.service.signal(_DBUS_OWNER_INTERFACE, signature="ay") + @dbus.service.signal(_DBUS_OWNER_IFACE, signature="ay") def IconChanged(self, icon_data): pass def _owner_icon_changed_cb(self, new_icon): self.IconChanged(dbus.ByteArray(new_icon)) - @dbus.service.signal(_DBUS_OWNER_INTERFACE, signature="s") + @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") def CurrentActivityChanged(self, activity_id): pass @@ -85,3 +120,7 @@ class ShellService(dbus.service.Object): if new_activity: new_id = new_activity.get_activity_id() self.CurrentActivityChanged(new_id) + + def _get_activity_info(self, bundle): + return ActivityInfo(bundle.get_name(), bundle.get_icon(), + bundle.get_service_name(), bundle.get_path()) diff --git a/shell/view/Shell.py b/shell/view/Shell.py index f2827e0..0f3b629 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -20,14 +20,16 @@ import logging import gobject import wnck -from view.home.HomeWindow import HomeWindow from sugar.activity.activityhandle import ActivityHandle from sugar.graphics.popupcontext import PopupContext +from sugar.activity import activityfactory +import sugar + from view.ActivityHost import ActivityHost -from sugar.activity import activityfactory, bundleregistry from view.frame.frame import Frame from view.keyhandler import KeyHandler -import sugar +from view.home.HomeWindow import HomeWindow +from model import bundleregistry class Shell(gobject.GObject): def __init__(self, model): diff --git a/shell/view/frame/ActivitiesBox.py b/shell/view/frame/ActivitiesBox.py index 77bf093..a755b4e 100644 --- a/shell/view/frame/ActivitiesBox.py +++ b/shell/view/frame/ActivitiesBox.py @@ -20,9 +20,10 @@ import logging from sugar.graphics import units from sugar.graphics.xocolor import XoColor from sugar.graphics.iconbutton import IconButton -from sugar.activity import bundleregistry from sugar import profile +from model import bundleregistry + class ActivityButton(IconButton): def __init__(self, activity, popup_context): IconButton.__init__(self, icon_name=activity.get_icon(), diff --git a/shell/view/home/FriendView.py b/shell/view/home/FriendView.py index 5dc98a5..317ca66 100644 --- a/shell/view/home/FriendView.py +++ b/shell/view/home/FriendView.py @@ -17,11 +17,12 @@ import hippo import gobject -from view.BuddyIcon import BuddyIcon from sugar.graphics.canvasicon import CanvasIcon from sugar.graphics import units from sugar.presence import presenceservice -from sugar.activity import bundleregistry + +from model import bundleregistry +from view.BuddyIcon import BuddyIcon class FriendView(hippo.CanvasBox): def __init__(self, shell, menu_shell, buddy, **kwargs): |