Example #1
0
def handle(config, options, args):
	"""@type config: L{zeroinstall.injector.config.Config}
	@type args: [str]"""
	if len(args) == 0:
		from zeroinstall import helpers
		if helpers.get_selections_gui(None, [], use_gui = options.gui) == helpers.DontUseGUI:
			for key, setting_type in settings.items():
				value = getattr(config, key)
				print(key, "=", setting_type.format(value))
		# (else we displayed the preferences dialog in the GUI)
		return
	elif len(args) > 2:
		raise UsageError()

	option = args[0]
	if option not in settings:
		raise SafeException(_('Unknown option "%s"') % option)

	if len(args) == 1:
		value = getattr(config, option)
		print(settings[option].format(value))
	else:
		value = settings[option].parse(args[1])
		if option == 'network_use' and value not in model.network_levels:
			raise SafeException(_("Must be one of %s") % list(model.network_levels))
		setattr(config, option, value)

		config.save_globals()
Example #2
0
def handle(config, options, args):
	if len(args) == 0:
		from zeroinstall import helpers
		if helpers.get_selections_gui(None, [], use_gui = options.gui) == helpers.DontUseGUI:
			for key, setting_type in settings.items():
				value = getattr(config, key)
				print(key, "=", setting_type.format(value))
		# (else we displayed the preferences dialog in the GUI)
		return
	elif len(args) > 2:
		raise UsageError()

	option = args[0]
	if option not in settings:
		raise SafeException(_('Unknown option "%s"') % option)

	if len(args) == 1:
		value = getattr(config, option)
		print(settings[option].format(value))
	else:
		value = settings[option].parse(args[1])
		if option == 'network_use' and value not in model.network_levels:
			raise SafeException(_("Must be one of %s") % list(model.network_levels))
		setattr(config, option, value)

		config.save_globals()
Example #3
0
def handle(config, options, args):
	if len(args) == 0:
		if options.gui is None and os.environ.get('DISPLAY', None):
			options.gui = True
		if options.gui:
			from zeroinstall import helpers
			return helpers.get_selections_gui(None, [])
		else:
			for key, setting_type in settings.iteritems():
				value = getattr(config, key)
				print key, "=", setting_type.format(value)
		return
	elif len(args) > 2:
		raise UsageError()

	option = args[0]
	if option not in settings:
		raise SafeException(_('Unknown option "%s"') % option)

	if len(args) == 1:
		value = getattr(config, option)
		print settings[option].format(value)
	else:
		value = settings[option].parse(args[1])
		if option == 'network_use' and value not in model.network_levels:
			raise SafeException(_("Must be one of %s") % list(model.network_levels))
		setattr(config, option, value)

		config.save_globals()
Example #4
0
def do_get_selections_gui(config, args):
	reqs, opts = args

	use_gui = opts['use_gui']
	if use_gui == "yes": use_gui = True
	elif use_gui == "no": use_gui = False
	elif use_gui == "maybe": use_gui = None
	else: assert 0, use_gui

	gui_args = []

	if opts['refresh']: gui_args += ['--refresh']
	if opts['systray']: gui_args += ['--systray']

	if opts['action'] == 'for-select': gui_args += ['--select-only']
	elif opts['action'] == 'for-download': gui_args += ['--download-only']
	elif opts['action'] != 'for-run': assert 0, opts

	reqs = reqs_from_json(reqs)
	gui_args += reqs.get_as_options()

	from zeroinstall import helpers
	sels = helpers.get_selections_gui(reqs.interface_uri, gui_args, use_gui = use_gui)
	if sels == helpers.DontUseGUI:
		return ["dont-use-gui"]
	if not sels:
		return ["aborted-by-user"]
	return ["ok", sels.toDOM().toxml()]
Example #5
0
def handle(config, options, args):
    if len(args) == 0:
        if options.gui is None and os.environ.get('DISPLAY', None):
            options.gui = True
        if options.gui:
            from zeroinstall import helpers
            return helpers.get_selections_gui(None, [])
        else:
            for key, setting_type in settings.iteritems():
                value = getattr(config, key)
                print(key, "=", setting_type.format(value))
        return
    elif len(args) > 2:
        raise UsageError()

    option = args[0]
    if option not in settings:
        raise SafeException(_('Unknown option "%s"') % option)

    if len(args) == 1:
        value = getattr(config, option)
        print(settings[option].format(value))
    else:
        value = settings[option].parse(args[1])
        if option == 'network_use' and value not in model.network_levels:
            raise SafeException(
                _("Must be one of %s") % list(model.network_levels))
        setattr(config, option, value)

        config.save_globals()
Example #6
0
def do_get_selections_gui(config, args):
    reqs, opts = args

    use_gui = opts['use_gui']
    if use_gui == "yes": use_gui = True
    elif use_gui == "no": use_gui = False
    elif use_gui == "maybe": use_gui = None
    else: assert 0, use_gui

    gui_args = []

    if opts['refresh']: gui_args += ['--refresh']
    if opts['systray']: gui_args += ['--systray']

    if opts['action'] == 'for-select': gui_args += ['--select-only']
    elif opts['action'] == 'for-download': gui_args += ['--download-only']
    elif opts['action'] != 'for-run': assert 0, opts

    reqs = reqs_from_json(reqs)
    gui_args += reqs.get_as_options()

    from zeroinstall import helpers
    sels = helpers.get_selections_gui(reqs.interface_uri,
                                      gui_args,
                                      use_gui=use_gui)
    if sels == helpers.DontUseGUI:
        return ["dont-use-gui"]
    if not sels:
        return ["aborted-by-user"]
    return ["ok", sels.toDOM().toxml()]
