Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/bin/sugar-install-bundle
blob: 359c1c06532da16575885eccf46598dfb7b0b912 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/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.split('/')[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_path()
if not os.path.isdir(bundle_dir):
    os.mkdir(bundle_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])