def install(self, bundle, uid=None, force_downgrade=False): activities_path = env.get_user_activities_path() for installed_bundle in self._bundles: if bundle.get_bundle_id() == installed_bundle.get_bundle_id() and \ NormalizedVersion(bundle.get_activity_version()) <= \ NormalizedVersion(installed_bundle.get_activity_version()): if not force_downgrade: raise AlreadyInstalledException else: self.uninstall(installed_bundle, force=True) elif bundle.get_bundle_id() == installed_bundle.get_bundle_id(): self.uninstall(installed_bundle, force=True) install_dir = env.get_user_activities_path() if isinstance(bundle, JournalEntryBundle): install_path = bundle.install(uid) elif isinstance(bundle, ContentBundle): install_path = bundle.install() else: install_path = bundle.install(install_dir) # TODO treat ContentBundle in special way # needs rethinking while fixing ContentBundle support if isinstance(bundle, ContentBundle) or \ isinstance(bundle, JournalEntryBundle): pass elif not self.add_bundle(install_path): raise RegistrationException
def get_environment(activity): environ = os.environ.copy() bin_path = os.path.join(activity.get_path(), 'bin') activity_root = env.get_profile_path(activity.get_bundle_id()) if not os.path.exists(activity_root): os.mkdir(activity_root) data_dir = os.path.join(activity_root, 'instance') if not os.path.exists(data_dir): os.mkdir(data_dir) data_dir = os.path.join(activity_root, 'data') if not os.path.exists(data_dir): os.mkdir(data_dir) tmp_dir = os.path.join(activity_root, 'tmp') if not os.path.exists(tmp_dir): os.mkdir(tmp_dir) environ['SUGAR_BUNDLE_PATH'] = activity.get_path() environ['SUGAR_BUNDLE_ID'] = activity.get_bundle_id() environ['SUGAR_ACTIVITY_ROOT'] = activity_root environ['PATH'] = bin_path + ':' + environ['PATH'] if activity.get_path().startswith(env.get_user_activities_path()): environ['SUGAR_LOCALEDIR'] = os.path.join(activity.get_path(), 'locale') return environ
def __init__(self): logging.debug('STARTUP: Loading the bundle registry') gobject.GObject.__init__(self) self._mime_defaults = self._load_mime_defaults() self._bundles = [] # hold a reference to the monitors so they don't get disposed self._gio_monitors = [] user_path = env.get_user_activities_path() for activity_dir in [user_path, config.activities_path]: self._scan_directory(activity_dir) directory = gio.File(activity_dir) monitor = directory.monitor_directory() monitor.connect('changed', self.__file_monitor_changed_cb) self._gio_monitors.append(monitor) self._last_defaults_mtime = -1 self._favorite_bundles = {} client = gconf.client_get_default() self._protected_activities = client.get_list( '/desktop/sugar/protected_activities', gconf.VALUE_STRING) if self._protected_activities is None: self._protected_activities = [] try: self._load_favorites() except Exception: logging.exception('Error while loading favorite_activities.') self._merge_default_favorites()
def _get_temp_file_path(self, uri): # TODO: Should we use the HTTP headers for the file name? scheme_, netloc_, path, params_, query_, fragment_ = \ urlparse(uri) path = os.path.basename(path) if not os.path.exists(env.get_user_activities_path()): os.makedirs(env.get_user_activities_path()) base_name, extension_ = os.path.splitext(path) fd, file_path = tempfile.mkstemp(dir=env.get_user_activities_path(), prefix=base_name, suffix='.xo') os.close(fd) os.unlink(file_path) return file_path
def generate_bundle(nick, new_basename): """Generate a new .xo bundle for the activity and copy it into the Journal. """ new_activity_name = _customize_activity_info( nick, new_basename) user_activities_path = get_user_activities_path() if os.path.exists(os.path.join(user_activities_path, new_basename, 'dist')): for path in glob.glob(os.path.join(user_activities_path, new_basename, 'dist', '*')): os.remove(path) config = bundlebuilder.Config(source_dir=os.path.join( user_activities_path, new_basename), dist_name='%s-1.xo' % (new_activity_name)) bundlebuilder.cmd_dist_xo(config, None) dsobject = datastore.create() dsobject.metadata['title'] = '%s-1.xo' % (new_activity_name) dsobject.metadata['mime_type'] = 'application/vnd.olpc-sugar' dsobject.set_file_path(os.path.join( user_activities_path, new_basename, 'dist', '%s-1.xo' % (new_activity_name))) datastore.write(dsobject) dsobject.destroy()
def test(self): try: from sugar import env print(u"Activities: %s" % env.get_user_activities_path()) except Exception as e: print(u"oops: %r" % e)
def install(self, install_dir=None): if install_dir is None: install_dir = env.get_user_activities_path() self._unzip(install_dir) install_path = os.path.join(install_dir, self._zip_root_dir) self.install_mime_type(install_path) return install_path
def __copy_to_home_cb(self, menu_item): """Make a local copy of the activity bundle in user_activities_path""" user_activities_path = get_user_activities_path() nick = customizebundle.generate_unique_id() new_basename = '%s_copy_of_%s' % ( nick, os.path.basename(self._document_path)) if not os.path.exists(os.path.join(user_activities_path, new_basename)): shutil.copytree(self._document_path, os.path.join(user_activities_path, new_basename), symlinks=True) customizebundle.generate_bundle(nick, new_basename) else: _logger.debug('%s already exists', new_basename)
def get_bundle(bundle_id): if not _bundles: dirs = [] try: from jarabe import config dirs.append(config.activities_path) except ImportError: if os.environ.has_key('SUGAR_ACTIVITIES'): dirs.extend(os.environ['SUGAR_ACTIVITIES'].split(':')) for i in dirs + [env.get_user_activities_path()]: _scan_directory(i) return _bundles.get(bundle_id)
def _customize_activity_info(nick, new_basename): """Modify bundle_id in new activity.info file: (1) change the bundle_id to bundle_id_[NICKNAME]; (2) change the activity_icon [NICKNAME]-activity-icon.svg; (3) set activity_version to 1; (4) modify the activity icon by applying a customize overlay. """ new_activity_name = '' user_activities_path = get_user_activities_path() info_old = open(os.path.join(user_activities_path, new_basename, 'activity', 'activity.info'), 'r') info_new = open(os.path.join(user_activities_path, new_basename, 'activity', 'new_activity.info'), 'w') for line in info_old: if line.find('=') < 0: info_new.write(line) continue name, value = [token.strip() for token in line.split('=', 1)] if name == 'bundle_id': new_value = '%s_%s' % (value, nick) elif name == 'activity_version': new_value = '1' elif name == 'icon': new_value = value icon_name = value elif name == 'name': new_value = '%s_copy_of_%s' % (nick, value) new_activity_name = new_value else: info_new.write(line) continue info_new.write('%s = %s\n' % (name, new_value)) info_old.close() info_new.close() os.rename(os.path.join(user_activities_path, new_basename, 'activity', 'new_activity.info'), os.path.join(user_activities_path, new_basename, 'activity', 'activity.info')) _create_custom_icon(new_basename, icon_name) return new_activity_name
def _create_custom_icon(new_basename, icon_name): """Modify activity icon by overlaying a badge: (1) Extract the payload from the badge icon; (2) Add a transform to resize it and position it; (3) Insert it into the activity icon. """ user_activities_path = get_user_activities_path() badge_path = None for path in gtk.icon_theme_get_default().get_search_path(): if os.path.exists(os.path.join(path, 'sugar', 'scalable', BADGE_SUBPATH)): badge_path = path break if badge_path is None: _logger.debug('%s not found', BADGE_SUBPATH) return badge_fd = open(os.path.join(badge_path, 'sugar', 'scalable', BADGE_SUBPATH), 'r') badge_payload = _extract_svg_payload(badge_fd) badge_fd.close() badge_svg = BADGE_TRANSFORM + badge_payload + '\n</g>' icon_path = os.path.join(user_activities_path, new_basename, 'activity', icon_name + '.svg') icon_fd = open(icon_path, 'r') icon_payload = _extract_svg_payload(icon_fd) icon_fd.close() icon_svg = ICON_TRANSFORM + icon_payload + '\n</g>' tmp_path = os.path.join(user_activities_path, new_basename, 'activity', 'tmp.svg') tmp_icon_fd = open(tmp_path, 'w') tmp_icon_fd.write(XML_HEADER) tmp_icon_fd.write(SVG_START) tmp_icon_fd.write(icon_svg) tmp_icon_fd.write(badge_svg) tmp_icon_fd.write(SVG_END) tmp_icon_fd.close() os.remove(icon_path) os.rename(tmp_path, icon_path)
def cmd_dev(config, args): """Setup for development""" if args: print 'Usage: %prog dev' return bundle_path = env.get_user_activities_path() if not os.path.isdir(bundle_path): os.mkdir(bundle_path) bundle_path = os.path.join(bundle_path, config.bundle_root_dir) try: os.symlink(config.source_dir, bundle_path) except OSError: if os.path.islink(bundle_path): print 'ERROR - The bundle has been already setup for development.' else: print 'ERROR - A bundle with the same name is already installed.'
def install(self, install_dir=None, strict_manifest=False): if install_dir is None: install_dir = env.get_user_activities_path() self._unzip(install_dir) install_path = os.path.join(install_dir, self._zip_root_dir) # List installed files manifestfiles = self.get_files(self._raw_manifest()) paths = [] for root, dirs_, files in os.walk(install_path): rel_path = root[len(install_path) + 1:] for f in files: paths.append(os.path.join(rel_path, f)) # Check the list against the MANIFEST for path in paths: if path in manifestfiles: manifestfiles.remove(path) elif path != "MANIFEST": logging.warning("Bundle %s: %s not in MANIFEST"% (self._name,path)) if strict_manifest: os.remove(os.path.join(install_path, path)) # Is anything in MANIFEST left over after accounting for all files? if manifestfiles: err = ("Bundle %s: files in MANIFEST not included: %s"% (self._name,str(manifestfiles))) if strict_manifest: raise MalformedBundleException(err) else: logging.warning(err) self.install_mime_type(install_path) return install_path
def get_environment(activity): environ = os.environ.copy() bin_path = os.path.join(activity.get_path(), 'bin') activity_root = env.get_profile_path(activity.get_bundle_id()) if not os.path.exists(activity_root): os.mkdir(activity_root) data_dir = os.path.join(activity_root, 'instance') if not os.path.exists(data_dir): os.mkdir(data_dir) data_dir = os.path.join(activity_root, 'data') if not os.path.exists(data_dir): os.mkdir(data_dir) tmp_dir = os.path.join(activity_root, 'tmp') if not os.path.exists(tmp_dir): os.mkdir(tmp_dir) environ['SUGAR_BUNDLE_PATH'] = activity.get_path() environ['SUGAR_BUNDLE_ID'] = activity.get_bundle_id() environ['SUGAR_ACTIVITY_ROOT'] = activity_root environ['PATH'] = bin_path + ':' + environ['PATH'] #environ['RAINBOW_STRACE_LOG'] = '1' if activity.get_path().startswith(env.get_user_activities_path()): environ['SUGAR_LOCALEDIR'] = os.path.join(activity.get_path(), 'locale') if activity.get_bundle_id() in [ 'org.laptop.WebActivity', 'org.laptop.GmailActivity', 'org.laptop.WikiBrowseActivity' ]: environ['RAINBOW_CONSTANT_UID'] = 'yes' return environ
def is_user_activity(self): return self.get_path().startswith(env.get_user_activities_path())