Example #7
0
    def _foreground_update(self, driver, use_gui):
        """We can't run with saved selections or solved selections without downloading.
		Try to open the GUI for a blocking download. If we can't do that, download without the GUI.
		@type driver: L{zeroinstall.injector.driver.Driver}
		@rtype: L{zeroinstall.injector.selections.Selections}"""
        from zeroinstall import helpers
        from zeroinstall.support import tasks

        gui_args = driver.requirements.get_as_options() + [
            '--download-only', '--refresh'
        ]
        sels = helpers.get_selections_gui(driver.requirements.interface_uri,
                                          gui_args,
                                          test_callback=None,
                                          use_gui=use_gui)
        if sels is None:
            raise SafeException("Aborted by user")
        if sels is helpers.DontUseGUI:
            downloaded = driver.solve_and_download_impls(refresh=True)
            if downloaded:
                tasks.wait_for_blocker(downloaded)
            sels = driver.solver.selections

        self.set_selections(sels, set_last_checked=True)

        return sels
Example #8
0
def _fork_gui(iface_uri, gui_args, prog_args, options = None):
	"""Run the GUI to get the selections.
	prog_args and options are used only if the GUI requests a test.
	"""
	from zeroinstall import helpers
	def test_callback(sels):
		from zeroinstall.injector import run
		return run.test_selections(sels, prog_args,
					     bool(options and options.dry_run),
					     options and options.main)
	return helpers.get_selections_gui(iface_uri, gui_args, test_callback)
Example #9
0
	def _foreground_update(self, driver, use_gui):
		"""We can't run with saved selections or solved selections without downloading.
		Try to open the GUI for a blocking download. If we can't do that, download without the GUI."""
		from zeroinstall import helpers
		from zeroinstall.support import tasks

		gui_args = driver.requirements.get_as_options() + ['--download-only', '--refresh']
		sels = helpers.get_selections_gui(driver.requirements.interface_uri, gui_args,
						  test_callback = None, use_gui = use_gui)
		if sels is None:
			raise SafeException("Aborted by user")
		if sels is helpers.DontUseGUI:
			downloaded = driver.solve_and_download_impls(refresh = True)
			if downloaded:
				tasks.wait_for_blocker(downloaded)
			sels = driver.solver.selections

		self.set_selections(sels, set_last_checked = True)

		return sels
