Use dbus activation to launch factories. This breaks

p-to-p chat and ./sugar/activities. Will fix tomorrow.
This commit is contained in:
Marco Pesenti Gritti 2006-07-28 01:25:08 +02:00
parent 1d370ca8e5
commit 86bd6f50f0
23 changed files with 186 additions and 86 deletions

1
.gitignore vendored
View File

@ -18,6 +18,7 @@ install-sh
missing
py-compile
stamp-h1
dbus-installed.conf
intltool-extract
intltool-extract.in

View File

@ -1 +1,7 @@
SUBDIRS = activities shell sugar
dbusconfdir = $(pkgdatadir)
dbusconf_DATA = dbus-installed.conf
install-data-local:
sugar/setup.py $(top_srcdir)/activities $(pkgdatadir)/activities $(bindir)/sugar-activity-factory

View File

@ -6,7 +6,4 @@ sugar_PYTHON = \
BrowserActivity.py \
NavigationToolbar.py
activitydir = $(pkgdatadir)/activities/browser
activity_DATA = browser.activity
EXTRA_DIST = $(activity_DATA)
EXTRA_DIST = browser.activity

View File

@ -1,6 +1,6 @@
[Activity]
name = Web
id = com.redhat.Sugar.BrowserActivity
python_module = BrowserActivity.BrowserActivity
python_module = browser.BrowserActivity.BrowserActivity
default_type = _web_olpc._udp
show_launcher = yes

View File

@ -3,7 +3,4 @@ sugar_PYTHON = \
__init__.py \
ChatActivity.py
activitydir = $(pkgdatadir)/activities/chat
activity_DATA = chat.activity
EXTRA_DIST = $(activity_DATA)
EXTRA_DIST = chat.activity

View File

@ -1,5 +1,5 @@
[Activity]
name = Chat
id = com.redhat.Sugar.ChatActivity
python_module = ChatActivity.ChatActivity
python_module = chat.ChatActivity.ChatActivity
default_type = _chat_activity._tcp

View File

@ -1,9 +1,6 @@
sugardir = $(pkgdatadir)/activities/browser
sugardir = $(pkgdatadir)/activities/terminal
sugar_PYTHON = \
__init__.py \
terminal.py
TerminalActivity.py
activitydir = $(pkgdatadir)/activities/browser
activity_DATA = terminal.activity
EXTRA_DIST = $(activity_DATA)
EXTRA_DIST = terminal.activity

View File

@ -1,4 +1,4 @@
[Activity]
name = Terminal
id = org.sugar.Terminal
python_module = terminal.TerminalActivity
python_module = terminal.TerminalActivity.TerminalActivity

View File

