예제 #1
0
파일: test_pga.py 프로젝트: dacp17/lutris
 def test_can_filter_by_installed_games(self):
     pga.add_game(name="installed_game", runner="Linux", installed=1)
     pga.add_game(name="bang", runner="Linux", installed=0)
     game_list = pga.get_games(filter_installed=True)
     print game_list
     self.assertEqual(len(game_list), 1)
     self.assertEqual(game_list[0]['name'], 'installed_game')
예제 #2
0
파일: sync.py 프로젝트: prettyv/lutris
    def sync_from_remote(self):
        """Synchronize from remote to local library.

        :return: The added and updated games (slugs)
        :rtype: tuple of sets
        """
        logger.debug("Syncing game library")
        # Get local library
        local_slugs = set([game['slug'] for game in self.library])
        logger.debug("%d games in local library", len(local_slugs))
        # Get remote library
        try:
            remote_library = api.get_library()
        except Exception as e:
            logger.debug("Error while downloading the remote library: %s" % e)
            remote_library = {}
        remote_slugs = set([game['slug'] for game in remote_library])
        logger.debug("%d games in remote library (inc. unpublished)",
                     len(remote_slugs))

        not_in_local = remote_slugs.difference(local_slugs)

        added = self.sync_missing_games(not_in_local, remote_library)
        updated = self.sync_game_details(remote_library)
        if added:
            self.library = pga.get_games()
        return (added, updated)
예제 #3
0
def switch_to_view(view=GAME_VIEW):
    game_list = [Game(game['slug']) for game in pga.get_games()]
    if view == 'icon':
        view = GameIconView(game_list)
    elif view == 'list':
        view = GameTreeView(game_list)
    view.show_all()
    return view
예제 #4
0
def update_platforms():
    pga_games = pga.get_games(filter_installed=True)
    for pga_game in pga_games:
        if pga_game.get('platform') or not pga_game['runner']:
            continue
        game = Game(id=pga_game['id'])
        game.set_platform_from_runner()
        game.save()
예제 #5
0
파일: api.py 프로젝트: aoighost/lutris
def sync():
    remote_library = get_library()['games']
    remote_slugs = set([game['slug'] for game in remote_library])
    local_libray = pga.get_games()
    local_slugs = set([game['slug'] for game in local_libray])
    not_in_local = remote_slugs.difference(local_slugs)
    for game in remote_library:
        if game['slug'] in not_in_local:
            pga.add_game(game['name'], slug=game['slug'])
    return not_in_local
예제 #6
0
def fill_missing_platforms():
    """Sets the platform on games where it's missing.
    This should never happen.
    """
    pga_games = pga.get_games(filter_installed=True)
    for pga_game in pga_games:
        if pga_game.get("platform") or not pga_game["runner"]:
            continue
        game = Game(game_id=pga_game["id"])
        logger.error("Providing missing platorm for game %s", game.slug)
        game.set_platform_from_runner()
        if game.platform:
            game.save(metadata_only=True)
예제 #7
0
 def get_store(self, games=None):
     """Return an instance of GameStore"""
     games = games or pga.get_games(show_installed_first=self.show_installed_first)
     game_store = GameStore(
         games,
         self.icon_type,
         self.filter_installed,
         self.view_sorting,
         self.view_sorting_ascending,
         self.show_installed_first,
     )
     game_store.connect("sorting-changed", self.on_game_store_sorting_changed)
     return game_store
예제 #8
0
def sync_from_remote():
    """Synchronize from remote to local library.

    :return: The added and updated games (slugs)
    :rtype: tuple of sets, added games and updated games
    """

    remote_library = api.get_library()
    remote_slugs = {game["slug"] for game in remote_library}

    local_slugs = {game["slug"] for game in pga.get_games()}
    missing_slugs = remote_slugs.difference(local_slugs)

    added = sync_missing_games(missing_slugs, remote_library)
    updated = sync_game_details(remote_library)
    return added, updated
예제 #9
0
파일: api.py 프로젝트: dennisjj4/lutris
def sync(caller=None):
    logger.debug("Syncing game library")
    remote_library = get_library()['games']
    remote_slugs = set([game['slug'] for game in remote_library])
    logger.debug("%d games in remote library", len(remote_slugs))
    local_libray = pga.get_games()
    local_slugs = set([game['slug'] for game in local_libray])
    logger.debug("%d games in local library", len(local_slugs))
    not_in_local = remote_slugs.difference(local_slugs)
    for game in remote_library:
        if game['slug'] in not_in_local:
            logger.debug("Adding %s to local library", game['slug'])
            pga.add_game(game['name'], slug=game['slug'], year=game['year'])
            if caller:
                caller.add_game_to_view(game['slug'])
    logger.debug("%d games added", len(not_in_local))
    return not_in_local
def migrate():
    games = pga.get_games(filter_installed=True)
    for game_info in games:
        if game_info["runner"] != "steam" or game_info["configpath"]:
            continue
        slug = game_info["slug"]
        config_id = make_game_config_id(slug)

        # Add configpath to db
        pga.add_or_update(name=game_info["name"],
                          runner="steam",
                          slug=slug,
                          configpath=config_id)

        # Add appid to config
        game_config = LutrisConfig(runner_slug="steam",
                                   game_config_id=config_id)
        game_config.raw_game_config.update(
            {"appid": str(game_info["steamid"])})
        game_config.save()
예제 #11
0
파일: sync.py 프로젝트: Freso/lutris
def sync_from_remote():
    """Synchronize from remote to local library.

    :return: The added and updated games (slugs)
    :rtype: tuple of sets, added games and updated games
    """
    local_library = pga.get_games()
    local_slugs = set([game['slug'] for game in local_library])

    try:
        remote_library = api.get_library()
    except Exception as ex:
        logger.error("Error while downloading the remote library: %s" % ex)
        remote_library = {}
    remote_slugs = set([game['slug'] for game in remote_library])

    missing_slugs = remote_slugs.difference(local_slugs)

    added = sync_missing_games(missing_slugs, remote_library)
    updated = sync_game_details(remote_library)
    return (added, updated)
예제 #12
0
파일: sync.py 프로젝트: Yilnis/lutris-1
def sync_from_remote():
    """Synchronize from remote to local library.

    :return: The added and updated games (slugs)
    :rtype: tuple of sets, added games and updated games
    """
    local_library = pga.get_games()
    local_slugs = set([game['slug'] for game in local_library])

    try:
        remote_library = api.get_library()
    except Exception as ex:
        logger.error("Error while downloading the remote library: %s" % ex)
        remote_library = {}
    remote_slugs = set([game['slug'] for game in remote_library])

    missing_slugs = remote_slugs.difference(local_slugs)

    added = sync_missing_games(missing_slugs, remote_library)
    updated = sync_game_details(remote_library)
    return (added, updated)
예제 #13
0
파일: test_pga.py 프로젝트: Yilnis/lutris-1
 def test_add_game(self):
     game_list = pga.get_games()
     game_names = [item['name'] for item in game_list]
     self.assertTrue("LutrisTest" in game_names)
예제 #14
0
 def sync_icons(self, stop_request=None):
     resources.fetch_icons(
         [game for game in pga.get_games()], callback=self.on_image_downloaded, stop_request=stop_request
     )
