Added new tool sugar-install-bundle.
This commit is contained in:
parent
37c6c1e9fa
commit
9d13a9836d
@ -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')
|
||||
|
19
shell/shellservice.py
Normal file
19
shell/shellservice.py
Normal file
@ -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)
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
bin_SCRIPTS = sugar-setup-activity
|
||||
bin_SCRIPTS = sugar-install-bundle \
|
||||
sugar-setup-activity
|
||||
|
56
tools/sugar-install-bundle
Executable file
56
tools/sugar-install-bundle
Executable file
@ -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])
|
Loading…
Reference in New Issue
Block a user