def _update_invite_menu(self, activity): buddy_activity = self._buddy.props.current_activity if buddy_activity is not None: buddy_activity_id = buddy_activity.activity_id else: buddy_activity_id = None self._invite_menu.hide() if activity is None or \ activity.is_journal() or \ activity.get_activity_id() == buddy_activity_id: return bundle_activity = ActivityBundle(activity.get_bundle_path()) if bundle_activity.get_max_participants() > 1: title = activity.get_title() self._invite_menu.set_label(_('Invite to %s') % title) icon = Icon(file=activity.get_icon_path(), pixel_size=style.SMALL_ICON_SIZE) icon.props.xo_color = activity.get_icon_color() self._invite_menu.set_image(icon) icon.show() self._invite_menu.show()
def get_icon_name(metadata): file_name = None bundle_id = metadata.get("activity", "") if not bundle_id: bundle_id = metadata.get("bundle_id", "") if bundle_id: activity_info = bundleregistry.get_registry().get_bundle(bundle_id) if activity_info: file_name = activity_info.get_icon() if file_name is None and is_activity_bundle(metadata): file_path = model.get_file(metadata["uid"]) if file_path is not None and os.path.exists(file_path): try: bundle = ActivityBundle(file_path) file_name = bundle.get_icon() except Exception: logging.exception("Could not read bundle") if file_name is None: file_name = _get_icon_for_mime(metadata.get("mime_type", "")) if file_name is None: file_name = get_icon_file_name("application-octet-stream") return file_name
def get_icon_name(metadata): file_name = None bundle_id = metadata.get('activity', '') if not bundle_id: bundle_id = metadata.get('bundle_id', '') if bundle_id: activity_info = bundleregistry.get_registry().get_bundle(bundle_id) if activity_info: file_name = activity_info.get_icon() if file_name is None and is_activity_bundle(metadata): file_path = model.get_file(metadata['uid']) if file_path is not None and os.path.exists(file_path): try: bundle = ActivityBundle(file_path) file_name = bundle.get_icon() except Exception: logging.exception('Could not read bundle') if file_name is None: file_name = _get_icon_for_mime(metadata.get('mime_type', '')) if file_name is None: file_name = get_icon_file_name('application-octet-stream') return file_name
def _create_activity_icon(metadata): if metadata.get('icon-color', ''): color = XoColor(metadata['icon-color']) else: color = XoColor() from sugar3.activity.activity import get_bundle_path bundle = ActivityBundle(get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) return icon
def _create_activity_icon(metadata): if metadata is not None and metadata.get('icon-color'): color = XoColor(metadata['icon-color']) else: client = GConf.Client.get_default() color = XoColor(client.get_string('/desktop/sugar/user/color')) from sugar3.activity.activity import get_bundle_path bundle = ActivityBundle(get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) return icon
def _create_activity_icon(metadata): if metadata.get('icon-color', ''): color = XoColor(metadata['icon-color']) else: client = GConf.Client.get_default() color = XoColor(client.get_string('/desktop/sugar/user/color')) from sugar3.activity.activity import get_bundle_path bundle = ActivityBundle(get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) return icon
def __init__(self, title, message, button_callback): Gtk.EventBox.__init__(self) self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) alignment = Gtk.Alignment.new(0.5, 0.5, 0.1, 0.1) self.add(alignment) alignment.show() box = Gtk.VBox() alignment.add(box) box.show() # Get the icon of this activity through the bundle path. bundle_path = activity.get_bundle_path() activity_bundle = ActivityBundle(bundle_path) icon = Icon( pixel_size=style.LARGE_ICON_SIZE, file=activity_bundle.get_icon(), stroke_color=style.COLOR_BUTTON_GREY.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg(), ) box.pack_start(icon, expand=True, fill=False, padding=0) icon.show() color = style.COLOR_BUTTON_GREY.get_html() label = Gtk.Label() label.set_markup('<span weight="bold" color="%s">%s</span>' % (color, GLib.markup_escape_text(title))) box.pack_start(label, expand=True, fill=False, padding=0) label.show() label = Gtk.Label() label.set_markup('<span color="%s">%s</span>' % (color, GLib.markup_escape_text(message))) box.pack_start(label, expand=True, fill=False, padding=0) label.show() button_box = Gtk.HButtonBox() button_box.set_layout(Gtk.ButtonBoxStyle.CENTER) box.pack_start(button_box, False, True, 0) button_box.show() button = Gtk.Button(label=_("Try again")) button.connect("clicked", button_callback) button.props.image = Icon( icon_name="entry-refresh", pixel_size=style.SMALL_ICON_SIZE, stroke_color=style.COLOR_WHITE.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg(), ) button_box.pack_start(button, expand=True, fill=False, padding=0) button.show()
def __init__(self, title, message, button_callback): Gtk.EventBox.__init__(self) self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) alignment = Gtk.Alignment.new(0.5, 0.5, 0.1, 0.1) self.add(alignment) alignment.show() box = Gtk.VBox() alignment.add(box) box.show() # Get the icon of this activity through the bundle path. bundle_path = activity.get_bundle_path() activity_bundle = ActivityBundle(bundle_path) icon = Icon(pixel_size=style.LARGE_ICON_SIZE, file=activity_bundle.get_icon(), stroke_color=style.COLOR_BUTTON_GREY.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) box.pack_start(icon, expand=True, fill=False, padding=0) icon.show() color = style.COLOR_BUTTON_GREY.get_html() label = Gtk.Label() label.set_markup('<span weight="bold" color="%s">%s</span>' % ( color, GLib.markup_escape_text(title))) box.pack_start(label, expand=True, fill=False, padding=0) label.show() label = Gtk.Label() label.set_markup('<span color="%s">%s</span>' % ( color, GLib.markup_escape_text(message))) box.pack_start(label, expand=True, fill=False, padding=0) label.show() button_box = Gtk.HButtonBox() button_box.set_layout(Gtk.ButtonBoxStyle.CENTER) box.pack_start(button_box, False, True, 0) button_box.show() button = Gtk.Button(label=_('Try again')) button.connect('clicked', button_callback) button.props.image = Icon(icon_name='entry-refresh', pixel_size=style.SMALL_ICON_SIZE, stroke_color=style.COLOR_WHITE.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) button_box.pack_start(button, expand=True, fill=False, padding=0) button.show()
def _setup_activity(self): if 'SUGAR_BUNDLE_PATH' not in os.environ: _logger.error("SUGAR_BUNDLE_PATH must be set to run application") sys.exit(1) bundle_path = os.environ['SUGAR_BUNDLE_PATH'] sys.path.insert(0, bundle_path) try: bundle = ActivityBundle(bundle_path) except MalformedBundleException as e: _logger.error(e) sys.exit(1) activity_root = GLib.get_user_data_dir() subdirs = [ os.path.join(activity_root, 'tmp'), os.path.join(activity_root, 'data'), os.path.join(activity_root, 'instance'), ] for subdir in subdirs: try: os.makedirs(subdir) except: pass os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_ACTIVITY_ROOT'] = activity_root os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() os.environ['SUGAR_BUNDLE_VERSION'] = str(bundle.get_activity_version()) locale_path = config.locale_path gettext.bindtextdomain(bundle.get_bundle_id(), locale_path) gettext.bindtextdomain('sugar-toolkit-gtk3', config.locale_path) gettext.textdomain(bundle.get_bundle_id()) activity_class = bundle.get_command().split(" ")[1] splitted_module = activity_class.rsplit('.', 1) module_name = splitted_module[0] class_name = splitted_module[1] module = __import__(module_name) for component in module_name.split('.')[1:]: module = getattr(module, component) constructor = getattr(module, class_name) handle = ActivityHandle(activity_id=bundle.get_bundle_id(), uri=self._path) os.chdir(bundle_path) activity = constructor(handle) activity.connect('closing', self._quit) activity.show() return activity
def process_dir(activity_path): for dir_name in sorted(os.listdir(activity_path)): bundles_installed = [] if dir_name.endswith('.activity'): bundle_dir = os.path.join(activity_path, dir_name) bundle = ActivityBundle(bundle_dir) bundles_installed.append(bundle) item = MenuItem(file_name=bundle.get_icon(), xo_color=xocolor.XoColor()) item.set_label(bundle.get_name()) item.set_reserve_indicator(True) item.set_submenu(self.make_submenu(bundle)) self.menu.append(item)
def notify_user(self, summary, body): """ Display a notification with the given summary and body. The notification will go under the activities icon in the frame. """ bundle = ActivityBundle(get_bundle_path()) icon = bundle.get_icon() bus = dbus.SessionBus() notify_obj = bus.get_object(N_BUS_NAME, N_OBJ_PATH) notifications = dbus.Interface(notify_obj, N_IFACE_NAME) notifications.Notify(self.get_id(), 0, '', summary, body, [], {'x-sugar-icon-file-name': icon}, -1)
def get_help_url_and_title(activity): """ Returns the help document name and the title to display, or None if not content is available. """ bundle_path = activity.get_bundle_path() if bundle_path is None: shell_model = shell.get_model() zoom_level = shell_model.zoom_level if zoom_level == shell_model.ZOOM_MESH: title = _('Mesh') link_id = 'mesh_view' elif zoom_level == shell_model.ZOOM_GROUP: title = _('Group') link_id = 'group_view' elif zoom_level == shell_model.ZOOM_HOME: title = _('Home') link_id = 'home_view' else: title = _('Journal') link_id = 'org.laptop.JournalActivity' else: # get activity name and window id activity_bundle = ActivityBundle(bundle_path) title = activity_bundle.get_name() link_id = activity_bundle.get_bundle_id() # get the help file name for the activity activity_path = _get_help_activity_path() if activity_path is None: return None help_content_link = os.path.join(activity_path, 'helplink.json') if not os.path.exists(help_content_link): _logger.error('Help activity not installed or json file not found') return None links = None try: with open(help_content_link) as json_file: links = json.load(json_file) except IOError: _logger.error('helplink.json malformed, or can\'t be read') if links: if link_id in links.keys(): return (links[link_id], title) return None
def get_help_url_and_title(activity): """ Returns the help document name and the title to display, or None if not content is available. """ bundle_path = activity.get_bundle_path() if bundle_path is None: shell_model = shell.get_model() zoom_level = shell_model.zoom_level if zoom_level == shell_model.ZOOM_MESH: title = _("Mesh") link_id = "mesh_view" elif zoom_level == shell_model.ZOOM_GROUP: title = _("Group") link_id = "group_view" elif zoom_level == shell_model.ZOOM_HOME: title = _("Home") link_id = "home_view" else: title = _("Journal") link_id = "org.laptop.JournalActivity" else: # get activity name and window id activity_bundle = ActivityBundle(bundle_path) title = activity_bundle.get_name() link_id = activity_bundle.get_bundle_id() # get the help file name for the activity activity_path = _get_help_activity_path() if activity_path is None: return None help_content_link = os.path.join(activity_path, "helplink.json") if not os.path.exists(help_content_link): _logger.error("Help activity not installed or json file not found") return None links = None try: with open(help_content_link) as json_file: links = json.load(json_file) except IOError: _logger.error("helplink.json malformed, or can't be read") if links: if link_id in links.keys(): return (links[link_id], title) return None
def get_bundle(metadata): try: if is_activity_bundle(metadata): file_path = model.get_file(metadata['uid']) if not os.path.exists(file_path): logging.warning('Invalid path: %r', file_path) return None return ActivityBundle(file_path) elif is_content_bundle(metadata): file_path = model.get_file(metadata['uid']) if not os.path.exists(file_path): logging.warning('Invalid path: %r', file_path) return None return ContentBundle(file_path) elif is_journal_bundle(metadata): file_path = model.get_file(metadata['uid']) if not os.path.exists(file_path): logging.warning('Invalid path: %r', file_path) return None return JournalEntryBundle(file_path) else: return None except Exception: logging.exception('Incorrect bundle') return None
def __init__(self, handle): "The entry point to the Activity" activity.Activity.__init__(self, handle, False) self.max_participants = 1 self._sequence = 0 self.selected_book = None self.queryresults = None self._getter = None self.show_images = True self.languages = {} self._lang_code_handler = languagenames.LanguageNames() self.catalogs_configuration = {} self.catalog_history = [] if os.path.exists('/etc/get-books.cfg'): self._read_configuration('/etc/get-books.cfg') else: self._read_configuration() toolbar_box = ToolbarBox() activity_button = ToolButton() color = profile.get_color() bundle = ActivityBundle(activity.get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) activity_button.set_icon_widget(icon) activity_button.show() toolbar_box.toolbar.insert(activity_button, 0) self._add_search_controls(toolbar_box.toolbar) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) toolbar_box.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self._books_toolbar = toolbar_box.toolbar self._create_controls() self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK) self.__book_downloader = self.__image_downloader = None
def bundle_from_dir(path): """ Return an appropriate Bundle object for a given directory containing an unzipped bundle. """ if os.path.exists(os.path.join(path, 'activity', 'activity.info')): return ActivityBundle(path) elif os.path.exists(os.path.join(path, 'library', 'library.info')): return ContentBundle(path) return None
def _main(): """Launch this activity from the command line.""" ab = ActivityBundle(os.path.dirname(__file__) or '.') ai = ActivityInfo(name=ab.get_name(), icon=None, bundle_id=ab.get_bundle_id(), version=ab.get_activity_version(), path=ab.get_path(), show_launcher=ab.get_show_launcher(), command=ab.get_command(), favorite=True, installation_time=ab.get_installation_time(), position_x=0, position_y=0) env = activityfactory.get_environment(ai) cmd_args = activityfactory.get_command(ai) os.execvpe(cmd_args[0], cmd_args, env)
def update(self): self.bundle = bundle = ActivityBundle(self.source_dir, translated=False) self.version = bundle.get_activity_version() self.activity_name = bundle.get_name() self.bundle_id = bundle.get_bundle_id() self.summary = bundle.get_summary() self.bundle_name = reduce(operator.add, self.activity_name.split()) self.bundle_root_dir = self.bundle_name + '.activity' self.tar_root_dir = '%s-%s' % (self.bundle_name, self.version) self.xo_name = '%s-%s.xo' % (self.bundle_name, self.version) self.tar_name = '%s-%s.tar.bz2' % (self.bundle_name, self.version)
def resume(metadata, bundle_id=None): registry = bundleregistry.get_registry() if is_activity_bundle(metadata) and bundle_id is None: logging.debug("Creating activity bundle") file_path = model.get_file(metadata["uid"]) bundle = ActivityBundle(file_path) if not registry.is_installed(bundle): logging.debug("Installing activity bundle") try: registry.install(bundle) except AlreadyInstalledException: _downgrade_option_alert(bundle) return else: logging.debug("Upgrading activity bundle") registry.upgrade(bundle) _launch_bundle(bundle) elif is_content_bundle(metadata) and bundle_id is None: logging.debug("Creating content bundle") file_path = model.get_file(metadata["uid"]) bundle = ContentBundle(file_path) if not bundle.is_installed(): logging.debug("Installing content bundle") bundle.install() activities = _get_activities_for_mime("text/html") if len(activities) == 0: logging.warning("No activity can open HTML content bundles") return uri = bundle.get_start_uri() logging.debug("activityfactory.creating with uri %s", uri) activity_bundle = registry.get_bundle(activities[0].get_bundle_id()) launch(activity_bundle, uri=uri) else: activity_id = metadata.get("activity_id", "") if bundle_id is None: activities = get_activities(metadata) if not activities: logging.warning("No activity can open this object, %s.", metadata.get("mime_type", None)) return bundle_id = activities[0].get_bundle_id() bundle = registry.get_bundle(bundle_id) if metadata.get("mountpoint", "/") == "/": object_id = metadata["uid"] else: object_id = model.copy(metadata, "/") launch(bundle, activity_id=activity_id, object_id=object_id, color=get_icon_color(metadata))
def bundle_from_archive(path, mime_type=None): """ Return an appropriate Bundle object for a given file path. The bundle type is identified by mime_type, which is guessed if not provided. """ if mime_type is None: mime_type, certainty = Gio.content_type_guess(path, data=None) if mime_type == ActivityBundle.MIME_TYPE: return ActivityBundle(path) elif mime_type == ContentBundle.MIME_TYPE: return ContentBundle(path) return None
def _add_bundle(self, bundle_path, install_mime_type=False): logging.debug('STARTUP: Adding bundle %r', bundle_path) try: bundle = ActivityBundle(bundle_path) if install_mime_type: bundle.install_mime_type(bundle_path) except MalformedBundleException: logging.exception('Error loading bundle %r', bundle_path) return None bundle_id = bundle.get_bundle_id() installed = self.get_bundle(bundle_id) if installed is not None: if NormalizedVersion(installed.get_activity_version()) >= \ NormalizedVersion(bundle.get_activity_version()): logging.debug('Skip old version for %s', bundle_id) return None else: logging.debug('Upgrade %s', bundle_id) self.remove_bundle(installed.get_path()) self._bundles.append(bundle) return bundle
exec 'reload(%s)' % debugee_module """ if this were to work properly we should set go equal to object Macro go_cmd = 'run -d -b %s %s'%(os.path.join(db.pydebug_path,'bin','start_debug.py'),child_path) _logger.debug('defining go: %s'%go_cmd) ip.user_ns['go'] = go_cmd """ _logger.debug('pydebug home: %s' % db.debugger_home) os.environ['PYDEBUG_HOME'] = pydebug_home os.chdir(child_path) os.environ['SUGAR_BUNDLE_PATH'] = child_path _logger.debug('sugar_bundle_path set to %s' % child_path) #set up python module search path sys.path.insert(0, child_path) bundle_info = ActivityBundle(child_path) bundle_id = bundle_info.get_bundle_id() #following two statements eliminate differences between sugar 0.82 and 0.84 bundle_info.path = child_path bundle_info.bundle_id = bundle_id bundle_name = bundle_info.get_name() os.environ['SUGAR_BUNDLE_NAME'] = bundle_name os.environ['SUGAR_BUNDLE_ID'] = bundle_id cmd_args = activityfactory.get_command(bundle_info) _logger.debug('command args:%r' % cmd_args) #need to get activity root, but activity bases off of HOME which some applications need to change #following will not work if storage system changes with new OS
def main(): usage = 'usage: %prog [options] [activity dir] [python class]' epilog = 'If you are running from a directory containing an Activity, ' \ 'the argument may be omitted. Otherwise please provide either '\ 'a directory containing a Sugar Activity [activity dir], a '\ '[python_class], or both.' parser = OptionParser(usage=usage, epilog=epilog) parser.add_option('-b', '--bundle-id', dest='bundle_id', help='identifier of the activity bundle') parser.add_option('-a', '--activity-id', dest='activity_id', help='identifier of the activity instance') parser.add_option('-o', '--object-id', dest='object_id', help='identifier of the associated datastore object') parser.add_option('-u', '--uri', dest='uri', help='URI to load') parser.add_option('-s', '--single-process', dest='single_process', action='store_true', help='start all the instances in the same process') parser.add_option('-i', '--invited', dest='invited', action='store_true', default=False, help='the activity is being launched for handling an ' 'invite from the network') (options, args) = parser.parse_args() logger.start() activity_class = None if len(args) == 2: activity_class = args[1] os.chdir(args[0]) elif len(args) == 1: if os.path.isdir(args[0]): os.chdir(args[0]) else: activity_class = args[0] bundle_path = os.path.abspath(os.curdir) sys.path.insert(0, bundle_path) try: bundle = ActivityBundle(bundle_path) except MalformedBundleException: parser.print_help() exit(0) if not activity_class: command = bundle.get_command() if command.startswith('sugar-activity'): if not command.startswith('sugar-activity3'): logging.warning("Activity written for Python 2," " consider porting to Python 3.") activity_class = command.split(" ")[1] # when an activity is started outside sugar, # activityfactory.get_environment has not executed in parent # process, so parts of get_environment must happen here. if 'SUGAR_BUNDLE_PATH' not in os.environ: profile_id = os.environ.get('SUGAR_PROFILE', 'default') home_dir = os.environ.get('SUGAR_HOME', os.path.expanduser('~/.sugar')) base = os.path.join(home_dir, profile_id) activity_root = os.path.join(base, bundle.get_bundle_id()) instance_dir = os.path.join(activity_root, 'instance') _makedirs(instance_dir) data_dir = os.path.join(activity_root, 'data') _makedirs(data_dir) tmp_dir = os.path.join(activity_root, 'tmp') _makedirs(tmp_dir) os.environ['SUGAR_BUNDLE_PATH'] = bundle_path os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_ACTIVITY_ROOT'] = activity_root os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() os.environ['SUGAR_BUNDLE_VERSION'] = str(bundle.get_activity_version()) # must be done early, some activities set translations globally, SL #3654 activity_locale_path = os.environ.get("SUGAR_LOCALEDIR", config.locale_path) gettext.bindtextdomain(bundle.get_bundle_id(), activity_locale_path) gettext.bindtextdomain('sugar-toolkit-gtk3', config.locale_path) gettext.textdomain(bundle.get_bundle_id()) splitted_module = activity_class.rsplit('.', 1) module_name = splitted_module[0] class_name = splitted_module[1] module = __import__(module_name) for comp in module_name.split('.')[1:]: module = getattr(module, comp) activity_constructor = getattr(module, class_name) if not options.activity_id: # Generate random hash data = '%s%s' % (time.time(), random.randint(10000, 100000)) random_hash = hashlib.sha1(data.encode()).hexdigest() options.activity_id = random_hash options.bundle_id = bundle.get_bundle_id() activity_handle = activityhandle.ActivityHandle( activity_id=options.activity_id, object_id=options.object_id, uri=options.uri, invited=options.invited) if options.single_process is True: sessionbus = dbus.SessionBus() service_name = get_single_process_name(options.bundle_id) service_path = get_single_process_path(options.bundle_id) bus_object = sessionbus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') try: name = bus_object.GetNameOwner( service_name, dbus_interface='org.freedesktop.DBus') except dbus.DBusException: name = None if not name: SingleProcess(service_name, activity_constructor) else: try: single_process = sessionbus.get_object(service_name, service_path) single_process.create( activity_handle.get_dict(), dbus_interface='org.laptop.SingleProcess') print('Created %s in a single process.' % service_name) sys.exit(0) except (TypeError, dbus.DBusException): print('Could not communicate with the instance process,' 'launching a new process') if hasattr(module, 'start'): module.start() instance = create_activity_instance(activity_constructor, activity_handle) if hasattr(instance, 'run_main_loop'): instance.run_main_loop()
try: name = bus_object.GetNameOwner(service_name, dbus_interface='org.freedesktop.DBus') except dbus.DBusException: name = None if not name: service = SingleProcess(service_name, constructor) else: single_process = bus.get_object(service_name, service_path) single_process.create(handle.get_dict()) print 'Created %s in a single process.' % service_name sys.exit(0) if hasattr(module, 'start'): module.start() bundle = ActivityBundle(bundle_path) os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() gettext.bindtextdomain(bundle.get_bundle_id(), bundle.get_locale_path()) gettext.textdomain(bundle.get_bundle_id()) Gtk.IconTheme.get_default().append_search_path(bundle.get_icons_path()) create_activity_instance(constructor, handle) Gtk.main()
go_cmd = 'run -d -b %s %s' % (os.path.join(db.pydebug_path, 'bin', 'start_debug.py'), child_path) _logger.debug('defining go: %s' % go_cmd) ip.user_ns['go'] = go_cmd _logger.debug('pydebug home: %s' % db.debugger_home) path = child_path pydebug_home = db.debugger_home os.environ['PYDEBUG_HOME'] = pydebug_home os.chdir(path) os.environ['SUGAR_BUNDLE_PATH'] = path _logger.debug('sugar_bundle_path set to %s' % path) #set up module search path sys.path.insert(0, path) activity = ActivityBundle(path) cmd_args = activityfactory.get_command(activity) _logger.debug('command args:%r' % cmd_args) bundle_name = activity.get_name() bundle_id = activity.get_bundle_id() #need to get activity root, but activity bases off of HOME which some applications need to change #following will not work if storage system changes with new OS #required because debugger needs to be able to change home so that foreign apps will work activity_root = os.path.join('/home/olpc/.sugar/default/', bundle_id) os.environ['SUGAR_ACTIVITY_ROOT'] = activity_root _logger.debug('sugar_activity_root set to %s' % activity_root) #following is useful for its side-effects info = activityfactory.get_environment(activity)
def _is_web_activity(bundle_path): activity_bundle = ActivityBundle(bundle_path) return activity_bundle.get_command() == 'sugar-activity-web'
def resume(metadata, bundle_id=None): registry = bundleregistry.get_registry() if is_activity_bundle(metadata) and bundle_id is None: logging.debug('Creating activity bundle') file_path = model.get_file(metadata['uid']) bundle = ActivityBundle(file_path) if not registry.is_installed(bundle): logging.debug('Installing activity bundle') try: registry.install(bundle) except AlreadyInstalledException: _downgrade_option_alert(bundle) return else: logging.debug('Upgrading activity bundle') registry.upgrade(bundle) _launch_bundle(bundle) elif is_content_bundle(metadata) and bundle_id is None: logging.debug('Creating content bundle') file_path = model.get_file(metadata['uid']) bundle = ContentBundle(file_path) if not bundle.is_installed(): logging.debug('Installing content bundle') bundle.install() activities = _get_activities_for_mime('text/html') if len(activities) == 0: logging.warning('No activity can open HTML content bundles') return uri = bundle.get_start_uri() logging.debug('activityfactory.creating with uri %s', uri) activity_bundle = registry.get_bundle(activities[0].get_bundle_id()) launch(activity_bundle, uri=uri) else: activity_id = metadata.get('activity_id', '') if bundle_id is None: activities = get_activities(metadata) if not activities: logging.warning('No activity can open this object, %s.', metadata.get('mime_type', None)) return bundle_id = activities[0].get_bundle_id() bundle = registry.get_bundle(bundle_id) if metadata.get('mountpoint', '/') == '/': object_id = metadata['uid'] else: object_id = model.copy(metadata, '/') launch(bundle, activity_id=activity_id, object_id=object_id, color=get_icon_color(metadata))
def refresh_files(self): """Refresh the treeview of activity files. """ self.bundle = ActivityBundle(self.activity_dir) self.activity_tree_view.load_activity(self.activity_dir, self.bundle)
def main(): parser = OptionParser() parser.add_option("-b", "--bundle-id", dest="bundle_id", help="identifier of the activity bundle") parser.add_option("-a", "--activity-id", dest="activity_id", help="identifier of the activity instance") parser.add_option("-o", "--object-id", dest="object_id", help="identifier of the associated datastore object") parser.add_option("-u", "--uri", dest="uri", help="URI to load") parser.add_option('-s', '--single-process', dest='single_process', action='store_true', help='start all the instances in the same process') (options, args) = parser.parse_args() logger.start() if 'SUGAR_BUNDLE_PATH' not in os.environ: print 'SUGAR_BUNDLE_PATH is not defined in the environment.' sys.exit(1) if len(args) == 0: print 'A python class must be specified as first argument.' sys.exit(1) bundle_path = os.environ['SUGAR_BUNDLE_PATH'] sys.path.append(bundle_path) bundle = ActivityBundle(bundle_path) os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() os.environ['SUGAR_BUNDLE_VERSION'] = str(bundle.get_activity_version()) Gtk.IconTheme.get_default().append_search_path(bundle.get_icons_path()) # This code can be removed when we grow an xsettings daemon (the GTK+ # init routines will then automatically figure out the font settings) settings = Gtk.Settings.get_default() settings.set_property('gtk-font-name', '%s %f' % (style.FONT_FACE, style.FONT_SIZE)) locale_path = None if 'SUGAR_LOCALEDIR' in os.environ: locale_path = os.environ['SUGAR_LOCALEDIR'] gettext.bindtextdomain(bundle.get_bundle_id(), locale_path) gettext.bindtextdomain('sugar-toolkit', sugar3.locale_path) gettext.textdomain(bundle.get_bundle_id()) splitted_module = args[0].rsplit('.', 1) module_name = splitted_module[0] class_name = splitted_module[1] module = __import__(module_name) for comp in module_name.split('.')[1:]: module = getattr(module, comp) activity_constructor = getattr(module, class_name) activity_handle = activityhandle.ActivityHandle( activity_id=options.activity_id, object_id=options.object_id, uri=options.uri) if options.single_process is True: sessionbus = dbus.SessionBus() service_name = get_single_process_name(options.bundle_id) service_path = get_single_process_path(options.bundle_id) bus_object = sessionbus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') try: name = bus_object.GetNameOwner( service_name, dbus_interface='org.freedesktop.DBus') except dbus.DBusException: name = None if not name: SingleProcess(service_name, activity_constructor) else: single_process = sessionbus.get_object(service_name, service_path) single_process.create(activity_handle.get_dict()) print 'Created %s in a single process.' % service_name sys.exit(0) if hasattr(module, 'start'): module.start() create_activity_instance(activity_constructor, activity_handle) from IPython.lib.inputhook import InputHookManager ihm = InputHookManager() ihm.enable_gtk()
def __init__(self, window_xid, bundle_path, document_path, sugar_toolkit_path, title): Gtk.Window.__init__(self) _logger.debug('ViewSource paths: %r %r %r', bundle_path, document_path, sugar_toolkit_path) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_border_width(style.LINE_WIDTH) self.set_has_resize_grip(False) width = Gdk.Screen.width() - style.GRID_CELL_SIZE * 2 height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 2 self.set_size_request(width, height) self._parent_window_xid = window_xid self._sugar_toolkit_path = sugar_toolkit_path self.connect('realize', self.__realize_cb) self.connect('destroy', self.__destroy_cb, document_path) self.connect('key-press-event', self.__key_press_event_cb) vbox = Gtk.VBox() self.add(vbox) vbox.show() toolbar = Toolbar(title, bundle_path, document_path, sugar_toolkit_path) vbox.pack_start(toolbar, False, True, 0) toolbar.connect('stop-clicked', self.__stop_clicked_cb) toolbar.connect('source-selected', self.__source_selected_cb) toolbar.show() pane = Gtk.HPaned() vbox.pack_start(pane, True, True, 0) pane.show() self._selected_bundle_file = None self._selected_sugar_file = None file_name = '' activity_bundle = ActivityBundle(bundle_path) command = activity_bundle.get_command() if len(command.split(' ')) > 1: name = command.split(' ')[1].split('.')[-1] tmppath = command.split(' ')[1].replace('.', '/') file_name = tmppath[0:-(len(name) + 1)] + '.py' path = os.path.join(activity_bundle.get_path(), file_name) self._selected_bundle_file = path # Split the tree pane into two vertical panes, one of which # will be hidden tree_panes = Gtk.VPaned() tree_panes.show() self._bundle_source_viewer = FileViewer(bundle_path, file_name) self._bundle_source_viewer.connect('file-selected', self.__file_selected_cb) tree_panes.add1(self._bundle_source_viewer) self._bundle_source_viewer.show() file_name = 'env.py' self._selected_sugar_file = os.path.join(sugar_toolkit_path, file_name) self._sugar_source_viewer = FileViewer(sugar_toolkit_path, file_name) self._sugar_source_viewer.connect('file-selected', self.__file_selected_cb) tree_panes.add2(self._sugar_source_viewer) self._sugar_source_viewer.hide() pane.add1(tree_panes) self._source_display = SourceDisplay() pane.add2(self._source_display) self._source_display.show() self._source_display.file_path = self._selected_bundle_file if document_path is not None: self._select_source(document_path)
def __init__(self, title, bundle_path, document_path, sugar_toolkit_path): Gtk.Toolbar.__init__(self) document_button = None self.bundle_path = bundle_path self.sugar_toolkit_path = sugar_toolkit_path self._add_separator() activity_bundle = ActivityBundle(bundle_path) file_name = activity_bundle.get_icon() if document_path is not None and os.path.exists(document_path): document_button = DocumentButton(file_name, document_path, title) document_button.connect('toggled', self.__button_toggled_cb, document_path) self.insert(document_button, -1) document_button.show() self._add_separator() if bundle_path is not None and os.path.exists(bundle_path): activity_button = DocumentButton(file_name, bundle_path, title, bundle=True) icon = Icon(file=file_name, icon_size=Gtk.IconSize.LARGE_TOOLBAR, fill_color=style.COLOR_TRANSPARENT.get_svg(), stroke_color=style.COLOR_WHITE.get_svg()) activity_button.set_icon_widget(icon) icon.show() if document_button is not None: activity_button.props.group = document_button activity_button.props.tooltip = _('Activity Bundle Source') activity_button.connect('toggled', self.__button_toggled_cb, bundle_path) self.insert(activity_button, -1) activity_button.show() self._add_separator() if sugar_toolkit_path is not None: sugar_button = RadioToolButton() icon = Icon(icon_name='computer-xo', icon_size=Gtk.IconSize.LARGE_TOOLBAR, fill_color=style.COLOR_TRANSPARENT.get_svg(), stroke_color=style.COLOR_WHITE.get_svg()) sugar_button.set_icon_widget(icon) icon.show() if document_button is not None: sugar_button.props.group = document_button else: sugar_button.props.group = activity_button sugar_button.props.tooltip = _('Sugar Toolkit Source') sugar_button.connect('toggled', self.__button_toggled_cb, sugar_toolkit_path) self.insert(sugar_button, -1) sugar_button.show() self._add_separator() self.activity_title_text = _('View source: %s') % title self.sugar_toolkit_title_text = _('View source: %r') % 'Sugar Toolkit' self.label = Gtk.Label() self.label.set_markup('<b>%s</b>' % self.activity_title_text) self.label.set_alignment(0, 0.5) self._add_widget(self.label) self._add_separator(True) stop = ToolButton(icon_name='dialog-cancel') stop.set_tooltip(_('Close')) stop.connect('clicked', self.__stop_clicked_cb) self.insert(stop, -1) stop.show()
def main(): usage = 'usage: %prog [options] [activity dir] [python class]' epilog = 'If you are running from a directory containing an Activity, ' \ 'the argument may be omitted. Otherwise please provide either '\ 'a directory containing a Sugar Activity [activity dir], a '\ '[python_class], or both.' parser = OptionParser(usage=usage, epilog=epilog) parser.add_option('-b', '--bundle-id', dest='bundle_id', help='identifier of the activity bundle') parser.add_option('-a', '--activity-id', dest='activity_id', help='identifier of the activity instance') parser.add_option('-o', '--object-id', dest='object_id', help='identifier of the associated datastore object') parser.add_option('-u', '--uri', dest='uri', help='URI to load') parser.add_option('-s', '--single-process', dest='single_process', action='store_true', help='start all the instances in the same process') parser.add_option('-i', '--invited', dest='invited', action='store_true', default=False, help='the activity is being launched for handling an ' 'invite from the network') (options, args) = parser.parse_args() logger.start() activity_class = None if len(args) == 2: activity_class = args[1] os.chdir(args[0]) elif len(args) == 1: if os.path.isdir(args[0]): os.chdir(args[0]) else: activity_class = args[0] bundle_path = os.path.abspath(os.curdir) sys.path.insert(0, bundle_path) try: bundle = ActivityBundle(bundle_path) except MalformedBundleException: parser.print_help() exit(0) if not activity_class: command = bundle.get_command() if command.startswith('sugar-activity'): if not command.startswith('sugar-activity3'): logging.warning("Activity written for Python 2, consider porting to Python 3.") activity_class = command.split(" ")[1] # when an activity is started outside sugar, # activityfactory.get_environment has not executed in parent # process, so parts of get_environment must happen here. if 'SUGAR_BUNDLE_PATH' not in os.environ: profile_id = os.environ.get('SUGAR_PROFILE', 'default') home_dir = os.environ.get('SUGAR_HOME', os.path.expanduser('~/.sugar')) base = os.path.join(home_dir, profile_id) activity_root = os.path.join(base, bundle.get_bundle_id()) instance_dir = os.path.join(activity_root, 'instance') _makedirs(instance_dir) data_dir = os.path.join(activity_root, 'data') _makedirs(data_dir) tmp_dir = os.path.join(activity_root, 'tmp') _makedirs(tmp_dir) os.environ['SUGAR_BUNDLE_PATH'] = bundle_path os.environ['SUGAR_BUNDLE_ID'] = bundle.get_bundle_id() os.environ['SUGAR_ACTIVITY_ROOT'] = activity_root os.environ['SUGAR_BUNDLE_NAME'] = bundle.get_name() os.environ['SUGAR_BUNDLE_VERSION'] = str(bundle.get_activity_version()) # must be done early, some activities set translations globally, SL #3654 activity_locale_path = os.environ.get("SUGAR_LOCALEDIR", config.locale_path) gettext.bindtextdomain(bundle.get_bundle_id(), activity_locale_path) gettext.bindtextdomain('sugar-toolkit-gtk3', config.locale_path) gettext.textdomain(bundle.get_bundle_id()) splitted_module = activity_class.rsplit('.', 1) module_name = splitted_module[0] class_name = splitted_module[1] module = __import__(module_name) for comp in module_name.split('.')[1:]: module = getattr(module, comp) activity_constructor = getattr(module, class_name) if not options.activity_id: # Generate random hash data = '%s%s' % (time.time(), random.randint(10000, 100000)) random_hash = hashlib.sha1(data.encode()).hexdigest() options.activity_id = random_hash options.bundle_id = bundle.get_bundle_id() activity_handle = activityhandle.ActivityHandle( activity_id=options.activity_id, object_id=options.object_id, uri=options.uri, invited=options.invited) if options.single_process is True: sessionbus = dbus.SessionBus() service_name = get_single_process_name(options.bundle_id) service_path = get_single_process_path(options.bundle_id) bus_object = sessionbus.get_object( 'org.freedesktop.DBus', '/org/freedesktop/DBus') try: name = bus_object.GetNameOwner( service_name, dbus_interface='org.freedesktop.DBus') except dbus.DBusException: name = None if not name: SingleProcess(service_name, activity_constructor) else: try: single_process = sessionbus.get_object(service_name, service_path) single_process.create( activity_handle.get_dict(), dbus_interface='org.laptop.SingleProcess') print('Created %s in a single process.' % service_name) sys.exit(0) except (TypeError, dbus.DBusException): print('Could not communicate with the instance process,' 'launching a new process') if hasattr(module, 'start'): module.start() instance = create_activity_instance(activity_constructor, activity_handle) if hasattr(instance, 'run_main_loop'): instance.run_main_loop()
def __init__(self, window_xid, bundle_path, document_path, sugar_toolkit_path, title): Gtk.Window.__init__(self) _logger.debug('ViewSource paths: %r %r %r', bundle_path, document_path, sugar_toolkit_path) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_border_width(style.LINE_WIDTH) self.set_has_resize_grip(False) width = Gdk.Screen.width() - style.GRID_CELL_SIZE * 2 height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 2 self.set_size_request(width, height) self._parent_window_xid = window_xid self._sugar_toolkit_path = sugar_toolkit_path self.connect('realize', self.__realize_cb) self.connect('destroy', self.__destroy_cb, document_path) self.connect('key-press-event', self.__key_press_event_cb) vbox = Gtk.VBox() self.add(vbox) vbox.show() toolbar = Toolbar(title, bundle_path, document_path, sugar_toolkit_path) vbox.pack_start(toolbar, False, True, 0) toolbar.connect('stop-clicked', self.__stop_clicked_cb) toolbar.connect('source-selected', self.__source_selected_cb) toolbar.show() pane = Gtk.HPaned() vbox.pack_start(pane, True, True, 0) pane.show() self._selected_bundle_file = None self._selected_sugar_file = None file_name = '' activity_bundle = ActivityBundle(bundle_path) command = activity_bundle.get_command() if _is_web_activity(bundle_path): file_name = 'index.html' elif len(command.split(' ')) > 1: name = command.split(' ')[1].split('.')[-1] tmppath = command.split(' ')[1].replace('.', '/') file_name = tmppath[0:-(len(name) + 1)] + '.py' if file_name: path = os.path.join(bundle_path, file_name) if os.path.exists(path): self._selected_bundle_file = path # Split the tree pane into two vertical panes, one of which # will be hidden tree_panes = Gtk.VPaned() tree_panes.show() self._bundle_source_viewer = FileViewer(bundle_path, file_name) self._bundle_source_viewer.connect('file-selected', self.__file_selected_cb) tree_panes.add1(self._bundle_source_viewer) self._bundle_source_viewer.show() self._sugar_source_viewer = None if sugar_toolkit_path is not None: if _is_web_activity(bundle_path): file_name = 'env.js' else: file_name = 'env.py' self._selected_sugar_file = os.path.join(sugar_toolkit_path, file_name) self._sugar_source_viewer = FileViewer(sugar_toolkit_path, file_name) self._sugar_source_viewer.connect('file-selected', self.__file_selected_cb) tree_panes.add2(self._sugar_source_viewer) self._sugar_source_viewer.hide() pane.add1(tree_panes) self._source_display = SourceDisplay() pane.add2(self._source_display) self._source_display.show() self._source_display.file_path = self._selected_bundle_file if document_path is not None: self._select_source(document_path)
def __init__(self, title, bundle_path, document_path, sugar_toolkit_path): Gtk.Toolbar.__init__(self) document_button = None self.bundle_path = bundle_path self.sugar_toolkit_path = sugar_toolkit_path self._add_separator() activity_bundle = ActivityBundle(bundle_path) file_name = activity_bundle.get_icon() if document_path is not None and os.path.exists(document_path): document_button = DocumentButton(file_name, document_path, title) document_button.connect('toggled', self.__button_toggled_cb, document_path) self.insert(document_button, -1) document_button.show() self._add_separator() if bundle_path is not None and os.path.exists(bundle_path): activity_button = DocumentButton(file_name, bundle_path, title, bundle=True) icon = Icon(file=file_name, pixel_size=style.STANDARD_ICON_SIZE, fill_color=style.COLOR_TRANSPARENT.get_svg(), stroke_color=style.COLOR_WHITE.get_svg()) activity_button.set_icon_widget(icon) icon.show() if document_button is not None: activity_button.props.group = document_button activity_button.props.tooltip = _('Activity Bundle Source') activity_button.connect('toggled', self.__button_toggled_cb, bundle_path) self.insert(activity_button, -1) activity_button.show() self._add_separator() if sugar_toolkit_path is not None: sugar_button = RadioToolButton() icon = Icon(icon_name='computer-xo', pixel_size=style.STANDARD_ICON_SIZE, fill_color=style.COLOR_TRANSPARENT.get_svg(), stroke_color=style.COLOR_WHITE.get_svg()) sugar_button.set_icon_widget(icon) icon.show() if document_button is not None: sugar_button.props.group = document_button else: sugar_button.props.group = activity_button sugar_button.props.tooltip = _('Sugar Toolkit Source') sugar_button.connect('toggled', self.__button_toggled_cb, sugar_toolkit_path) self.insert(sugar_button, -1) sugar_button.show() self._add_separator() self.activity_title_text = _('View source: %s') % title self.sugar_toolkit_title_text = _('View source: %r') % 'Sugar Toolkit' self.label = Gtk.Label() self.label.set_markup('<b>%s</b>' % self.activity_title_text) self.label.set_alignment(0, 0.5) self._add_widget(self.label) self._add_separator(True) stop = ToolButton(icon_name='dialog-cancel') stop.set_tooltip(_('Close')) stop.connect('clicked', self.__stop_clicked_cb) self.insert(stop, -1) stop.show()