Example #10
0
def main(command_args, config=None):
    """Act as if 0launch was run with the given arguments.
	@arg command_args: array of arguments (e.g. C{sys.argv[1:]})
	@type command_args: [str]
	"""
    # Ensure stdin, stdout and stderr FDs exist, to avoid confusion
    for std in (0, 1, 2):
        try:
            os.fstat(std)
        except OSError:
            fd = os.open('/dev/null', os.O_RDONLY)
            if fd != std:
                os.dup2(fd, std)
                os.close(fd)

    parser = OptionParser(
        usage=_("usage: %prog [options] interface [args]\n"
                "       %prog --list [search-term]\n"
                "       %prog --import [signed-interface-files]\n"
                "       %prog --feed [interface]"))
    parser.add_option("",
                      "--before",
                      help=_("choose a version before this"),
                      metavar='VERSION')
    parser.add_option("",
                      "--command",
                      help=_("command to select"),
                      metavar='COMMAND')
    parser.add_option("-c",
                      "--console",
                      help=_("never use GUI"),
                      action='store_false',
                      dest='gui')
    parser.add_option("", "--cpu", help=_("target CPU type"), metavar='CPU')
    parser.add_option("-d",
                      "--download-only",
                      help=_("fetch but don't run"),
                      action='store_true')
    parser.add_option("-D",
                      "--dry-run",
                      help=_("just print actions"),
                      action='store_true')
    parser.add_option("-f",
                      "--feed",
                      help=_("add or remove a feed"),
                      action='store_true')
    parser.add_option("",
                      "--get-selections",
                      help=_("write selected versions as XML"),
                      action='store_true',
                      dest='xml')
    parser.add_option("-g",
                      "--gui",
                      help=_("show graphical policy editor"),
                      action='store_true')
    parser.add_option("-i",
                      "--import",
                      help=_("import from files, not from the network"),
                      action='store_true')
    parser.add_option("-l",
                      "--list",
                      help=_("list all known interfaces"),
                      action='store_true')
    parser.add_option("-m", "--main", help=_("name of the file to execute"))
    parser.add_option("",
                      "--message",
                      help=_("message to display when interacting with user"))
    parser.add_option("",
                      "--not-before",
                      help=_("minimum version to choose"),
                      metavar='VERSION')
    parser.add_option("",
                      "--os",
                      help=_("target operation system type"),
                      metavar='OS')
    parser.add_option("-o",
                      "--offline",
                      help=_("try to avoid using the network"),
                      action='store_true')
    parser.add_option("-r",
                      "--refresh",
                      help=_("refresh all used interfaces"),
                      action='store_true')
    parser.add_option("",
                      "--select-only",
                      help=_("only download the feeds"),
                      action='store_true')
    parser.add_option("",
                      "--set-selections",
                      help=_("run versions specified in XML file"),
                      metavar='FILE')
    parser.add_option("",
                      "--show",
                      help=_("show where components are installed"),
                      action='store_true')
    parser.add_option("-s",
                      "--source",
                      help=_("select source code"),
                      action='store_true')
    parser.add_option("-v",
                      "--verbose",
                      help=_("more verbose output"),
                      action='count')
    parser.add_option("-V",
                      "--version",
                      help=_("display version information"),
                      action='store_true')
    parser.add_option("",
                      "--with-store",
                      help=_("add an implementation cache"),
                      action='append',
                      metavar='DIR')
    parser.add_option("-w",
                      "--wrapper",
                      help=_("execute program using a debugger, etc"),
                      metavar='COMMAND')
    parser.disable_interspersed_args()

    (options, args) = parser.parse_args(command_args)

    if options.verbose:
        logger = logging.getLogger()
        if options.verbose == 1:
            logger.setLevel(logging.INFO)
        else:
            logger.setLevel(logging.DEBUG)
        import zeroinstall
        logging.info(
            _("Running 0launch %(version)s %(args)s; Python %(python_version)s"
              ), {
                  'version': zeroinstall.version,
                  'args': repr(args),
                  'python_version': sys.version
              })

    if options.select_only or options.show:
        options.download_only = True

    if config is None:
        config = load_config()
        config.handler.dry_run = bool(options.dry_run)

    if options.with_store:
        from zeroinstall import zerostore
        for x in options.with_store:
            config.stores.stores.append(zerostore.Store(os.path.abspath(x)))
        logging.info(_("Stores search path is now %s"), config.stores.stores)

    if options.set_selections:
        args = [options.set_selections] + args

    try:
        if options.list:
            from zeroinstall.cmd import list
            list.handle(config, options, args)
        elif options.version:
            import zeroinstall
            print("0launch (zero-install) " + zeroinstall.version)
            print("Copyright (C) 2010 Thomas Leonard")
            print(
                _("This program comes with ABSOLUTELY NO WARRANTY,"
                  "\nto the extent permitted by law."
                  "\nYou may redistribute copies of this program"
                  "\nunder the terms of the GNU Lesser General Public License."
                  "\nFor more information about these matters, see the file named COPYING."
                  ))
        elif getattr(options, 'import'):
            # (import is a keyword)
            cmd = __import__('zeroinstall.cmd.import', globals(), locals(),
                             ["import"], 0)
            cmd.handle(config, options, args)
        elif options.feed:
            from zeroinstall.cmd import add_feed
            add_feed.handle(config, options, args, add_ok=True, remove_ok=True)
        elif options.select_only:
            from zeroinstall.cmd import select
            if not options.show:
                options.quiet = True
            select.handle(config, options, args)
        elif options.download_only or options.xml or options.show:
            from zeroinstall.cmd import download
            download.handle(config, options, args)
        else:
            if len(args) < 1:
                if options.gui:
                    from zeroinstall import helpers
                    return helpers.get_selections_gui(None, [])
                else:
                    raise UsageError()
            else:
                from zeroinstall.cmd import run
                run.handle(config, options, args)
    except NeedDownload as ex:
        # This only happens for dry runs
        print(ex)
    except KeyboardInterrupt:
        logging.info("KeyboardInterrupt")
        sys.exit(1)
    except UsageError:
        parser.print_help()
        sys.exit(1)
    except SafeException as ex:
        if options.verbose: raise
        try:
            print(unicode(ex), file=sys.stderr)
        except:
            print(repr(ex), file=sys.stderr)
        sys.exit(1)
Example #11
0
def _check_for_updates(requirements, verbose, app):
    """@type requirements: L{zeroinstall.injector.requirements.Requirements}
	@type verbose: bool
	@type app: L{zeroinstall.apps.App}"""
    if app is not None:
        old_sels = app.get_selections()

    from zeroinstall.injector.driver import Driver
    from zeroinstall.injector.config import load_config

    background_handler = BackgroundHandler(requirements.interface_uri,
                                           requirements.interface_uri)
    background_config = load_config(background_handler)
    root_iface = background_config.iface_cache.get_interface(
        requirements.interface_uri).get_name()
    background_handler.title = root_iface

    driver = Driver(config=background_config, requirements=requirements)

    logger.info(_("Checking for updates to '%s' in a background process"),
                root_iface)
    if verbose:
        background_handler.notify("Zero Install",
                                  _("Checking for updates to '%s'...") %
                                  root_iface,
                                  timeout=1)

    network_state = background_handler.get_network_state()
    if network_state not in (_NetworkState.NM_STATE_CONNECTED_SITE,
                             _NetworkState.NM_STATE_CONNECTED_GLOBAL):
        logger.info(
            _("Not yet connected to network (status = %d). Sleeping for a bit..."
              ), network_state)
        import time
        time.sleep(120)
        if network_state in (_NetworkState.NM_STATE_DISCONNECTED,
                             _NetworkState.NM_STATE_ASLEEP):
            logger.info(_("Still not connected to network. Giving up."))
            sys.exit(1)
    else:
        logger.info(_("NetworkManager says we're on-line. Good!"))

    background_config.freshness = 0  # Don't bother trying to refresh when getting the interface
    refresh = driver.solve_with_downloads(
        force=True)  # (causes confusing log messages)
    tasks.wait_for_blocker(refresh)

    if background_handler.need_gui or not driver.solver.ready or driver.get_uncached_implementations(
    ):
        if verbose:
            background_handler.notify(
                "Zero Install",
                _("Updates ready to download for '%s'.") % root_iface,
                timeout=1)

        # Run the GUI if possible...
        from zeroinstall import helpers
        gui_args = ['--refresh', '--systray', '--download'
                    ] + requirements.get_as_options()
        new_sels = helpers.get_selections_gui(requirements.interface_uri,
                                              gui_args,
                                              use_gui=None)
        if new_sels is None:
            sys.exit(0)  # Cancelled by user
        elif new_sels is helpers.DontUseGUI:
            if not driver.solver.ready:
                background_handler.notify("Zero Install",
                                          _("Can't update '%s'") % root_iface)
                sys.exit(1)

            tasks.wait_for_blocker(driver.download_uncached_implementations())
            new_sels = driver.solver.selections

        if app is None:
            background_handler.notify(
                "Zero Install",
                _("{name} updated.").format(name=root_iface),
                timeout=1)
    else:
        if verbose:
            background_handler.notify("Zero Install",
                                      _("No updates to download."),
                                      timeout=1)
        new_sels = driver.solver.selections

    if app is not None:
        assert driver.solver.ready
        from zeroinstall.support import xmltools
        if not xmltools.nodes_equal(new_sels.toDOM(), old_sels.toDOM()):
            app.set_selections(new_sels)
            background_handler.notify(
                "Zero Install",
                _("{app} updated.").format(app=app.get_name()),
                timeout=1)
        app.set_last_checked()
    sys.exit(0)
