Merge branch 'master' of git+ssh://danw@dev.laptop.org/git/sugar

This commit is contained in:
Dan Winship 2007-08-08 13:13:31 -04:00
commit bdba2d149e
17 changed files with 157 additions and 113 deletions

View File

@ -45,7 +45,7 @@ data/Makefile
lib/Makefile
lib/ui/Makefile
services/Makefile
services/clipboard/Makefile
services/shell/Makefile
shell/Makefile
shell/intro/Makefile
shell/hardware/Makefile

View File

@ -1 +1 @@
SUBDIRS = clipboard console
SUBDIRS = shell console

View File

@ -1,29 +1,37 @@
servicedir = $(datadir)/dbus-1/services
service_in_files = \
org.laptop.ActivityRegistry.service.in \
org.laptop.Clipboard.service.in \
org.laptop.ObjectTypeRegistry.service.in
service_DATA = \
org.laptop.ActivityRegistry.service \
org.laptop.Clipboard.service \
org.laptop.ObjectTypeRegistry.service
org.laptop.ActivityRegistry.service: org.laptop.ActivityRegistry.service.in Makefile
@sed -e "s|\@bindir\@|$(bindir)|" $< > $@
org.laptop.Clipboard.service: org.laptop.Clipboard.service.in Makefile
@sed -e "s|\@bindir\@|$(bindir)|" $< > $@
org.laptop.ObjectTypeRegistry.service: org.laptop.ObjectTypeRegistry.service.in Makefile
@sed -e "s|\@bindir\@|$(bindir)|" $< > $@
sugardir = $(pkgdatadir)/services/clipboard
sugardir = $(pkgdatadir)/services/shell
sugar_PYTHON = \
__init__.py \
activityregistryservice.py \
bundleregistry.py \
clipboardobject.py \
clipboardservice.py \
objecttypeservice.py
bin_SCRIPTS = sugar-clipboard
bin_SCRIPTS = sugar-shell-service
DISTCLEANFILES = $(service_DATA)
EXTRA_DIST = $(service_in_files) $(bin_SCRIPTS)

View File