예제 #15
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        # Use stdout to output logs, only if no command line argument is
        # provided
        argc = len(sys.argv) - 1
        if "-d" in sys.argv or "--debug" in sys.argv:
            argc -= 1
        if not argc:
            # Switch back the log output to stderr (the default in Python)
            # to avoid messing with any output from command line options.

            # Use when targetting Python 3.7 minimum
            # console_handler.setStream(sys.stderr)

            # Until then...
            logger.removeHandler(log.console_handler)
            log.console_handler = logging.StreamHandler(stream=sys.stdout)
            log.console_handler.setFormatter(log.SIMPLE_FORMATTER)
            logger.addHandler(log.console_handler)

        # Set up logger
        if options.contains("debug"):
            log.console_handler.setFormatter(log.DEBUG_FORMATTER)
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # Print Lutris version and exit
        if options.contains("version"):
            executable_name = os.path.basename(sys.argv[0])
            print(executable_name + "-" + settings.VERSION)
            logger.setLevel(logging.NOTSET)
            return 0

        logger.info("Running Lutris %s", settings.VERSION)
        migrate()
        run_all_checks()
        AsyncCall(init_dxvk_versions)

        # List game
        if options.contains("list-games"):
            game_list = pga.get_games()
            if options.contains("installed"):
                game_list = [game for game in game_list if game["installed"]]
            if options.contains("json"):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        elif options.contains("list-steam-games"):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        elif options.contains("list-steam-folders"):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        elif options.contains("exec"):
            command = options.lookup_value("exec").get_string()
            self.execute_command(command)
            return 0

        elif options.contains("submit-issue"):
            IssueReportWindow(application=self)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, "%s is not a valid URI" % url.get_strv())
            return 1
        game_slug = installer_info["game_slug"]
        action = installer_info["action"]
        revision = installer_info["revision"]

        installer_file = None
        if options.contains("install"):
            installer_file = options.lookup_value("install").get_string()
            installer_file = os.path.abspath(installer_file)
            action = "install"
            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        db_game = None
        if game_slug:
            if action == "rungameid":
                # Force db_game to use game id
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "id")
            elif action == "rungame":
                # Force db_game to use game slug
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "slug")
            elif action == "install":
                # Installers can use game or installer slugs
                self.run_in_background = True
                db_game = pga.get_game_by_field(
                    game_slug, "slug") or pga.get_game_by_field(
                        game_slug, "installer_slug")
            else:
                # Dazed and confused, try anything that might works
                db_game = (pga.get_game_by_field(game_slug, "id")
                           or pga.get_game_by_field(game_slug, "slug") or
                           pga.get_game_by_field(game_slug, "installer_slug"))

        # Graphical commands
        self.activate()

        if not action:
            if db_game and db_game["installed"]:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game["name"])
                if not dlg.action_confirmed:
                    action = None
                elif dlg.action == "play":
                    action = "rungame"
                elif dlg.action == "install":
                    action = "install"
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = "install"

        if action == "install":
            InstallerWindow(
                game_slug=game_slug,
                installer_file=installer_file,
                revision=revision,
                parent=self.window,
                application=self,
            )
        elif action in ("rungame", "rungameid"):
            if not db_game or not db_game["id"]:
                logger.warning("No game found in library")
                if not self.window.is_visible():
                    self.do_shutdown()
                return 0
            self.launch(Game(db_game["id"]))
        return 0
예제 #16
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        if options.contains('debug'):
            logger.setLevel(logging.DEBUG)

        if options.contains('list-games'):
            game_list = pga.get_games()
            if options.contains('installed'):
                game_list = [game for game in game_list if game['installed']]
            if options.contains('json'):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        elif options.contains('list-steam-games'):
            self.print_steam_list(command_line)
            return 0
        elif options.contains('list-steam-folders'):
            self.print_steam_folders(command_line)
            return 0
        elif options.contains('exec'):
            command = options.lookup_value('exec').get_string()
            self.execute_command(command)
            return 0

        game_slug = ''
        revision = None
        uri = options.lookup_value(GLib.OPTION_REMAINING)
        if uri:
            uri = uri.get_strv()
        if uri and len(uri):
            uri = uri[0]  # TODO: Support multiple
            installer_info = parse_installer_url(uri)
            if installer_info is False:
                self._print(command_line, '%s is not a valid URI' % uri)
                return 1
            game_slug = installer_info['game_slug']
            revision = installer_info['revision']

        if game_slug or options.contains('install'):
            installer_file = None
            if options.contains('install'):
                installer_file = options.lookup_value('install').get_string()
                if not os.path.isfile(installer_file):
                    self._print(command_line, "No such file: %s" % installer_file)
                    return 1

            db_game = None
            if game_slug:
                db_game = (pga.get_game_by_field(game_slug, 'id') or
                           pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

            force_install = options.contains('reinstall') or bool(installer_info.get('revision'))
            if db_game and db_game['installed'] and not force_install:
                self._print(command_line, "Launching %s" % db_game['name'])
                if self.window:
                    self.run_game(db_game['id'])
                else:
                    lutris_game = Game(db_game['id'])
                    # FIXME: This is awful
                    lutris_game.exit_main_loop = True
                    lutris_game.play()
                    try:
                        GLib.MainLoop().run()
                    except KeyboardInterrupt:
                        lutris_game.stop()
            else:
                self._print(command_line, "Installing %s" % game_slug or installer_file)
                if self.window:
                    self.window.on_install_clicked(game_slug=game_slug,
                                                   installer_file=installer_file,
                                                   revision=revision)
                else:
                    runtime_updater = RuntimeUpdater()
                    runtime_updater.update()
                    # FIXME: This should be a Gtk.Dialog child of LutrisWindow
                    dialog = InstallerDialog(game_slug=game_slug,
                                             installer_file=installer_file,
                                             revision=revision)
                    self.add_window(dialog)
            return 0

        self.activate()
        return 0
예제 #17
0
    def do_command_line(self, command_line):  # noqa: C901  # pylint: disable=arguments-differ
        # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches
        # pylint: disable=too-many-statements
        # TODO: split into multiple methods to reduce complexity (35)
        options = command_line.get_options_dict()

        # Use stdout to output logs, only if no command line argument is
        # provided
        argc = len(sys.argv) - 1
        if "-d" in sys.argv or "--debug" in sys.argv:
            argc -= 1
        if not argc:
            # Switch back the log output to stderr (the default in Python)
            # to avoid messing with any output from command line options.

            # Use when targetting Python 3.7 minimum
            # console_handler.setStream(sys.stderr)

            # Until then...
            logger.removeHandler(log.console_handler)
            log.console_handler = logging.StreamHandler(stream=sys.stdout)
            log.console_handler.setFormatter(log.SIMPLE_FORMATTER)
            logger.addHandler(log.console_handler)

        # Set up logger
        if options.contains("debug"):
            log.console_handler.setFormatter(log.DEBUG_FORMATTER)
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # Print Lutris version and exit
        if options.contains("version"):
            executable_name = os.path.basename(sys.argv[0])
            print(executable_name + "-" + settings.VERSION)
            logger.setLevel(logging.NOTSET)
            return 0

        logger.info("Running Lutris %s", settings.VERSION)
        migrate()
        run_all_checks()
        AsyncCall(init_dxvk_versions, None)

        # List game
        if options.contains("list-games"):
            game_list = pga.get_games()
            if options.contains("installed"):
                game_list = [game for game in game_list if game["installed"]]
            if options.contains("json"):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        if options.contains("list-steam-games"):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        if options.contains("list-steam-folders"):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        if options.contains("exec"):
            command = options.lookup_value("exec").get_string()
            self.execute_command(command)
            return 0

        if options.contains("submit-issue"):
            IssueReportWindow(application=self)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, "%s is not a valid URI" % url.get_strv())
            return 1
        game_slug = installer_info["game_slug"]
        action = installer_info["action"]
        revision = installer_info["revision"]

        installer_file = None
        if options.contains("install"):
            installer_file = options.lookup_value("install").get_string()
            if installer_file.startswith(("http:", "https:")):
                try:
                    request = Request(installer_file).get()
                except HTTPError:
                    self._print(command_line,
                                "Failed to download %s" % installer_file)
                    return 1
                try:
                    headers = dict(request.response_headers)
                    file_name = headers["Content-Disposition"].split("=",
                                                                     1)[-1]
                except (KeyError, IndexError):
                    file_name = os.path.basename(installer_file)
                file_path = os.path.join(tempfile.gettempdir(), file_name)
                self._print(
                    command_line,
                    "download %s to %s started" % (installer_file, file_path))
                with open(file_path, 'wb') as dest_file:
                    dest_file.write(request.content)
                installer_file = file_path
                action = "install"
            else:
                installer_file = os.path.abspath(installer_file)
                action = "install"

            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        db_game = None
        if game_slug:
            if action == "rungameid":
                # Force db_game to use game id
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "id")
            elif action == "rungame":
                # Force db_game to use game slug
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "slug")
            elif action == "install":
                # Installers can use game or installer slugs
                self.run_in_background = True
                db_game = pga.get_game_by_field(
                    game_slug, "slug") or pga.get_game_by_field(
                        game_slug, "installer_slug")
            else:
                # Dazed and confused, try anything that might works
                db_game = (pga.get_game_by_field(game_slug, "id")
                           or pga.get_game_by_field(game_slug, "slug") or
                           pga.get_game_by_field(game_slug, "installer_slug"))

        # Graphical commands
        self.activate()
        self.set_tray_icon()

        if not action:
            if db_game and db_game["installed"]:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game["name"])
                if not dlg.action_confirmed:
                    action = None
                elif dlg.action == "play":
                    action = "rungame"
                elif dlg.action == "install":
                    action = "install"
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = "install"

        if action == "install":
            self.show_window(
                InstallerWindow,
                parent=self.window,
                game_slug=game_slug,
                installer_file=installer_file,
                revision=revision,
            )
        elif action in ("rungame", "rungameid"):
            if not db_game or not db_game["id"]:
                logger.warning("No game found in library")
                if not self.window.is_visible():
                    self.do_shutdown()
                return 0
            self.launch(Game(db_game["id"]))
        return 0
