57 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			57 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #!/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]) |