Example #12
0
def _normal_mode(options, args):
	from zeroinstall.injector import handler

	if len(args) < 1:
		if options.gui:
			from zeroinstall import helpers
			return helpers.get_selections_gui(None, [])
		else:
			raise UsageError()

	iface_uri = model.canonical_iface_uri(args[0])
	root_iface = iface_cache.get_interface(iface_uri)

	if os.isatty(1):
		h = handler.ConsoleHandler()
	else:
		h = handler.Handler()
	h.dry_run = bool(options.dry_run)

	policy = autopolicy.AutoPolicy(iface_uri,
				handler = h,
				download_only = bool(options.download_only),
				src = options.source)

	if options.before or options.not_before:
		policy.solver.extra_restrictions[root_iface] = [model.VersionRangeRestriction(model.parse_version(options.before),
									      		      model.parse_version(options.not_before))]

	if options.os or options.cpu:
		from zeroinstall.injector import arch
		policy.target_arch = arch.get_architecture(options.os, options.cpu)

	if options.offline:
		policy.network_use = model.network_offline

	if options.get_selections:
		if len(args) > 1:
			raise SafeException(_("Can't use arguments with --get-selections"))
		if options.main:
			raise SafeException(_("Can't use --main with --get-selections"))

	# Note that need_download() triggers a solve
	if options.refresh or options.gui:
		# We could run immediately, but the user asked us not to
		can_run_immediately = False
	else:
		can_run_immediately = (not policy.need_download()) and policy.ready

		stale_feeds = [feed for feed in policy.solver.feeds_used if policy.is_stale(iface_cache.get_feed(feed))]

		if options.download_only and stale_feeds:
			can_run_immediately = False

	if can_run_immediately:
		if stale_feeds:
			if policy.network_use == model.network_offline:
				logging.debug(_("No doing background update because we are in off-line mode."))
			else:
				# There are feeds we should update, but we can run without them.
				# Do the update in the background while the program is running.
				import background
				background.spawn_background_update(policy, options.verbose > 0)
		if options.get_selections:
			_get_selections(policy)
		else:
			if not options.download_only:
				from zeroinstall.injector import run
				run.execute(policy, args[1:], dry_run = options.dry_run, main = options.main, wrapper = options.wrapper)
			else:
				logging.info(_("Downloads done (download-only mode)"))
			assert options.dry_run or options.download_only
		return

	# If the user didn't say whether to use the GUI, choose for them.
	if options.gui is None and os.environ.get('DISPLAY', None):
		options.gui = True
		# If we need to download anything, we might as well
		# refresh all the interfaces first. Also, this triggers
		# the 'checking for updates' box, which is non-interactive
		# when there are no changes to the selection.
		options.refresh = True
		logging.info(_("Switching to GUI mode... (use --console to disable)"))

	prog_args = args[1:]

	try:
		from zeroinstall.injector import run
		if options.gui:
			gui_args = []
			if options.download_only:
				# Just changes the button's label
				gui_args.append('--download-only')
			if options.refresh:
				gui_args.append('--refresh')
			if options.systray:
				gui_args.append('--systray')
			if options.not_before:
				gui_args.insert(0, options.not_before)
				gui_args.insert(0, '--not-before')
			if options.before:
				gui_args.insert(0, options.before)
				gui_args.insert(0, '--before')
			if options.source:
				gui_args.insert(0, '--source')
			if options.message:
				gui_args.insert(0, options.message)
				gui_args.insert(0, '--message')
			if options.verbose:
				gui_args.insert(0, '--verbose')
				if options.verbose > 1:
					gui_args.insert(0, '--verbose')
			if options.cpu:
				gui_args.insert(0, options.cpu)
				gui_args.insert(0, '--cpu')
			if options.os:
				gui_args.insert(0, options.os)
				gui_args.insert(0, '--os')
			if options.with_store:
				for x in options.with_store:
					gui_args += ['--with-store', x]
			sels = _fork_gui(iface_uri, gui_args, prog_args, options)
			if not sels:
				sys.exit(1)		# Aborted
		else:
			#program_log('download_and_execute ' + iface_uri)
			downloaded = policy.solve_and_download_impls(refresh = bool(options.refresh))
			if downloaded:
				policy.handler.wait_for_blocker(downloaded)
			sels = selections.Selections(policy)

		if options.get_selections:
			doc = sels.toDOM()
			doc.writexml(sys.stdout)
			sys.stdout.write('\n')
		elif not options.download_only:
			run.execute_selections(sels, prog_args, options.dry_run, options.main, options.wrapper)

	except NeedDownload, ex:
		# This only happens for dry runs
		print ex