예제 #18
0
파일: lutriswindow.py 프로젝트: TRPB/lutris
    def __init__(self, application, **kwargs):
        self.application = application
        self.runtime_updater = RuntimeUpdater()
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_launch_time = 0
        self.selected_runner = None
        self.selected_platform = None
        self.icon_type = None

        # Load settings
        width = int(settings.read_setting("width") or 800)
        height = int(settings.read_setting("height") or 600)
        self.window_size = (width, height)
        self.maximized = settings.read_setting("maximized") == "True"

        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = settings.read_setting(
            "filter_installed") == "true"
        self.show_installed_first = (
            settings.read_setting("show_installed_first") == "true")
        self.sidebar_visible = settings.read_setting("sidebar_visible") in [
            "true",
            None,
        ]
        self.view_sorting = settings.read_setting("view_sorting") or "name"
        self.view_sorting_ascending = (
            settings.read_setting("view_sorting_ascending") != "false")
        self.use_dark_theme = (settings.read_setting(
            "dark_theme", default="false").lower() == "true")
        self.show_tray_icon = (settings.read_setting(
            "show_tray_icon", default="false").lower() == "true")

        # Window initialization
        self.game_actions = GameActions(application=application, window=self)
        self.game_list = pga.get_games(
            show_installed_first=self.show_installed_first)
        self.game_store = GameStore(
            [],
            self.icon_type,
            self.filter_installed,
            self.view_sorting,
            self.view_sorting_ascending,
            self.show_installed_first,
        )
        self.view = self.get_view(view_type)
        self.game_store.connect("sorting-changed",
                                self.on_game_store_sorting_changed)
        super().__init__(default_width=width,
                         default_height=height,
                         icon_name="lutris",
                         application=application,
                         **kwargs)
        if self.maximized:
            self.maximize()
        self.init_template()
        self._init_actions()
        self._bind_zoom_adjustment()

        # Load view
        self.games_scrollwindow.add(self.view)
        self._connect_signals()
        # Set theme to dark if set in the settings
        self.set_dark_theme(self.use_dark_theme)
        self.set_viewtype_icon(view_type)

        # Add additional widgets
        self.sidebar_listbox = SidebarListBox()
        self.sidebar_listbox.set_size_request(250, -1)
        self.sidebar_listbox.connect("selected-rows-changed",
                                     self.on_sidebar_changed)
        self.sidebar_scrolled.add(self.sidebar_listbox)

        self.game_revealer = Gtk.Revealer()
        self.game_revealer.show()
        self.game_revealer.set_transition_duration(500)
        self.game_revealer.set_transition_type(
            Gtk.RevealerTransitionType.SLIDE_LEFT)

        self.game_scrolled = Gtk.ScrolledWindow()
        self.game_scrolled.set_size_request(320, -1)
        self.game_scrolled.set_policy(Gtk.PolicyType.NEVER,
                                      Gtk.PolicyType.NEVER)
        self.game_scrolled.show()
        self.game_revealer.add(self.game_scrolled)

        self.game_panel = Gtk.Box()
        self.main_box.pack_end(self.game_revealer, False, False, 0)

        self.view.show()

        # Contextual menu
        self.view.contextual_menu = ContextualMenu(
            self.game_actions.get_game_actions())

        # Sidebar
        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.sidebar_revealer.set_reveal_child(self.sidebar_visible)
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials["username"])
        else:
            self.toggle_connection(False)
            self.sync_library()

        self.sync_services()