@ -23,6 +23,7 @@ AM_GLIB_GNU_GETTEXT
AC_OUTPUT([
Makefile
dbus-installed.conf
activities/Makefile
activities/browser/Makefile
activities/chat/Makefile

24
dbus-installed.conf.in Normal file
View File

@ -0,0 +1,24 @@
<!-- This configuration file controls the per-user-login-session message bus.
Add a session-local.conf and edit that rather than changing this
file directly. -->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Our well-known bus type, don't change this -->
<type>session</type>
<listen>unix:tmpdir=/tmp</listen>
<servicedir>@prefix@/share/sugar/activities</servicedir>
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
</policy>
</busconfig>

24
dbus-uninstalled.conf Normal file
View File

@ -0,0 +1,24 @@
<!-- This configuration file controls the per-user-login-session message bus.
Add a session-local.conf and edit that rather than changing this
file directly. -->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Our well-known bus type, don't change this -->
<type>session</type>
<listen>unix:tmpdir=/tmp</listen>
<servicedir>/tmp/sugar</servicedir>
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
</policy>
</busconfig>

View File

@ -3,16 +3,13 @@ import os
from ConfigParser import ConfigParser
from ConfigParser import NoOptionError
from sugar import env
class ActivityModule:
"""Info about an activity module. Wraps a .activity file."""
def __init__(self, name, activity_id, activity_exec, directory):
def __init__(self, name, activity_id, directory):
self._name = name
self._id = activity_id
self._directory = directory
self._exec = activity_exec
self._show_launcher = False
def get_name(self):
@ -23,10 +20,6 @@ class ActivityModule:
"""Get the activity identifier"""
return self._id
def get_exec(self):
"""Get the activity executable"""
return self._exec
def get_directory(self):
"""Get the path to activity directory."""
return self._directory
@ -63,12 +56,9 @@ class ActivityRegistry:
def scan_directory(self, path):
"""Scan a directory for activities and add them to the registry."""
if os.path.isdir(path):
for filename in os.listdir(path):
activity_dir = os.path.join(path, filename)
if os.path.isdir(activity_dir):
for filename in os.listdir(activity_dir):
if filename.endswith(".activity"):
self.add(os.path.join(activity_dir, filename))
for f in os.listdir(path):
if f.endswith(".activity"):
self.add(os.path.join(path, f))
def add(self, path):
"""Add an activity to the registry. The path points to a .activity file."""
@ -94,21 +84,7 @@ class ActivityRegistry:
else:
default_type = None
if cp.has_option('Activity', 'exec'):
activity_exec = cp.get('Activity', 'exec')
elif cp.has_option('Activity', 'python_module'):
python_module = cp.get('Activity', 'python_module')
python_module = cp.get('Activity', 'python_module')
activity_exec = '%s %s %s' % ('sugar-activity-factory',
activity_id, python_module)
if default_type:
activity_exec += ' ' + default_type
env.add_to_python_path(directory)
else:
logging.error('%s must specifiy exec or python_module' % (path))
return False
module = ActivityModule(name, activity_id, activity_exec, directory)
module = ActivityModule(name, activity_id, directory)
self._activities.append(module)
if cp.has_option('Activity', 'show_launcher'):

View File

@ -11,17 +11,12 @@ from Process import Process
import sugar.theme
import sugar.env
class ActivityProcess(Process):
def __init__(self, module):
Process.__init__(self, module.get_exec())
self._module = module
def get_name(self):
return self._module.get_name()
class DbusProcess(Process):
def __init__(self):
Process.__init__(self, "dbus-daemon --session --print-address")
config = sugar.env.get_dbus_config()
cmd = "dbus-daemon --print-address --config-file %s" % config
print cmd
Process.__init__(self, cmd)
def get_name(self):
return 'Dbus'
@ -66,9 +61,9 @@ class PresenceServiceProcess(Process):
class Session:
"""Takes care of running the shell and all the sugar processes"""
def __init__(self):
def __init__(self, registry):
sugar.theme.setup()
self._registry = registry
def start(self):
"""Start the session"""
@ -81,14 +76,9 @@ class Session:
process = PresenceServiceProcess()
process.start()
shell = Shell()
shell = Shell(self._registry)
shell.start()
registry = shell.get_registry()
for activity_module in registry.list_activities():
process = ActivityProcess(activity_module)
process.start()
try:
gtk.main()
except KeyboardInterrupt:

View File

@ -42,8 +42,9 @@ class ShellDbusService(dbus.service.Object):
gobject.idle_add(self.__log_idle, (module_id, message))
class Shell:
def __init__(self):
def __init__(self, registry):
self._screen = wnck.screen_get_default()
self._registry = registry
def start(self):
log_writer = LogWriter("Shell", False)
@ -56,10 +57,6 @@ class Shell:
self._owner = ShellOwner()
self._owner.announce()
self._registry = ActivityRegistry()
self._registry.scan_directory(env.get_activities_dir())
self._registry.scan_directory(os.path.join(env.get_user_dir(), 'activities'))
self._home_window = HomeWindow(self)
self._home_window.show()

View File

@ -4,6 +4,7 @@ import sys
import os
import pwd
import random
import tempfile
import pygtk
pygtk.require('2.0')
@ -47,10 +48,33 @@ if os.path.isfile(os.path.join(basedir, 'sugar/__uninstalled__.py')):
add_to_bin_path(os.path.join(basedir, 'shell'))
add_to_python_path(basedir)
add_to_python_path(os.path.join(basedir, 'shell'))
add_to_python_path(os.path.join(basedir, 'activities'))
from sugar import env
from sugar import setup
activities_dest = os.path.join(tempfile.gettempdir(), 'sugar')
if not os.path.isdir(activities_dest):
os.mkdir(activities_dest)
else:
# FIXME delete the whole directory
pass
setup.install_activities(env.get_activities_dir(), activities_dest,
os.path.join(basedir, 'shell/sugar-activity-factory'))
else:
import sugar.env
add_to_python_path(os.path.join(sugar.env.get_data_dir(), 'shell'))
print 'Running the installed sugar...'
from sugar import env
add_to_python_path(os.path.join(env.get_data_dir(), 'shell'))
add_to_python_path(os.path.join(env.get_data_dir(), 'activities'))
activities_dest = env.get_activities_dir()
from ActivityRegistry import ActivityRegistry
registry = ActivityRegistry()
registry.scan_directory(activities_dest)
#registry.scan_directory(os.path.join(env.get_user_dir(), 'activities'))
from Emulator import Emulator
@ -62,5 +86,5 @@ print 'Redirecting output to the console, press F3 to open it.'
from Session import Session
session = Session()
session = Session(registry)
session.start()

View File

@ -15,8 +15,8 @@ logging.info('Starting activity factory %s' % sys.argv[1])
theme.setup()
lw = LogWriter(sys.argv[1])
lw.start()
#lw = LogWriter(sys.argv[1])
#lw.start()
if len(sys.argv) == 4:
Activity.register_factory(sys.argv[1], sys.argv[2], sys.argv[3])

View File

@ -6,6 +6,7 @@ sugar_PYTHON = \
__installed__.py \
bots.py \
env.py \
setup.py \
theme.py \
util.py \
LogWriter.py

View File

@ -1,3 +1,4 @@
sugar_data_dir = '@prefix@/share/sugar'
sugar_activity_runner = '@prefix@/bin/sugar-activity'
sugar_activities_dir = '@prefix@/share/sugar/activities'
sugar_dbus_config = '@prefix@/share/sugar/dbus-installed.conf'

View File

@ -4,3 +4,4 @@ _source_dir = os.path.dirname(os.path.dirname(__file__))
sugar_data_dir = os.path.join(_source_dir, 'shell/data')
sugar_activities_dir = os.path.join(_source_dir, 'activities')
sugar_dbus_config = os.path.join(_source_dir, 'dbus-uninstalled.conf')

View File

@ -1,5 +1,4 @@
import sys
import imp
import dbus
import dbus.service
@ -34,20 +33,14 @@ class ActivityFactory(dbus.service.Object):
def __init__(self, name, activity_class, default_type):
self._default_type = default_type
splitted_module = activity_class.rsplit('.', 1)
module_name = splitted_module[0]
class_name = splitted_module[1]
(fp, pathname, description) = imp.find_module(module_name)
module = imp.load_module(module_name, fp, pathname, description)
try:
start = getattr(module, 'start')
except:
start = None
if start:
start()
module = __import__(module_name)
for comp in module_name.split('.')[1:]:
module = getattr(module, comp)
self._class = getattr(module, class_name)

View File

@ -34,6 +34,9 @@ def get_nick_name():
def get_data_dir():
return sugar_data_dir
def get_dbus_config():
return sugar_dbus_config
def get_data_file(filename):
return os.path.join(get_data_dir(), filename)

67
sugar/setup.py Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/python
import os
import sys
import shutil
import logging
from ConfigParser import ConfigParser
from ConfigParser import NoOptionError
class ServiceParser(ConfigParser):
def optionxform(self, option):
return option
def _install_activity(activity_dir, filename, dest_path, bin):
source = os.path.join(activity_dir, filename)
dest = os.path.join(dest_path, filename)
print 'Install ' + filename + ' ...'
shutil.copyfile(source, dest)
cp = ConfigParser()
cp.read([source])
try:
activity_id = cp.get('Activity', 'id')
except NoOptionError:
logging.error('%s miss the required id option' % (path))
return False
if cp.has_option('Activity', 'default_type'):
default_type = cp.get('Activity', 'default_type')
else:
default_type = None
if cp.has_option('Activity', 'exec'):
activity_exec = cp.get('Activity', 'exec')
elif cp.has_option('Activity', 'python_module'):
python_module = cp.get('Activity', 'python_module')
python_module = cp.get('Activity', 'python_module')
activity_exec = '%s %s %s' % (bin, activity_id, python_module)
if default_type:
activity_exec += ' ' + default_type
else:
logging.error('%s must specifiy exec or python_module' % (source))
return False
service_cp = ServiceParser()
section = 'D-BUS Service'
service_cp.add_section(section)
service_cp.set(section, 'Name', activity_id + '.Factory')
service_cp.set(section, 'Exec', activity_exec)
fileobject = open(os.path.join(dest_path, activity_id + '.service'), 'w')
service_cp.write(fileobject)
fileobject.close()
def install_activities(source_path, dest_path, bin):
"""Scan a directory for activities and install them."""
if os.path.isdir(source_path):
for filename in os.listdir(source_path):
activity_dir = os.path.join(source_path, filename)
if os.path.isdir(activity_dir):
for filename in os.listdir(activity_dir):
if filename.endswith(".activity"):
_install_activity(activity_dir, filename, dest_path, bin)
if __name__=='__main__':
install_activities(sys.argv[1], sys.argv[2], sys.argv[3])