Example #13
0
def get_selections(config, options, iface_uri, select_only, download_only, test_callback):
	"""Get selections for iface_uri, according to the options passed.
	Will switch to GUI mode if necessary.
	@param options: options from OptionParser
	@param iface_uri: canonical URI of the interface
	@param select_only: return immediately even if the selected versions aren't cached
	@param download_only: wait for stale feeds, and display GUI button as Download, not Run
	@return: the selected versions, or None if the user cancels
	@rtype: L{selections.Selections} | None
	"""
	if options.offline:
		config.network_use = model.network_offline

	# Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a
	# selections document and we return immediately.
	maybe_selections = config.iface_cache.get_feed(iface_uri, selections_ok = True)
	if isinstance(maybe_selections, selections.Selections):
		if not select_only:
			blocker = maybe_selections.download_missing(config)
			if blocker:
				logging.info(_("Waiting for selected implementations to be downloaded..."))
				config.handler.wait_for_blocker(blocker)
		return maybe_selections

	r = requirements.Requirements(iface_uri)
	r.parse_options(options)

	policy = Policy(config = config, requirements = r)

	# Note that need_download() triggers a solve
	if options.refresh or options.gui:
		# We could run immediately, but the user asked us not to
		can_run_immediately = False
	else:
		if select_only:
			# --select-only: we only care that we've made a selection, not that we've cached the implementations
			policy.need_download()
			can_run_immediately = policy.ready
		else:
			can_run_immediately = not policy.need_download()

		stale_feeds = [feed for feed in policy.solver.feeds_used if
				not feed.startswith('distribution:') and	# Ignore (memory-only) PackageKit feeds
				policy.is_stale(config.iface_cache.get_feed(feed))]

		if download_only and stale_feeds:
			can_run_immediately = False

	if can_run_immediately:
		if stale_feeds:
			if policy.network_use == model.network_offline:
				logging.debug(_("No doing background update because we are in off-line mode."))
			else:
				# There are feeds we should update, but we can run without them.
				# Do the update in the background while the program is running.
				from zeroinstall.injector import background
				background.spawn_background_update(policy, options.verbose > 0)
		return policy.solver.selections

	# If the user didn't say whether to use the GUI, choose for them.
	if options.gui is None and os.environ.get('DISPLAY', None):
		options.gui = True
		# If we need to download anything, we might as well
		# refresh all the feeds first.
		options.refresh = True
		logging.info(_("Switching to GUI mode... (use --console to disable)"))

	if options.gui:
		gui_args = policy.requirements.get_as_options()
		if download_only:
			# Just changes the button's label
			gui_args.append('--download-only')
		if options.refresh:
			gui_args.append('--refresh')
		if options.verbose:
			gui_args.insert(0, '--verbose')
			if options.verbose > 1:
				gui_args.insert(0, '--verbose')
		if options.with_store:
			for x in options.with_store:
				gui_args += ['--with-store', x]
		if select_only:
			gui_args.append('--select-only')

		from zeroinstall import helpers
		sels = helpers.get_selections_gui(iface_uri, gui_args, test_callback)

		if not sels:
			return None		# Aborted
	else:
		# Note: --download-only also makes us stop and download stale feeds first.
		downloaded = policy.solve_and_download_impls(refresh = options.refresh or download_only or False,
							     select_only = select_only)
		if downloaded:
			config.handler.wait_for_blocker(downloaded)
		sels = selections.Selections(policy)

	return sels