예제 #19
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        # Set up logger
        if options.contains('debug'):
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # Print Lutris version and exit
        if options.contains('version'):
            executable_name = os.path.basename(sys.argv[0])
            print(executable_name + "-" + VERSION)
            logger.setLevel(logging.NOTSET)
            return 0

        # List game
        if options.contains('list-games'):
            game_list = pga.get_games()
            if options.contains('installed'):
                game_list = [game for game in game_list if game['installed']]
            if options.contains('json'):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        elif options.contains('list-steam-games'):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        elif options.contains('list-steam-folders'):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        elif options.contains('exec'):
            command = options.lookup_value('exec').get_string()
            self.execute_command(command)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, '%s is not a valid URI' % url.get_strv())
            return 1
        game_slug = installer_info['game_slug']
        action = installer_info['action']
        revision = installer_info['revision']

        installer_file = None
        if options.contains('install'):
            installer_file = options.lookup_value('install').get_string()
            installer_file = os.path.abspath(installer_file)
            action = 'install'
            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        # Graphical commands
        self.activate()

        db_game = None
        if game_slug:
            if action == 'rungameid':
                # Force db_game to use game id
                db_game = pga.get_game_by_field(game_slug, 'id')
            elif action == 'rungame':
                # Force db_game to use game slug
                db_game = pga.get_game_by_field(game_slug, 'slug')
            elif action == 'install':
                # Installers can use game or installer slugs
                db_game = (pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

            else:
                # Dazed and confused, try anything that might works
                db_game = (pga.get_game_by_field(game_slug, 'id')
                           or pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

        if not action:
            if db_game and db_game['installed']:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game['name'])
                if not dlg.action_confirmed:
                    action = None
                if dlg.action == 'play':
                    action = 'rungame'
                elif dlg.action == 'install':
                    action = 'install'
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = 'install'

        if action == 'install':
            self.window.present()
            self.window.on_install_clicked(game_slug=game_slug,
                                           installer_file=installer_file,
                                           revision=revision)
        elif action in ('rungame', 'rungameid'):
            if not db_game or not db_game['id']:
                if self.window.is_visible():
                    logger.info("No game found in library")
                else:
                    logger.info("No game found in library, shutting down")
                    self.do_shutdown()
                return 0

            logger.info("Launching %s", db_game['name'])

            # If game is not installed, show the GUI before running. Otherwise leave the GUI closed.
            if not db_game['installed']:
                self.window.present()
            self.window.on_game_run(game_id=db_game['id'])

        else:
            self.window.present()

        return 0
예제 #20
0
 def test_get_games_is_safe(self):
     try:
         pga.get_games(select="; asdf")
     except OperationalError:
         self.fail()
예제 #21
0
 def __init__(self):
     self.library = pga.get_games()
예제 #22
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        # Use stdout to output logs, only if no command line argument is
        # provided
        argc = len(sys.argv) - 1
        if "-d" in sys.argv or "--debug" in sys.argv:
            argc -= 1
        if not argc:
            # Switch back the log output to stderr (the default in Python)
            # to avoid messing with any output from command line options.

            # Use when targetting Python 3.7 minimum
            # console_handler.setStream(sys.stderr)

            # Until then...
            logger.removeHandler(log.console_handler)
            log.console_handler = logging.StreamHandler(stream=sys.stdout)
            log.console_handler.setFormatter(log.SIMPLE_FORMATTER)
            logger.addHandler(log.console_handler)

        # Set up logger
        if options.contains("debug"):
            log.console_handler.setFormatter(log.DEBUG_FORMATTER)
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # Print Lutris version and exit
        if options.contains("version"):
            executable_name = os.path.basename(sys.argv[0])
            print(executable_name + "-" + settings.VERSION)
            logger.setLevel(logging.NOTSET)
            return 0

        logger.info("Running Lutris %s", settings.VERSION)
        migrate()
        run_all_checks()
        AsyncCall(init_dxvk_versions)

        # List game
        if options.contains("list-games"):
            game_list = pga.get_games()
            if options.contains("installed"):
                game_list = [game for game in game_list if game["installed"]]
            if options.contains("json"):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        elif options.contains("list-steam-games"):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        elif options.contains("list-steam-folders"):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        elif options.contains("exec"):
            command = options.lookup_value("exec").get_string()
            self.execute_command(command)
            return 0

        elif options.contains("submit-issue"):
            IssueReportWindow(application=self)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, "%s is not a valid URI" % url.get_strv())
            return 1
        game_slug = installer_info["game_slug"]
        action = installer_info["action"]
        revision = installer_info["revision"]

        installer_file = None
        if options.contains("install"):
            installer_file = options.lookup_value("install").get_string()
            installer_file = os.path.abspath(installer_file)
            action = "install"
            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        db_game = None
        if game_slug:
            if action == "rungameid":
                # Force db_game to use game id
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "id")
            elif action == "rungame":
                # Force db_game to use game slug
                self.run_in_background = True
                db_game = pga.get_game_by_field(game_slug, "slug")
            elif action == "install":
                # Installers can use game or installer slugs
                self.run_in_background = True
                db_game = pga.get_game_by_field(
                    game_slug, "slug"
                ) or pga.get_game_by_field(game_slug, "installer_slug")
            else:
                # Dazed and confused, try anything that might works
                db_game = (
                    pga.get_game_by_field(game_slug, "id")
                    or pga.get_game_by_field(game_slug, "slug")
                    or pga.get_game_by_field(game_slug, "installer_slug")
                )

        # Graphical commands
        self.activate()

        if not action:
            if db_game and db_game["installed"]:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game["name"])
                if not dlg.action_confirmed:
                    action = None
                elif dlg.action == "play":
                    action = "rungame"
                elif dlg.action == "install":
                    action = "install"
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = "install"

        if action == "install":
            InstallerWindow(
                game_slug=game_slug,
                installer_file=installer_file,
                revision=revision,
                parent=self.window,
                application=self,
            )
        elif action in ("rungame", "rungameid"):
            if not db_game or not db_game["id"]:
                logger.warning("No game found in library")
                if not self.window.is_visible():
                    self.do_shutdown()
                return 0
            self.launch(Game(db_game["id"]))
        return 0
예제 #23
0
파일: game.py 프로젝트: prettyv/lutris
def get_game_list():
    games = pga.get_games()
    return [game['id'] for game in games]
예제 #24
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        # Set up logger
        if options.contains("debug"):
            console_handler.setFormatter(DEBUG_FORMATTER)
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # Print Lutris version and exit
        if options.contains("version"):
            executable_name = os.path.basename(sys.argv[0])
            print(executable_name + "-" + VERSION)
            logger.setLevel(logging.NOTSET)
            return 0

        # List game
        if options.contains("list-games"):
            game_list = pga.get_games()
            if options.contains("installed"):
                game_list = [game for game in game_list if game["installed"]]
            if options.contains("json"):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        elif options.contains("list-steam-games"):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        elif options.contains("list-steam-folders"):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        elif options.contains("exec"):
            command = options.lookup_value("exec").get_string()
            self.execute_command(command)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, "%s is not a valid URI" % url.get_strv())
            return 1
        game_slug = installer_info["game_slug"]
        action = installer_info["action"]
        revision = installer_info["revision"]

        installer_file = None
        if options.contains("install"):
            installer_file = options.lookup_value("install").get_string()
            installer_file = os.path.abspath(installer_file)
            action = "install"
            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        # Graphical commands
        self.activate()

        db_game = None
        if game_slug:
            if action == "rungameid":
                # Force db_game to use game id
                db_game = pga.get_game_by_field(game_slug, "id")
            elif action == "rungame":
                # Force db_game to use game slug
                db_game = pga.get_game_by_field(game_slug, "slug")
            elif action == "install":
                # Installers can use game or installer slugs
                db_game = pga.get_game_by_field(
                    game_slug, "slug") or pga.get_game_by_field(
                        game_slug, "installer_slug")

            else:
                # Dazed and confused, try anything that might works
                db_game = (pga.get_game_by_field(game_slug, "id")
                           or pga.get_game_by_field(game_slug, "slug") or
                           pga.get_game_by_field(game_slug, "installer_slug"))

        if not action:
            if db_game and db_game["installed"]:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game["name"])
                if not dlg.action_confirmed:
                    action = None
                elif dlg.action == "play":
                    action = "rungame"
                elif dlg.action == "install":
                    action = "install"
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = "install"

        if action == "install":
            InstallerWindow(
                game_slug=game_slug,
                installer_file=installer_file,
                revision=revision,
                parent=self.window,
                application=self,
            )
        elif action in ("rungame", "rungameid"):
            if not db_game or not db_game["id"]:
                logger.warning("No game found in library")
                return 0

            logger.info("Launching %s", db_game["name"])

            # If game is not installed, show the GUI before running. Otherwise leave the GUI closed.
            if not db_game["installed"]:
                self.window.present()
            self.launch(db_game["id"])

        else:
            self.window.present()

        return 0
예제 #25
0
def migrate():
    for game in [Game(pga_game['id']) for pga_game in pga.get_games()]:
        if xdg.desktop_launcher_exists(game.slug, game.id):
            xdg.create_launcher(game.slug, game.id, game.name, desktop=True)
        if xdg.menu_launcher_exists(game.slug, game.id):
            xdg.create_launcher(game.slug, game.id, game.name, menu=True)
예제 #26
0
def migrate():
    for game in get_games():
        if not game["playtime"]:
            continue
        fix_playtime(game)
예제 #27
0
파일: test_pga.py 프로젝트: Yilnis/lutris-1
 def test_get_game_list(self):
     game_list = pga.get_games()
     self.assertEqual(game_list[0]['id'], self.game_id)
     self.assertEqual(game_list[0]['slug'], 'lutristest')
     self.assertEqual(game_list[0]['name'], 'LutrisTest')
     self.assertEqual(game_list[0]['runner'], 'Linux')
예제 #28
0
 def test_does_set_installed_games(self):
     pga.add_game(name="some game", runner='linux', directory="/home")
     pga.set_installed_games()
     test_game = pga.get_games()[0]
     self.assertEqual(test_game['installed'], 1)