@ -0,0 +1,104 @@
# Copyright (C) 2006-2007 Red Hat, Inc.
# Copyright (C) 2007 One Laptop Per Child
#
# 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 dbus
import dbus.service
import bundleregistry
_ACTIVITY_REGISTRY_SERVICE_NAME = 'org.laptop.ActivityRegistry'
_ACTIVITY_REGISTRY_IFACE = 'org.laptop.ActivityRegistry'
_ACTIVITY_REGISTRY_PATH = '/org/laptop/ActivityRegistry'
class ActivityRegistry(dbus.service.Object):
def __init__(self):
bus = dbus.SessionBus()
bus_name = dbus.service.BusName(_ACTIVITY_REGISTRY_SERVICE_NAME, bus=bus)
dbus.service.Object.__init__(self, bus_name, _ACTIVITY_REGISTRY_PATH)
bundle_registry = bundleregistry.get_registry()
bundle_registry.connect('bundle-added', self._bundle_added_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,
that is, the directory with activity/activity.info as a
child of the directory.
The bundleregistry.BundleRegistry is responsible for setting
up a set of d-bus service mappings for each available activity.
'''
registry = bundleregistry.get_registry()
return registry.add_bundle(bundle_path)
@dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
in_signature='s', out_signature='a{sv}')
def GetActivity(self, service_name):
registry = bundleregistry.get_registry()
bundle = registry.get_bundle(service_name)
if not bundle:
return {}
return self._bundle_to_dict(bundle)
@dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
in_signature='s', out_signature='aa{sv}')
def FindActivity(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._bundle_to_dict(bundle))
return result
@dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
in_signature='s', out_signature='aa{sv}')
def GetActivitiesForType(self, mime_type):
result = []
registry = bundleregistry.get_registry()
for bundle in registry.get_activities_for_type(mime_type):
result.append(self._bundle_to_dict(bundle))
return result
@dbus.service.signal(_ACTIVITY_REGISTRY_IFACE, signature='a{sv}')
def ActivityAdded(self, activity_info):
pass
def _bundle_to_dict(self, bundle):
return {'name': bundle.get_name(),
'icon': bundle.get_icon(),
'service_name': bundle.get_service_name(),
'path': bundle.get_path()}
def _bundle_added_cb(self, bundle_registry, bundle):
self.ActivityAdded(self._bundle_to_dict(bundle))
_instance = None
def get_instance():
global _instance
if not _instance:
_instance = ActivityRegistry()
return _instance

View File

@ -106,6 +106,13 @@ class BundleRegistry(gobject.GObject):
else:
return False
def get_activities_for_type(self, mime_type):
result = []
for bundle in self._bundles.values():
if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
result.append(bundle)
return result
def get_registry():
return _bundle_registry

View File

@ -19,9 +19,9 @@ import logging
import urlparse
from sugar.objects import mime
from sugar import activity
import objecttypeservice
import bundleregistry
class ClipboardObject:
@ -66,30 +66,15 @@ class ClipboardObject:
return ''
def get_activity(self):
logging.debug('get_activity')
mapping = {'text/html' : 'org.laptop.WebActivity',
'image/jpeg' : 'org.laptop.WebActivity',
'image/gif' : 'org.laptop.WebActivity',
'image/png' : 'org.laptop.WebActivity',
'text/plain' : 'org.laptop.AbiWordActivity',
'text/rtf' : 'org.laptop.AbiWordActivity',
'text/richtext' : 'org.laptop.AbiWordActivity',
'application/pdf' : 'org.laptop.sugar.ReadActivity',
'application/x-squeak-project' : 'org.vpri.EtoysActivity'}
mime = self.get_mime_type()
if not mime:
return ''
"""
registry = activity.get_registry()
registry = bundleregistry.get_registry()
activities = registry.get_activities_for_type(self.get_mime_type())
# TODO: should we return several activities?
if activities:
return activities[0]
else:
return ''
"""
if mapping.has_key(mime):
return mapping[mime]
return activities[0].get_service_name()
else:
return ''
@ -101,8 +86,6 @@ class ClipboardObject:
def add_format(self, format):
self._formats[format.get_type()] = format
# We want to get the activity early in order to prevent a DBus lockup.
activity = self.get_activity()
def get_formats(self):
return self._formats

View File

@ -0,0 +1,4 @@
[D-BUS Service]
Name = org.laptop.ActivityRegistry
Exec = @bindir@/sugar-shell-service

View File

@ -1,4 +1,4 @@
[D-BUS Service]
Name = org.laptop.Clipboard
Exec = @bindir@/sugar-clipboard
Exec = @bindir@/sugar-shell-service

View File

@ -1,4 +1,4 @@
[D-BUS Service]
Name = org.laptop.ObjectTypeRegistry
Exec = @bindir@/sugar-clipboard
Exec = @bindir@/sugar-shell-service

View File

@ -23,28 +23,31 @@ import os
import logging
from sugar import logger
logger.start('clipboard')
logger.start('shellservice')
import gobject
import dbus.glib
from sugar import env
sys.path.append(env.get_service_path('clipboard'))
sys.path.append(env.get_service_path('shell'))
import clipboardservice
import objecttypeservice
import activityregistryservice
logging.info('Starting clipboard service.')
logging.info('Starting shell service.')
gobject.threads_init()
dbus.glib.threads_init()
clipboard_service = clipboardservice.get_instance()
object_type_registry = objecttypeservice.get_instance()
activity_registry = activityregistryservice.get_instance()
loop = gobject.MainLoop()
try:
loop.run()
except KeyboardInterrupt:
print 'Ctrl+C pressed, exiting...'

View File

@ -4,7 +4,6 @@ sugardir = $(pkgdatadir)/shell/model
sugar_PYTHON = \
__init__.py \
accesspointmodel.py \
bundleregistry.py \
BuddyModel.py \
Friends.py \
Invites.py \

View File

@ -17,10 +17,7 @@
"""D-bus service providing access to the shell's functionality"""
import dbus
from model import bundleregistry
_DBUS_SERVICE = "org.laptop.Shell"
_DBUS_ACTIVITY_REGISTRY_IFACE = "org.laptop.Shell.ActivityRegistry"
_DBUS_SHELL_IFACE = "org.laptop.Shell"
_DBUS_OWNER_IFACE = "org.laptop.Shell.Owner"
_DBUS_PATH = "/org/laptop/Shell"
@ -56,9 +53,6 @@ class ShellService(dbus.service.Object):
self._home_model.connect('active-activity-changed',
self._cur_activity_changed_cb)
bundle_registry = bundleregistry.get_registry()
bundle_registry.connect('bundle-added', self._bundle_added_cb)
bus = dbus.SessionBus()
bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus)
dbus.service.Object.__init__(self, bus_name, _DBUS_PATH)
@ -83,60 +77,6 @@ class ShellService(dbus.service.Object):
def NotifyLaunchFailure(self, activity_id):
self._shell.notify_launch_failure(activity_id)
@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,
that is, the directory with activity/activity.info as a
child of the directory.
The bundleregistry.BundleRegistry is responsible for setting
up a set of d-bus service mappings for each available activity.
"""
registry = bundleregistry.get_registry()
return registry.add_bundle(bundle_path)
@dbus.service.method(_DBUS_ACTIVITY_REGISTRY_IFACE,
in_signature="s", out_signature="a{sv}")
def GetActivity(self, service_name):
registry = bundleregistry.get_registry()
bundle = registry.get_bundle(service_name)
if not bundle:
return {}
return self._bundle_to_dict(bundle)
@dbus.service.method(_DBUS_ACTIVITY_REGISTRY_IFACE,
in_signature="s", out_signature="aa{sv}")
def FindActivity(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._bundle_to_dict(bundle))
return result
@dbus.service.method(_DBUS_ACTIVITY_REGISTRY_IFACE,
in_signature="s", out_signature="aa{sv}")
def GetActivitiesForType(self, mime_type):
result = []
for bundle in bundleregistry.get_registry():
if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
result.append(self._bundle_to_dict(bundle))
return result
@dbus.service.signal(_DBUS_ACTIVITY_REGISTRY_IFACE, signature="a{sv}")
def ActivityAdded(self, activity_info):
pass
@dbus.service.signal(_DBUS_OWNER_IFACE, signature="s")
def ColorChanged(self, color):
pass
@ -169,12 +109,3 @@ class ShellService(dbus.service.Object):
if new_id:
self.CurrentActivityChanged(new_id)
def _bundle_to_dict(self, bundle):
return {'name': bundle.get_name(),
'icon': bundle.get_icon(),
'service_name': bundle.get_service_name(),
'path': bundle.get_path()}
def _bundle_added_cb(self, bundle_registry, bundle):
self.ActivityAdded(self._bundle_to_dict(bundle))

View File

@ -64,11 +64,13 @@ class ClipboardMenu(Palette):
self._remove_item = MenuItem(_('Remove'), 'stock-remove')
self._remove_item.connect('activate', self._remove_item_activate_cb)
self.append_menu_item(self._remove_item)
self.menu.append(self._remove_item)
self._remove_item.show()
self._open_item = MenuItem(_('Open'), 'stock-keep')
self._open_item.connect('activate', self._open_item_activate_cb)
self.append_menu_item(self._open_item)
self.menu.append(self._open_item)
self._open_item.show()
#self._stop_item = MenuItem(_('Stop download'), 'stock-close')
# TODO: Implement stopping downloads
@ -77,7 +79,8 @@ class ClipboardMenu(Palette):
self._journal_item = MenuItem(_('Add to journal'), 'document-save')
self._journal_item.connect('activate', self._journal_item_activate_cb)
self.append_menu_item(self._journal_item)
self.menu.append(self._journal_item)
self._journal_item.show()
self._update_items_visibility(installable)

View File

@ -1,4 +1,5 @@
# Copyright (C) 2006-2007 Red Hat, Inc.
# Copyright (C) 2007 One Laptop Per Child
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@ -19,9 +20,9 @@ import logging
import dbus
_SHELL_SERVICE = "org.laptop.Shell"
_SHELL_PATH = "/org/laptop/Shell"
_REGISTRY_IFACE = "org.laptop.Shell.ActivityRegistry"
_ACTIVITY_REGISTRY_SERVICE_NAME = 'org.laptop.ActivityRegistry'
_ACTIVITY_REGISTRY_IFACE = 'org.laptop.ActivityRegistry'
_ACTIVITY_REGISTRY_PATH = '/org/laptop/ActivityRegistry'
def _activity_info_from_dict(info_dict):
if not info_dict:
@ -39,8 +40,9 @@ class ActivityInfo(object):
class ActivityRegistry(object):
def __init__(self):
bus = dbus.SessionBus()
bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
self._registry = dbus.Interface(bus_object, _REGISTRY_IFACE)
bus_object = bus.get_object(_ACTIVITY_REGISTRY_SERVICE_NAME,
_ACTIVITY_REGISTRY_PATH)
self._registry = dbus.Interface(bus_object, _ACTIVITY_REGISTRY_IFACE)
self._registry.connect_to_signal('ActivityAdded', self._activity_added_cb)
# Two caches fo saving some travel across dbus.