Example #14
0
def get_selections(config, options, iface_uri, select_only, download_only, test_callback):
	"""Get selections for iface_uri, according to the options passed.
	Will switch to GUI mode if necessary.
	@param options: options from OptionParser
	@param iface_uri: canonical URI of the interface
	@param select_only: return immediately even if the selected versions aren't cached
	@param download_only: wait for stale feeds, and display GUI button as Download, not Run
	@return: the selected versions, or None if the user cancels
	@rtype: L{selections.Selections} | None
	"""
	if options.offline:
		config.network_use = model.network_offline

	iface_cache = config.iface_cache

	# Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a
	# selections document and we return immediately.
	maybe_selections = iface_cache.get_feed(iface_uri, selections_ok = True)
	if isinstance(maybe_selections, selections.Selections):
		if not select_only:
			blocker = maybe_selections.download_missing(config)
			if blocker:
				logging.info(_("Waiting for selected implementations to be downloaded..."))
				tasks.wait_for_blocker(blocker)
		return maybe_selections

	r = requirements.Requirements(iface_uri)
	r.parse_options(options)

	policy = Policy(config = config, requirements = r)

	# Note that need_download() triggers a solve
	if options.refresh or options.gui:
		# We could run immediately, but the user asked us not to
		can_run_immediately = False
	else:
		if select_only:
			# --select-only: we only care that we've made a selection, not that we've cached the implementations
			policy.need_download()
			can_run_immediately = policy.ready
		else:
			can_run_immediately = not policy.need_download()

		stale_feeds = [feed for feed in policy.solver.feeds_used if
				not os.path.isabs(feed) and			# Ignore local feeds (note: file might be missing too)
				not feed.startswith('distribution:') and	# Ignore (memory-only) PackageKit feeds
				iface_cache.is_stale(iface_cache.get_feed(feed), config.freshness)]

		if download_only and stale_feeds:
			can_run_immediately = False

	if can_run_immediately:
		if stale_feeds:
			if policy.network_use == model.network_offline:
				logging.debug(_("No doing background update because we are in off-line mode."))
			else:
				# There are feeds we should update, but we can run without them.
				# Do the update in the background while the program is running.
				from zeroinstall.injector import background
				background.spawn_background_update(policy, options.verbose > 0)
		return policy.solver.selections

	# If the user didn't say whether to use the GUI, choose for them.
	if options.gui is None and os.environ.get('DISPLAY', None):
		options.gui = True
		# If we need to download anything, we might as well
		# refresh all the feeds first.
		options.refresh = True
		logging.info(_("Switching to GUI mode... (use --console to disable)"))

	if options.gui:
		gui_args = policy.requirements.get_as_options()
		if download_only:
			# Just changes the button's label
			gui_args.append('--download-only')
		if options.refresh:
			gui_args.append('--refresh')
		if options.verbose:
			gui_args.insert(0, '--verbose')
			if options.verbose > 1:
				gui_args.insert(0, '--verbose')
		if options.with_store:
			for x in options.with_store:
				gui_args += ['--with-store', x]
		if select_only:
			gui_args.append('--select-only')

		from zeroinstall import helpers
		sels = helpers.get_selections_gui(iface_uri, gui_args, test_callback)

		if not sels:
			return None		# Aborted
	else:
		# Note: --download-only also makes us stop and download stale feeds first.
		downloaded = policy.solve_and_download_impls(refresh = options.refresh or download_only or False,
							     select_only = select_only)
		if downloaded:
			tasks.wait_for_blocker(downloaded)
		sels = selections.Selections(policy)

	return sels
Example #15
0
def get_selections_for(requirements, config, options, select_only, download_only, test_callback):
	"""Get selections for given requirements.
	@since: 1.9"""
	if options.offline:
		config.network_use = model.network_offline

	iface_cache = config.iface_cache

	driver = Driver(config = config, requirements = requirements)

	# Note that need_download() triggers a solve
	if options.refresh or options.gui:
		# We could run immediately, but the user asked us not to
		can_run_immediately = False
	else:
		if select_only:
			# --select-only: we only care that we've made a selection, not that we've cached the implementations
			driver.need_download()
			can_run_immediately = driver.solver.ready
		else:
			can_run_immediately = not driver.need_download()

		stale_feeds = [feed for feed in driver.solver.feeds_used if
				not feed.startswith('distribution:') and	# Ignore (memory-only) PackageKit feeds
				iface_cache.is_stale(feed, config.freshness)]

		if download_only and stale_feeds:
			can_run_immediately = False

	if can_run_immediately:
		if stale_feeds:
			if config.network_use == model.network_offline:
				logger.debug(_("No doing background update because we are in off-line mode."))
			else:
				# There are feeds we should update, but we can run without them.
				# Do the update in the background while the program is running.
				from zeroinstall.injector import background
				background.spawn_background_update(driver, options.verbose)
		return driver.solver.selections

	# If we need to download anything, we might as well
	# refresh all the feeds first.
	options.refresh = True

	if options.gui != False:
		# If the user didn't say whether to use the GUI, choose for them.
		gui_args = driver.requirements.get_as_options()
		if download_only:
			# Just changes the button's label
			gui_args.append('--download-only')
		if options.refresh:
			gui_args.append('--refresh')
		if options.verbose:
			gui_args.insert(0, '--verbose')
			if options.verbose > 1:
				gui_args.insert(0, '--verbose')
		if options.with_store:
			for x in options.with_store:
				gui_args += ['--with-store', x]
		if select_only:
			gui_args.append('--select-only')

		from zeroinstall import helpers
		sels = helpers.get_selections_gui(requirements.interface_uri, gui_args, test_callback, use_gui = options.gui)

		if not sels:
			return None		# Aborted
		elif sels is helpers.DontUseGUI:
			sels = None
	else:
		sels = None

	if sels is None:
		# Note: --download-only also makes us stop and download stale feeds first.
		downloaded = driver.solve_and_download_impls(refresh = options.refresh or download_only or False,
							     select_only = select_only)
		if downloaded:
			tasks.wait_for_blocker(downloaded)
		sels = driver.solver.selections

	return sels