예제 #29
0
파일: test_pga.py 프로젝트: Yilnis/lutris-1
 def test_can_filter_by_installed_games(self):
     pga.add_game(name="installed_game", runner="Linux", installed=1)
     pga.add_game(name="bang", runner="Linux", installed=0)
     game_list = pga.get_games(filter_installed=True)
     self.assertEqual(len(game_list), 1)
     self.assertEqual(game_list[0]['name'], 'installed_game')
예제 #30
0
    def __init__(self, application, **kwargs):
        self.runtime_updater = RuntimeUpdater()
        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None
        self.selected_runner = None
        self.selected_platform = None

        # Load settings
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        self.maximized = settings.read_setting('maximized') == 'True'

        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = \
            settings.read_setting('filter_installed') == 'true'
        self.sidebar_visible = \
            settings.read_setting('sidebar_visible') in ['true', None]
        self.use_dark_theme = settings.read_setting('dark_theme') == 'true'

        # Sync local lutris library with current Steam games and desktop games
        # before setting up game list and view
        steam.sync_with_lutris()
        desktopapps.sync_with_lutris()

        # Window initialization
        self.game_list = pga.get_games()
        self.game_store = GameStore([], self.icon_type, self.filter_installed)
        self.view = self.get_view(view_type)
        super().__init__(default_width=width,
                         default_height=height,
                         icon_name='lutris',
                         application=application,
                         **kwargs)
        if self.maximized:
            self.maximize()
        self.init_template()
        self._init_actions()

        # Set theme to dark if set in the settings
        self.set_dark_theme(self.use_dark_theme)

        # Load view
        self.games_scrollwindow.add(self.view)
        self.connect_signals()
        self.view.show()

        # Contextual menu
        main_entries = [
            ('play', "Play", self.on_game_run),
            ('install', "Install", self.on_install_clicked),
            ('add', "Add manually", self.on_add_manually),
            ('configure', "Configure", self.on_edit_game_configuration),
            ('browse', "Browse files", self.on_browse_files),
            ('desktop-shortcut', "Create desktop shortcut",
             self.create_desktop_shortcut),
            ('rm-desktop-shortcut', "Delete desktop shortcut",
             self.remove_desktop_shortcut),
            ('menu-shortcut', "Create application menu shortcut",
             self.create_menu_shortcut),
            ('rm-menu-shortcut', "Delete application menu shortcut",
             self.remove_menu_shortcut),
            ('install_more', "Install (add) another version", self.on_install_clicked),
            ('remove', "Remove", self.on_remove_game),
            ('view', "View on Lutris.net", self.on_view_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect('cursor-changed', self.on_sidebar_changed)
        self.sidebar_viewport.add(self.sidebar_treeview)
        self.sidebar_treeview.show()

        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.show_sidebar()
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status)]
        steamapps_paths = steam.get_steamapps_paths(flat=True)
        self.steam_watcher = steam.SteamWatcher(steamapps_paths,
                                                self.on_steam_game_changed)
예제 #31
0
def get_game_list(filter_installed=False):
    games = pga.get_games(filter_installed=filter_installed)
    return [game['slug'] for game in games]
예제 #32
0
 def __init__(self):
     self.library = pga.get_games()
예제 #33
0
    def __init__(self, service=None):

        Gtk.Application.__init__(
            self,
            application_id="net.lutris.main",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        ui_filename = os.path.join(datapath.get(), 'ui', 'lutris-window.ui')
        if not os.path.exists(ui_filename):
            raise IOError('File %s not found' % ui_filename)

        self.service = service
        self.runtime_updater = RuntimeUpdater()
        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None
        self.selected_runner = None

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)

        # Load settings
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        window = self.builder.get_object('window')
        window.resize(width, height)
        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = \
            settings.read_setting('filter_installed') == 'true'
        self.sidebar_visible = \
            settings.read_setting('sidebar_visible') in ['true', None]

        # Set theme to dark if set in the settings
        dark_theme_menuitem = self.builder.get_object('dark_theme_menuitem')
        use_dark_theme = settings.read_setting('dark_theme') == 'true'
        dark_theme_menuitem.set_active(use_dark_theme)
        self.set_dark_theme(use_dark_theme)

        self.game_list = pga.get_games()

        # Load view
        self.game_store = GameStore([], self.icon_type, self.filter_installed)
        self.view = self.get_view(view_type)

        self.main_box = self.builder.get_object('main_box')
        self.splash_box = self.builder.get_object('splash_box')
        self.connect_link = self.builder.get_object('connect_link')
        # View menu
        installed_games_only_menuitem =\
            self.builder.get_object('filter_installed')
        installed_games_only_menuitem.set_active(self.filter_installed)
        self.grid_view_menuitem = self.builder.get_object("gridview_menuitem")
        self.grid_view_menuitem.set_active(view_type == 'grid')
        self.list_view_menuitem = self.builder.get_object("listview_menuitem")
        self.list_view_menuitem.set_active(view_type == 'list')
        sidebar_menuitem = self.builder.get_object('sidebar_menuitem')
        sidebar_menuitem.set_active(self.sidebar_visible)

        # View buttons
        self.grid_view_btn = self.builder.get_object('switch_grid_view_btn')
        self.grid_view_btn.set_active(view_type == 'grid')
        self.list_view_btn = self.builder.get_object('switch_list_view_btn')
        self.list_view_btn.set_active(view_type == 'list')
        # Icon type menu
        self.banner_small_menuitem = \
            self.builder.get_object('banner_small_menuitem')
        self.banner_small_menuitem.set_active(self.icon_type == 'banner_small')
        self.banner_menuitem = self.builder.get_object('banner_menuitem')
        self.banner_menuitem.set_active(self.icon_type == 'banner')
        self.icon_menuitem = self.builder.get_object('icon_menuitem')
        self.icon_menuitem.set_active(self.icon_type == 'icon')

        self.search_entry = self.builder.get_object('search_entry')
        self.search_entry.connect('icon-press', self.on_clear_search)

        # Scroll window
        self.games_scrollwindow = self.builder.get_object('games_scrollwindow')
        self.games_scrollwindow.add(self.view)
        # Buttons
        self.stop_button = self.builder.get_object('stop_button')
        self.stop_button.set_sensitive(False)
        self.delete_button = self.builder.get_object('delete_button')
        self.delete_button.set_sensitive(False)
        self.play_button = self.builder.get_object('play_button')
        self.play_button.set_sensitive(False)

        # Contextual menu
        main_entries = [
            ('play', "Play", self.on_game_run),
            ('install', "Install", self.on_install_clicked),
            ('add', "Add manually", self.on_add_manually),
            ('configure', "Configure", self.on_edit_game_configuration),
            ('browse', "Browse files", self.on_browse_files),
            ('desktop-shortcut', "Create desktop shortcut",
             self.create_desktop_shortcut),
            ('rm-desktop-shortcut', "Delete desktop shortcut",
             self.remove_desktop_shortcut),
            ('menu-shortcut', "Create application menu shortcut",
             self.create_menu_shortcut),
            ('rm-menu-shortcut', "Delete application menu shortcut",
             self.remove_menu_shortcut),
            ('install_more', "Install (add) another version",
             self.on_install_clicked),
            ('remove', "Remove", self.on_remove_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        self.sidebar_paned = self.builder.get_object('sidebar_paned')
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect('cursor-changed',
                                      self.on_sidebar_changed)
        self.sidebar_viewport = self.builder.get_object('sidebar_viewport')
        self.sidebar_viewport.add(self.sidebar_treeview)

        # Window initialization
        self.window = self.builder.get_object("window")
        self.window.resize_to_geometry(width, height)
        self.window.set_default_icon_name('lutris')
        self.window.show_all()
        self.builder.connect_signals(self)
        self.connect_signals()

        self.statusbar = self.builder.get_object("statusbar")

        # XXX Hide PGA config menu item until it actually gets implemented
        pga_menuitem = self.builder.get_object('pga_menuitem')
        pga_menuitem.hide()

        # Sync local lutris library with current Steam games before setting up
        # view
        steam.sync_with_lutris()

        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.show_sidebar()
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status)]
        steamapps_paths = steam.get_steamapps_paths(flat=True)
        self.steam_watcher = steam.SteamWatcher(steamapps_paths,
                                                self.on_steam_game_changed)
