Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2007-01-27 11:54:56 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2007-01-27 11:54:56 (GMT)
commit9d13a9836d10e8ef5d2dda4dff6a7931ca2af728 (patch)
treeb05c8b37576e56201ebb6fb7b030e3c018da35f5
parent37c6c1e9fa9b42d7a65f2234eac61307352887c2 (diff)
Added new tool sugar-install-bundle.
-rw-r--r--shell/model/ShellModel.py3
-rw-r--r--shell/shellservice.py19
-rwxr-xr-xshell/sugar-shell2
-rw-r--r--shell/view/frame/ActivitiesBox.py8
-rw-r--r--sugar/activity/bundlebuilder.py8
-rw-r--r--sugar/activity/bundleregistry.py18
-rw-r--r--sugar/env.py7
-rw-r--r--tools/Makefile.am3
-rwxr-xr-xtools/sugar-install-bundle56
9 files changed, 110 insertions, 14 deletions
diff --git a/shell/model/ShellModel.py b/shell/model/ShellModel.py
index b1c21bc..11254d9 100644
--- a/shell/model/ShellModel.py
+++ b/shell/model/ShellModel.py
@@ -55,8 +55,7 @@ class ShellModel(gobject.GObject):
self._mesh = MeshModel(self._bundle_registry)
self._home = HomeModel(self._bundle_registry)
- path = os.path.expanduser('~/Activities')
- self._bundle_registry.add_search_path(path)
+ self._bundle_registry.add_search_path(env.get_user_activities_dir())
for path in env.get_data_dirs():
bundles_path = os.path.join(path, 'activities')
diff --git a/shell/shellservice.py b/shell/shellservice.py
new file mode 100644
index 0000000..dcbfc0e
--- /dev/null
+++ b/shell/shellservice.py
@@ -0,0 +1,19 @@
+import dbus
+
+_DBUS_SERVICE = "org.laptop.Shell"
+_DBUS_INTERFACE = "org.laptop.Shell"
+_DBUS_PATH = "/org/laptop/Shell"
+
+class ShellService(dbus.service.Object):
+
+ def __init__(self, shellModel):
+ self._shellModel = shellModel
+
+ 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):
+ registry = self._shellModel.get_bundle_registry()
+ return registry.add_bundle(bundle_path)
diff --git a/shell/sugar-shell b/shell/sugar-shell
index 4eaccf5..08a3a6d 100755
--- a/shell/sugar-shell
+++ b/shell/sugar-shell
@@ -37,6 +37,7 @@ sys.path.insert(0, os.path.join(env.get_data_dir(), 'shell'))
from view.FirstTimeDialog import FirstTimeDialog
from view.Shell import Shell
from model.ShellModel import ShellModel
+from shellservice import ShellService
name = profile.get_nick_name()
if not name or not len(name):
@@ -54,6 +55,7 @@ f.write(os.environ["DBUS_SESSION_BUS_ADDRESS"])
f.close()
model = ShellModel()
+service = ShellService(model)
shell = Shell(model)
# Start the NetworkManager applet
diff --git a/shell/view/frame/ActivitiesBox.py b/shell/view/frame/ActivitiesBox.py
index 2ca0cfd..c265b6c 100644
--- a/shell/view/frame/ActivitiesBox.py
+++ b/shell/view/frame/ActivitiesBox.py
@@ -69,10 +69,13 @@ class ActivitiesBox(hippo.CanvasBox):
self._invite_to_item = {}
self._invites = self._shell_model.get_invites()
- for bundle in self._shell_model.get_bundle_registry():
+ bundle_registry = self._shell_model.get_bundle_registry()
+ for bundle in bundle_registry:
if bundle.get_show_launcher():
self.add_activity(bundle)
+ bundle_registry.connect('bundle-added', self._bundle_added_cb)
+
for invite in self._invites:
self.add_invite(invite)
self._invites.connect('invite-added', self._invite_added_cb)
@@ -92,6 +95,9 @@ class ActivitiesBox(hippo.CanvasBox):
def _invite_removed_cb(self, invites, invite):
self.remove_invite(invite)
+ def _bundle_added_cb(self, bundle_registry, bundle):
+ self.add_activity(bundle)
+
def add_activity(self, activity):
item = ActivityItem(activity)
item.connect('activated', self._activity_clicked_cb)
diff --git a/sugar/activity/bundlebuilder.py b/sugar/activity/bundlebuilder.py
index a2e338f..9b3a81d 100644
--- a/sugar/activity/bundlebuilder.py
+++ b/sugar/activity/bundlebuilder.py
@@ -68,12 +68,6 @@ def _extract_bundle(source_file, dest_dir):
def _get_source_path():
return os.getcwd()
-def _get_activities_path():
- path = os.path.expanduser('~/Activities')
- if not os.path.isdir(path):
- os.mkdir(path)
- return path
-
def _get_bundle_dir():
bundle_name = os.path.basename(_get_source_path())
return bundle_name + '.activity'
@@ -82,7 +76,7 @@ def _get_install_dir(prefix):
return os.path.join(prefix, 'share/activities')
def _get_bundle_path():
- return os.path.join(_get_activities_path(), _get_bundle_dir())
+ return os.path.join(env.get_user_activities_dir(), _get_bundle_dir())
def _get_package_name():
bundle = Bundle(_get_source_path())
diff --git a/sugar/activity/bundleregistry.py b/sugar/activity/bundleregistry.py
index 8b7c44a..22a84e1 100644
--- a/sugar/activity/bundleregistry.py
+++ b/sugar/activity/bundleregistry.py
@@ -1,5 +1,6 @@
import os
from ConfigParser import ConfigParser
+import gobject
from sugar.activity.bundle import Bundle
from sugar import env
@@ -18,10 +19,17 @@ class _ServiceManager(object):
util.write_service(name, full_exec, self._path)
-class BundleRegistry:
+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()
@@ -54,10 +62,14 @@ class BundleRegistry:
bundle_dir = os.path.join(path, f)
if os.path.isdir(bundle_dir) and \
bundle_dir.endswith('.activity'):
- self._add_bundle(bundle_dir)
+ self.add_bundle(bundle_dir)
- def _add_bundle(self, bundle_path):
+ 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
diff --git a/sugar/env.py b/sugar/env.py
index 14d8d70..c0df585 100644
--- a/sugar/env.py
+++ b/sugar/env.py
@@ -84,3 +84,10 @@ def get_user_service_dir():
if not os.path.isdir(service_dir):
os.makedirs(service_dir)
return service_dir
+
+def get_user_activities_dir():
+ path = os.path.expanduser('~/Activities')
+ if not os.path.isdir(path):
+ os.mkdir(path)
+ return path
+
diff --git a/tools/Makefile.am b/tools/Makefile.am
index c4cd3bb..fb3f598 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1 +1,2 @@
-bin_SCRIPTS = sugar-setup-activity
+bin_SCRIPTS = sugar-install-bundle \
+ sugar-setup-activity
diff --git a/tools/sugar-install-bundle b/tools/sugar-install-bundle
new file mode 100755
index 0000000..0945c29
--- /dev/null
+++ b/tools/sugar-install-bundle
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+import sys
+import os
+import zipfile
+import dbus
+
+from sugar import env
+
+DBUS_SERVICE = "org.laptop.Shell"
+DBUS_PATH = "/org/laptop/Shell"
+
+# We check here that all the files in the .xo are inside one only dir (bundle_root_dir).
+def get_bundle_root_dir(file_names):
+ bundle_root_dir = None
+ for file_name in file_names:
+ if not bundle_root_dir:
+ bundle_root_dir = file_name.partition('/')[0]
+ if not bundle_root_dir.endswith('.activity'):
+ raise 'Incorrect bundle.'
+ else:
+ if not file_name.startswith(bundle_root_dir):
+ raise 'Incorrect bundle.'
+
+ return bundle_root_dir
+
+bus = dbus.SessionBus()
+proxy_obj = bus.get_object(DBUS_SERVICE, DBUS_PATH)
+dbus_service = dbus.Interface(proxy_obj, DBUS_SERVICE)
+
+bundle_dir = env.get_user_activities_dir()
+
+zip_file = zipfile.ZipFile(sys.argv[1])
+file_names = zip_file.namelist()
+bundle_root_dir = get_bundle_root_dir(file_names)
+bundle_path = os.path.join(bundle_dir, bundle_root_dir)
+
+# FIXME: we need to support installing different versions of the same bundle.
+if os.path.exists(bundle_path):
+ raise IOError, 'This bundle is already installed as ' + bundle_path
+
+if os.spawnlp(os.P_WAIT, 'unzip', 'unzip', sys.argv[1], '-d', bundle_dir):
+ raise RuntimeError, 'An error occurred while extracting the .xo contents.'
+
+# notify shell of new bundle
+if not dbus_service.add_bundle(bundle_path):
+ # error, let's delete the just expanded bundle.
+ for root, dirs, files in os.walk(bundle_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(bundle_path)
+
+ raise RuntimeError, 'Bundle is not well-formed.'
+
+print "%s: '%s' installed." % (sys.argv[0], sys.argv[1])