Example #16
0
def get_selections_for(requirements, config, options, select_only,
                       download_only, test_callback):
    """Get selections for given requirements.
	@since: 1.9"""
    if options.offline:
        config.network_use = model.network_offline

    iface_cache = config.iface_cache

    driver = Driver(config=config, requirements=requirements)

    # Note that need_download() triggers a solve
    if options.refresh or options.gui:
        # We could run immediately, but the user asked us not to
        can_run_immediately = False
    else:
        if select_only:
            # --select-only: we only care that we've made a selection, not that we've cached the implementations
            driver.need_download()
            can_run_immediately = driver.solver.ready
        else:
            can_run_immediately = not driver.need_download()

        stale_feeds = [
            feed for feed in driver.solver.feeds_used
            if not feed.startswith('distribution:')
            and  # Ignore (memory-only) PackageKit feeds
            iface_cache.is_stale(feed, config.freshness)
        ]

        if download_only and stale_feeds:
            can_run_immediately = False

    if can_run_immediately:
        if stale_feeds:
            if config.network_use == model.network_offline:
                logger.debug(
                    _("No doing background update because we are in off-line mode."
                      ))
            else:
                # There are feeds we should update, but we can run without them.
                # Do the update in the background while the program is running.
                from zeroinstall.injector import background
                background.spawn_background_update(driver, options.verbose)
        return driver.solver.selections

    # If we need to download anything, we might as well
    # refresh all the feeds first.
    options.refresh = True

    if options.gui != False:
        # If the user didn't say whether to use the GUI, choose for them.
        gui_args = driver.requirements.get_as_options()
        if download_only:
            # Just changes the button's label
            gui_args.append('--download-only')
        if options.refresh:
            gui_args.append('--refresh')
        if options.verbose:
            gui_args.insert(0, '--verbose')
            if options.verbose > 1:
                gui_args.insert(0, '--verbose')
        if options.with_store:
            for x in options.with_store:
                gui_args += ['--with-store', x]
        if select_only:
            gui_args.append('--select-only')

        from zeroinstall import helpers
        sels = helpers.get_selections_gui(requirements.interface_uri,
                                          gui_args,
                                          test_callback,
                                          use_gui=options.gui)

        if not sels:
            return None  # Aborted
        elif sels is helpers.DontUseGUI:
            sels = None
    else:
        sels = None

    if sels is None:
        # Note: --download-only also makes us stop and download stale feeds first.
        downloaded = driver.solve_and_download_impls(refresh=options.refresh
                                                     or download_only or False,
                                                     select_only=select_only)
        if downloaded:
            tasks.wait_for_blocker(downloaded)
        sels = driver.solver.selections

    return sels
Example #17
0
def main(command_args, config = None):
	"""Act as if 0launch was run with the given arguments.
	@arg command_args: array of arguments (e.g. C{sys.argv[1:]})
	@type command_args: [str]
	"""
	# Ensure stdin, stdout and stderr FDs exist, to avoid confusion
	for std in (0, 1, 2):
		try:
			os.fstat(std)
		except OSError:
			fd = os.open(os.devnull, os.O_RDONLY)
			if fd != std:
				os.dup2(fd, std)
				os.close(fd)

	parser = OptionParser(usage=_("usage: %prog [options] interface [args]\n"
				    "       %prog --list [search-term]\n"
				    "       %prog --import [signed-interface-files]\n"
				    "       %prog --feed [interface]"))
	parser.add_option("", "--before", help=_("choose a version before this"), metavar='VERSION')
	parser.add_option("", "--command", help=_("command to select"), metavar='COMMAND')
	parser.add_option("-c", "--console", help=_("never use GUI"), action='store_false', dest='gui')
	parser.add_option("", "--cpu", help=_("target CPU type"), metavar='CPU')
	parser.add_option("-d", "--download-only", help=_("fetch but don't run"), action='store_true')
	parser.add_option("-D", "--dry-run", help=_("just print actions"), action='store_true')
	parser.add_option("-f", "--feed", help=_("add or remove a feed"), action='store_true')
	parser.add_option("", "--get-selections", help=_("write selected versions as XML"), action='store_true', dest='xml')
	parser.add_option("-g", "--gui", help=_("show graphical policy editor"), action='store_true')
	parser.add_option("-i", "--import", help=_("import from files, not from the network"), action='store_true')
	parser.add_option("-l", "--list", help=_("list all known interfaces"), action='store_true')
	parser.add_option("-m", "--main", help=_("name of the file to execute"))
	parser.add_option("", "--message", help=_("message to display when interacting with user"))
	parser.add_option("", "--not-before", help=_("minimum version to choose"), metavar='VERSION')
	parser.add_option("", "--os", help=_("target operation system type"), metavar='OS')
	parser.add_option("-o", "--offline", help=_("try to avoid using the network"), action='store_true')
	parser.add_option("-r", "--refresh", help=_("refresh all used interfaces"), action='store_true')
	parser.add_option("", "--select-only", help=_("only download the feeds"), action='store_true')
	parser.add_option("", "--set-selections", help=_("run versions specified in XML file"), metavar='FILE')
	parser.add_option("", "--show", help=_("show where components are installed"), action='store_true')
	parser.add_option("-s", "--source", help=_("select source code"), action='store_true')
	parser.add_option("-v", "--verbose", help=_("more verbose output"), action='count')
	parser.add_option("-V", "--version", help=_("display version information"), action='store_true')
	parser.add_option("", "--with-store", help=_("add an implementation cache"), action='append', metavar='DIR')
	parser.add_option("-w", "--wrapper", help=_("execute program using a debugger, etc"), metavar='COMMAND')
	parser.disable_interspersed_args()

	(options, args) = parser.parse_args(command_args)

	if options.verbose:
		logger = logging.getLogger()
		if options.verbose == 1:
			logger.setLevel(logging.INFO)
		else:
			logger.setLevel(logging.DEBUG)
		import zeroinstall
		logging.info(_("Running 0launch %(version)s %(args)s; Python %(python_version)s"), {'version': zeroinstall.version, 'args': repr(args), 'python_version': sys.version})

	if options.select_only or options.show:
		options.download_only = True

	if config is None:
		config = load_config()
		config.handler.dry_run = bool(options.dry_run)

	if options.with_store:
		from zeroinstall import zerostore
		for x in options.with_store:
			config.stores.stores.append(zerostore.Store(os.path.abspath(x)))
		logging.info(_("Stores search path is now %s"), config.stores.stores)

	if options.set_selections:
		args = [options.set_selections] + args

	try:
		if options.list:
			from zeroinstall.cmd import list
			list.handle(config, options, args)
		elif options.version:
			import zeroinstall
			print("0launch (zero-install) " + zeroinstall.version)
			print("Copyright (C) 2010 Thomas Leonard")
			print(_("This program comes with ABSOLUTELY NO WARRANTY,"
					"\nto the extent permitted by law."
					"\nYou may redistribute copies of this program"
					"\nunder the terms of the GNU Lesser General Public License."
					"\nFor more information about these matters, see the file named COPYING."))
		elif getattr(options, 'import'):
			# (import is a keyword)
			cmd = __import__('zeroinstall.cmd.import', globals(), locals(), ["import"], 0)
			cmd.handle(config, options, args)
		elif options.feed:
			from zeroinstall.cmd import add_feed
			add_feed.handle(config, options, args, add_ok = True, remove_ok = True)
		elif options.select_only:
			from zeroinstall.cmd import select
			if not options.show:
				options.quiet = True
			select.handle(config, options, args)
		elif options.download_only or options.xml or options.show:
			from zeroinstall.cmd import download
			download.handle(config, options, args)
		else:
			if len(args) < 1:
				if options.gui:
					from zeroinstall import helpers
					return helpers.get_selections_gui(None, [])
				else:
					raise UsageError()
			else:
				from zeroinstall.cmd import run
				run.handle(config, options, args)
	except NeedDownload as ex:
		# This only happens for dry runs
		print(ex)
	except KeyboardInterrupt:
		logging.info("KeyboardInterrupt")
		sys.exit(1)
	except UsageError:
		parser.print_help()
		sys.exit(1)
	except SafeException as ex:
		if options.verbose: raise
		try:
			print(unicode(ex), file=sys.stderr)
		except:
			print(repr(ex), file=sys.stderr)
		sys.exit(1)