예제 #34
0
 def sync_db(self, *args):
     api.sync()
     game_list = pga.get_games()
     resources.fetch_banners([game_info['slug'] for game_info in game_list],
                             callback=self.on_image_downloaded)
예제 #35
0
 def sync_icons(self):
     game_list = pga.get_games()
     resources.fetch_icons([game_info['slug'] for game_info in game_list],
                           callback=self.on_image_downloaded)
예제 #36
0
파일: test_pga.py 프로젝트: dacp17/lutris
 def test_does_set_installed_games(self):
     pga.add_game(name="some game", runner='linux', directory="/home")
     pga.set_installed_games()
     test_game = pga.get_games()[0]
     self.assertEqual(test_game['installed'], 1)
예제 #37
0
    def __init__(self, application, **kwargs):
        self.application = application
        self.runtime_updater = RuntimeUpdater()
        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None
        self.selected_runner = None
        self.selected_platform = None
        self.icon_type = None

        # Load settings
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        self.maximized = settings.read_setting('maximized') == 'True'

        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = settings.read_setting(
            'filter_installed') == 'true'
        self.show_installed_first = \
            settings.read_setting('show_installed_first') == 'true'
        self.sidebar_visible = \
            settings.read_setting('sidebar_visible') in ['true', None]
        self.sidebar_width = int(settings.read_setting('sidebar_width') or 180)
        self.use_dark_theme = settings.read_setting(
            'dark_theme', default='false').lower() == 'true'
        self.show_tray_icon = settings.read_setting(
            'show_tray_icon', default='false').lower() == 'true'

        # Sync local lutris library with current Steam games and desktop games
        for service in get_services_synced_at_startup():
            service.sync_with_lutris()

        # Window initialization
        self.game_list = pga.get_games(
            show_installed_first=self.show_installed_first)
        self.game_store = GameStore([], self.icon_type, self.filter_installed,
                                    self.show_installed_first)
        self.view = self.get_view(view_type)
        super().__init__(default_width=width,
                         default_height=height,
                         icon_name='lutris',
                         application=application,
                         **kwargs)
        if self.maximized:
            self.maximize()
        self.init_template()
        self._init_actions()

        # Set theme to dark if set in the settings
        self.set_dark_theme(self.use_dark_theme)

        # Load view
        self.games_scrollwindow.add(self.view)
        self.connect_signals()
        self.view.show()

        # Contextual menu
        main_entries = [
            ('play', "Play", self.on_game_run),
            ('install', "Install", self.on_install_clicked),
            ('add', "Add manually", self.on_add_manually),
            ('configure', "Configure", self.on_edit_game_configuration),
            ('execute-script', "Execute script",
             self.on_execute_script_clicked),
            ('browse', "Browse files", self.on_browse_files),
            ('desktop-shortcut', "Create desktop shortcut",
             self.create_desktop_shortcut),
            ('rm-desktop-shortcut', "Delete desktop shortcut",
             self.remove_desktop_shortcut),
            ('menu-shortcut', "Create application menu shortcut",
             self.create_menu_shortcut),
            ('rm-menu-shortcut', "Delete application menu shortcut",
             self.remove_menu_shortcut),
            ('install_more', "Install (add) another version",
             self.on_install_clicked),
            ('remove', "Remove", self.on_remove_game),
            ('view', "View on Lutris.net", self.on_view_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect('cursor-changed',
                                      self.on_sidebar_changed)
        self.sidebar_viewport.add(self.sidebar_treeview)
        self.sidebar_treeview.show()

        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.show_sidebar()
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status)]
        steamapps_paths = steam.get_steamapps_paths(flat=True)
        self.steam_watcher = SteamWatcher(steamapps_paths,
                                          self.on_steam_game_changed)

        self.gui_needs_update = True
        self.config_menu_first_access = True
