| 
									
										
										
										
											2007-01-27 12:54:56 +01:00
										 |  |  | #!/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: | 
					
						
							| 
									
										
										
										
											2007-02-25 18:03:17 +01:00
										 |  |  |             bundle_root_dir = file_name.split('/')[0] | 
					
						
							| 
									
										
										
										
											2007-01-27 12:54:56 +01:00
										 |  |  |             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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-09 14:57:54 +01:00
										 |  |  | bundle_dir = env.get_user_activities_path() | 
					
						
							| 
									
										
										
										
											2007-03-18 13:48:34 +01:00
										 |  |  | if not os.path.isdir(bundle_dir): | 
					
						
							|  |  |  |     os.mkdir(bundle_dir) | 
					
						
							| 
									
										
										
										
											2007-01-27 12:54:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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]) |