Example #18
0
def _check_for_updates(requirements, verbose, app):
	if app is not None:
		old_sels = app.get_selections()

	from zeroinstall.injector.driver import Driver
	from zeroinstall.injector.config import load_config

	background_handler = BackgroundHandler(requirements.interface_uri, requirements.interface_uri)
	background_config = load_config(background_handler)
	root_iface = background_config.iface_cache.get_interface(requirements.interface_uri).get_name()
	background_handler.title = root_iface

	driver = Driver(config = background_config, requirements = requirements)

	logger.info(_("Checking for updates to '%s' in a background process"), root_iface)
	if verbose:
		background_handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout = 1)

	network_state = background_handler.get_network_state()
	if network_state not in (_NetworkState.NM_STATE_CONNECTED_SITE, _NetworkState.NM_STATE_CONNECTED_GLOBAL):
		logger.info(_("Not yet connected to network (status = %d). Sleeping for a bit..."), network_state)
		import time
		time.sleep(120)
		if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP):
			logger.info(_("Still not connected to network. Giving up."))
			sys.exit(1)
	else:
		logger.info(_("NetworkManager says we're on-line. Good!"))

	background_config.freshness = 0			# Don't bother trying to refresh when getting the interface
	refresh = driver.solve_with_downloads(force = True)	# (causes confusing log messages)
	tasks.wait_for_blocker(refresh)

	if background_handler.need_gui or driver.get_uncached_implementations():
		if verbose:
			background_handler.notify("Zero Install",
					      _("Updates ready to download for '%s'.") % root_iface,
					      timeout = 1)

		# Run the GUI if possible...
		from zeroinstall import helpers
		gui_args = ['--refresh', '--systray', '--download'] + requirements.get_as_options()
		new_sels = helpers.get_selections_gui(requirements.interface_uri, gui_args, use_gui = None)
		if new_sels is None:
			sys.exit(0)	# Cancelled by user
		elif new_sels is helpers.DontUseGUI:
			tasks.wait_for_blocker(driver.download_uncached_implementations())
			new_sels = driver.solver.selections

		if app is None:
			background_handler.notify("Zero Install",
					      _("{name} updated.").format(name = root_iface),
					      timeout = 1)
	else:
		if verbose:
			background_handler.notify("Zero Install", _("No updates to download."), timeout = 1)
		new_sels = driver.solver.selections

	if app is not None:
		assert driver.solver.ready
		from zeroinstall.support import xmltools
		if not xmltools.nodes_equal(new_sels.toDOM(), old_sels.toDOM()):
			app.set_selections(new_sels)
			background_handler.notify("Zero Install",
					      _("{app} updated.").format(app = app.get_name()),
					      timeout = 1)
		app.set_last_checked()
	sys.exit(0)