예제 #38
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        # Set up logger
        if options.contains('debug'):
            logger.setLevel(logging.DEBUG)

        # Text only commands

        # List game
        if options.contains('list-games'):
            game_list = pga.get_games()
            if options.contains('installed'):
                game_list = [game for game in game_list if game['installed']]
            if options.contains('json'):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        # List Steam games
        elif options.contains('list-steam-games'):
            self.print_steam_list(command_line)
            return 0
        # List Steam folders
        elif options.contains('list-steam-folders'):
            self.print_steam_folders(command_line)
            return 0

        # Execute command in Lutris context
        elif options.contains('exec'):
            command = options.lookup_value('exec').get_string()
            self.execute_command(command)
            return 0

        try:
            url = options.lookup_value(GLib.OPTION_REMAINING)
            installer_info = self.get_lutris_action(url)
        except ValueError:
            self._print(command_line, '%s is not a valid URI' % url.get_strv())
            return 1
        game_slug = installer_info['game_slug']
        action = installer_info['action']
        revision = installer_info['revision']

        installer_file = None
        if options.contains('install'):
            installer_file = options.lookup_value('install').get_string()
            installer_file = os.path.abspath(installer_file)
            action = 'install'
            if not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

        # Graphical commands
        self.activate()

        db_game = None
        if game_slug:
            if action == 'rungameid':
                # Force db_game to use game id
                db_game = pga.get_game_by_field(game_slug, 'id')
            elif action == 'rungame':
                # Force db_game to use game slug
                db_game = pga.get_game_by_field(game_slug, 'slug')
            elif action == 'install':
                # Installers can use game or installer slugs
                db_game = (pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

            else:
                # Dazed and confused, try anything that might works
                db_game = (pga.get_game_by_field(game_slug, 'id') or
                           pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

        if not action:
            if db_game and db_game['installed']:
                # Game found but no action provided, ask what to do
                dlg = InstallOrPlayDialog(db_game['name'])
                if not dlg.action_confirmed:
                    action = None
                if dlg.action == 'play':
                    action = 'rungame'
                elif dlg.action == 'install':
                    action = 'install'
            elif game_slug or installer_file:
                # No game found, default to install if a game_slug or
                # installer_file is provided
                action = 'install'

        if action == 'install':
            self.window.on_install_clicked(game_slug=game_slug,
                                           installer_file=installer_file,
                                           revision=revision)
        elif action in ('rungame', 'rungameid'):
            if not db_game or not db_game['id']:
                logger.info("No game found in library, shutting down")
                self.do_shutdown()
                return 0
            
            logger.info("Launching %s" % db_game['name'])

            # If game is installed, run it without showing the GUI
            # Also set a timer to shut down lutris when game ends
            if db_game['installed']:
                self.window.hide()
                self.window.on_game_run(game_id=db_game['id'])
                GLib.timeout_add(300, self.refresh_status)
            # If game is not installed, show the GUI
            else:
                self.window.on_game_run(game_id=db_game['id'])


        return 0
예제 #39
0
def get_game_list(filter_installed=False):
    return [Game(game['slug'])
            for game in pga.get_games(filter_installed=filter_installed)]
예제 #40
0
 def sync_icons(self):
     game_list = pga.get_games()
     resources.fetch_banners([game_info['slug'] for game_info in game_list],
                             callback=self.on_image_downloaded)
예제 #41
0
def get_game_list(filter_installed=False):
    return [Game(game['slug'])
            for game in pga.get_games(filter_installed=filter_installed)]
예제 #42
0
def migrate():
    for game in get_games():
        if not game["playtime"]:
            continue
        fix_playtime(game)
예제 #43
0
파일: test_pga.py 프로젝트: Yilnis/lutris-1
 def test_delete_game(self):
     pga.delete_game(self.game_id)
     game_list = pga.get_games()
     self.assertEqual(len(game_list), 0)
     self.game_id = pga.add_game(name="LutrisTest", runner="Linux")
예제 #44
0
    def __init__(self, service=None):

        Gtk.Application.__init__(
            self, application_id="net.lutris.main",
            flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE
        )
        ui_filename = os.path.join(
            datapath.get(), 'ui', 'lutris-window.ui'
        )
        if not os.path.exists(ui_filename):
            raise IOError('File %s not found' % ui_filename)

        self.service = service
        self.runtime_updater = RuntimeUpdater()
        self.running_game = None
        self.threads_stoppers = []

        # Emulate double click to workaround GTK bug #484640
        # https://bugzilla.gnome.org/show_bug.cgi?id=484640
        self.game_selection_time = 0
        self.game_launch_time = 0
        self.last_selected_game = None
        self.selected_runner = None

        self.builder = Gtk.Builder()
        self.builder.add_from_file(ui_filename)

        # Load settings
        width = int(settings.read_setting('width') or 800)
        height = int(settings.read_setting('height') or 600)
        self.window_size = (width, height)
        window = self.builder.get_object('window')
        window.resize(width, height)
        view_type = self.get_view_type()
        self.load_icon_type_from_settings(view_type)
        self.filter_installed = \
            settings.read_setting('filter_installed') == 'true'
        self.sidebar_visible = \
            settings.read_setting('sidebar_visible') in ['true', None]

        # Set theme to dark if set in the settings
        dark_theme_menuitem = self.builder.get_object('dark_theme_menuitem')
        use_dark_theme = settings.read_setting('dark_theme') == 'true'
        dark_theme_menuitem.set_active(use_dark_theme)
        self.set_dark_theme(use_dark_theme)

        self.game_list = pga.get_games()

        # Load view
        self.game_store = GameStore([], self.icon_type, self.filter_installed)
        self.view = self.get_view(view_type)

        self.main_box = self.builder.get_object('main_box')
        self.splash_box = self.builder.get_object('splash_box')
        self.connect_link = self.builder.get_object('connect_link')
        # View menu
        installed_games_only_menuitem =\
            self.builder.get_object('filter_installed')
        installed_games_only_menuitem.set_active(self.filter_installed)
        self.grid_view_menuitem = self.builder.get_object("gridview_menuitem")
        self.grid_view_menuitem.set_active(view_type == 'grid')
        self.list_view_menuitem = self.builder.get_object("listview_menuitem")
        self.list_view_menuitem.set_active(view_type == 'list')
        sidebar_menuitem = self.builder.get_object('sidebar_menuitem')
        sidebar_menuitem.set_active(self.sidebar_visible)

        # View buttons
        self.grid_view_btn = self.builder.get_object('switch_grid_view_btn')
        self.grid_view_btn.set_active(view_type == 'grid')
        self.list_view_btn = self.builder.get_object('switch_list_view_btn')
        self.list_view_btn.set_active(view_type == 'list')
        # Icon type menu
        self.banner_small_menuitem = \
            self.builder.get_object('banner_small_menuitem')
        self.banner_small_menuitem.set_active(self.icon_type == 'banner_small')
        self.banner_menuitem = self.builder.get_object('banner_menuitem')
        self.banner_menuitem.set_active(self.icon_type == 'banner')
        self.icon_menuitem = self.builder.get_object('icon_menuitem')
        self.icon_menuitem.set_active(self.icon_type == 'icon')

        self.search_entry = self.builder.get_object('search_entry')
        self.search_entry.connect('icon-press', self.on_clear_search)

        # Scroll window
        self.games_scrollwindow = self.builder.get_object('games_scrollwindow')
        self.games_scrollwindow.add(self.view)
        # Buttons
        self.stop_button = self.builder.get_object('stop_button')
        self.stop_button.set_sensitive(False)
        self.delete_button = self.builder.get_object('delete_button')
        self.delete_button.set_sensitive(False)
        self.play_button = self.builder.get_object('play_button')
        self.play_button.set_sensitive(False)

        # Contextual menu
        main_entries = [
            ('play', "Play", self.on_game_run),
            ('install', "Install", self.on_install_clicked),
            ('add', "Add manually", self.on_add_manually),
            ('configure', "Configure", self.on_edit_game_configuration),
            ('browse', "Browse files", self.on_browse_files),
            ('desktop-shortcut', "Create desktop shortcut",
             self.create_desktop_shortcut),
            ('rm-desktop-shortcut', "Delete desktop shortcut",
             self.remove_desktop_shortcut),
            ('menu-shortcut', "Create application menu shortcut",
             self.create_menu_shortcut),
            ('rm-menu-shortcut', "Delete application menu shortcut",
             self.remove_menu_shortcut),
            ('install_more', "Install (add) another version", self.on_install_clicked),
            ('remove', "Remove", self.on_remove_game),
        ]
        self.menu = ContextualMenu(main_entries)
        self.view.contextual_menu = self.menu

        # Sidebar
        self.sidebar_paned = self.builder.get_object('sidebar_paned')
        self.sidebar_treeview = SidebarTreeView()
        self.sidebar_treeview.connect('cursor-changed', self.on_sidebar_changed)
        self.sidebar_viewport = self.builder.get_object('sidebar_viewport')
        self.sidebar_viewport.add(self.sidebar_treeview)

        # Window initialization
        self.window = self.builder.get_object("window")
        self.window.resize_to_geometry(width, height)
        self.window.set_default_icon_name('lutris')
        self.window.show_all()
        self.builder.connect_signals(self)
        self.connect_signals()

        self.statusbar = self.builder.get_object("statusbar")

        # XXX Hide PGA config menu item until it actually gets implemented
        pga_menuitem = self.builder.get_object('pga_menuitem')
        pga_menuitem.hide()

        # Sync local lutris library with current Steam games before setting up
        # view
        steam.sync_with_lutris()

        self.game_store.fill_store(self.game_list)
        self.switch_splash_screen()

        self.show_sidebar()
        self.update_runtime()

        # Connect account and/or sync
        credentials = api.read_api_key()
        if credentials:
            self.on_connect_success(None, credentials)
        else:
            self.toggle_connection(False)
            self.sync_library()

        # Timers
        self.timer_ids = [GLib.timeout_add(300, self.refresh_status)]
        steamapps_paths = steam.get_steamapps_paths(flat=True)
        self.steam_watcher = steam.SteamWatcher(steamapps_paths,
                                                self.on_steam_game_changed)
예제 #45
0
파일: test_pga.py 프로젝트: Yilnis/lutris-1
 def test_filter(self):
     pga.add_game(name="foobar", runner="Linux")
     pga.add_game(name="bang", runner="Linux")
     game_list = pga.get_games(name_filter='bang')
     self.assertEqual(len(game_list), 1)
     self.assertEqual(game_list[0]['name'], 'bang')
예제 #46
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        if options.contains('debug'):
            logger.setLevel(logging.DEBUG)

        if options.contains('list-games'):
            game_list = pga.get_games()
            if options.contains('installed'):
                game_list = [game for game in game_list if game['installed']]
            if options.contains('json'):
                    games = []
                    for game in game_list:
                        games.append({
                            'id': game['id'],
                            'slug': game['slug'],
                            'name': game['name'],
                            'runner': game['runner'],
                            'directory': game['directory']
                        })
                    self._print(command_line, json.dumps(games, indent=2))
            else:
                for game in game_list:
                    self._print(
                        command_line,
                        "{:4} | {:<40} | {:<40} | {:<15} | {:<64}".format(
                            game['id'],
                            game['name'][:40],
                            game['slug'][:40],
                            game['runner'] or '-',
                            game['directory'] or '-'
                        )
                    )
            return 0

        if options.contains('list-steam-games'):
            steamapps_paths = get_steamapps_paths()
            for platform in ('linux', 'windows'):
                for path in steamapps_paths[platform]:
                    appmanifest_files = get_appmanifests(path)
                    for appmanifest_file in appmanifest_files:
                        appmanifest = AppManifest(os.path.join(path, appmanifest_file))
                        self._print(
                            command_line,
                            "  {:8} | {:<60} | {:10} | {}".format(
                                appmanifest.steamid,
                                appmanifest.name or '-',
                                platform,
                                ", ".join(appmanifest.states)
                            )
                        )
            return 0

        if options.contains('list-steam-folders'):
            steamapps_paths = get_steamapps_paths()
            for platform in ('linux', 'windows'):
                for path in steamapps_paths[platform]:
                    self._print(command_line, path)
            return 0

        check_config(force_wipe=False)
        migrate()
        game = None

        game_slug = ''
        uri = options.lookup_value(GLib.OPTION_REMAINING)
        if uri:
            uri = uri.get_strv()
        if uri and len(uri):
            uri = uri[0]  # TODO: Support multiple
            if not uri.startswith('lutris:'):
                self._print(command_line, '%s is not a valid URI' % uri)
                return 1
            game_slug = uri[7:]

        if game_slug or options.contains('install'):
            if options.contains('install'):
                installer_file = options.lookup_value('install').get_string()
                installer = installer_file
            else:
                installer_file = None
                installer = game_slug
            if not game_slug and not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

            db_game = None
            if game_slug:
                db_game = (pga.get_game_by_field(game_slug, 'id')
                           or pga.get_game_by_field(game_slug, 'slug')
                           or pga.get_game_by_field(game_slug, 'installer_slug'))

            if db_game and db_game['installed'] and not options.contains('reinstall'):
                self._print(command_line, "Launching %s" % db_game['name'])
                if self.window:
                    self.run_game(db_game['id'])
                else:
                    lutris_game = Game(db_game['id'])
                    # FIXME: This is awful
                    lutris_game.exit_main_loop = True
                    lutris_game.play()
                    try:
                        GLib.MainLoop().run()
                    except KeyboardInterrupt:
                        lutris_game.stop()
                return 0
            else:
                self._print(command_line, "Installing %s" % installer)
                if self.window:
                    self.install_game(installer)
                else:
                    runtime_updater = RuntimeUpdater()
                    runtime_updater.update()
                    # FIXME: This should be a Gtk.Dialog child of LutrisWindow
                    dialog = InstallerDialog(installer)
                    self.add_window(dialog)
                return 0

        self.activate()
        return 0
예제 #47
0
    def __init__(
        self,
        games,
        icon_type,
        filter_installed,
        sort_key,
        sort_ascending,
        show_hidden_games,
        show_installed_first=False,
    ):
        super(GameStore, self).__init__()
        self.games = games or pga.get_games(
            show_installed_first=show_installed_first)
        if not show_hidden_games:
            # Check if the PGA contains game IDs that the user does not
            # want to see
            self.games = [
                game for game in self.games
                if game["id"] not in pga.get_hidden_ids()
            ]

        self.search_mode = False
        self.games_to_refresh = set()
        self.icon_type = icon_type
        self.filter_installed = filter_installed
        self.show_installed_first = show_installed_first
        self.filter_text = None
        self.filter_runner = None
        self.filter_platform = None
        self.store = Gtk.ListStore(
            int,
            str,
            str,
            Pixbuf,
            str,
            str,
            str,
            str,
            int,
            str,
            bool,
            int,
            str,
            float,
            str,
        )
        sort_col = COL_NAME
        if show_installed_first:
            sort_col = COL_INSTALLED
            self.store.set_sort_column_id(sort_col, Gtk.SortType.DESCENDING)
        else:
            self.store.set_sort_column_id(sort_col, Gtk.SortType.ASCENDING)
        self.prevent_sort_update = False  # prevent recursion with signals
        self.modelfilter = self.store.filter_new()
        self.modelfilter.set_visible_func(self.filter_view)
        try:
            self.modelsort = Gtk.TreeModelSort.sort_new_with_model(
                self.modelfilter)
        except AttributeError:
            # Apparently some API breaking changes on GTK minor versions.
            self.modelsort = Gtk.TreeModelSort.new_with_model(self.modelfilter)  # pylint: disable=no-member  # NOQA
        self.modelsort.connect("sort-column-changed",
                               self.on_sort_column_changed)
        self.modelsort.set_sort_func(sort_col, sort_func, sort_col)
        self.sort_view(sort_key, sort_ascending)
        self.medias = {"banner": {}, "icon": {}}
        self.banner_misses = set()
        self.icon_misses = set()
        self.media_loaded = False
        self.connect("media-loaded", self.on_media_loaded)
        self.connect("icon-loaded", self.on_icon_loaded)
예제 #48
0
    def do_command_line(self, command_line):
        options = command_line.get_options_dict()

        if options.contains('debug'):
            logger.setLevel(logging.DEBUG)

        if options.contains('list-games'):
            game_list = pga.get_games()
            if options.contains('installed'):
                game_list = [game for game in game_list if game['installed']]
            if options.contains('json'):
                self.print_game_json(command_line, game_list)
            else:
                self.print_game_list(command_line, game_list)
            return 0
        elif options.contains('list-steam-games'):
            self.print_steam_list(command_line)
            return 0
        elif options.contains('list-steam-folders'):
            self.print_steam_folders(command_line)
            return 0
        elif options.contains('exec'):
            command = options.lookup_value('exec').get_string()
            self.execute_command(command)
            return 0

        check_config(force_wipe=False)
        migrate()

        game_slug = ''
        uri = options.lookup_value(GLib.OPTION_REMAINING)
        if uri:
            uri = uri.get_strv()
        if uri and len(uri):
            uri = uri[0]  # TODO: Support multiple
            if not uri.startswith('lutris:'):
                self._print(command_line, '%s is not a valid URI' % uri)
                return 1
            game_slug = uri[7:]

        if game_slug or options.contains('install'):
            if options.contains('install'):
                installer_file = options.lookup_value('install').get_string()
                installer = installer_file
            else:
                installer_file = None
                installer = game_slug
            if not game_slug and not os.path.isfile(installer_file):
                self._print(command_line, "No such file: %s" % installer_file)
                return 1

            db_game = None
            if game_slug:
                db_game = (pga.get_game_by_field(game_slug, 'id')
                           or pga.get_game_by_field(game_slug, 'slug') or
                           pga.get_game_by_field(game_slug, 'installer_slug'))

            if db_game and db_game['installed'] and not options.contains(
                    'reinstall'):
                self._print(command_line, "Launching %s" % db_game['name'])
                if self.window:
                    self.run_game(db_game['id'])
                else:
                    lutris_game = Game(db_game['id'])
                    # FIXME: This is awful
                    lutris_game.exit_main_loop = True
                    lutris_game.play()
                    try:
                        GLib.MainLoop().run()
                    except KeyboardInterrupt:
                        lutris_game.stop()
                return 0
            else:
                self._print(command_line, "Installing %s" % installer)
                if self.window:
                    self.install_game(installer)
                else:
                    runtime_updater = RuntimeUpdater()
                    runtime_updater.update()
                    # FIXME: This should be a Gtk.Dialog child of LutrisWindow
                    dialog = InstallerDialog(installer)
                    self.add_window(dialog)
                return 0

        self.activate()
        return 0