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')
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)
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
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()
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
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)
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
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
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()
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)
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)
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 )
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
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
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
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()
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
def test_get_games_is_safe(self): try: pga.get_games(select="; asdf") except OperationalError: self.fail()
def __init__(self): self.library = pga.get_games()
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
def get_game_list(): games = pga.get_games() return [game['id'] for game in games]
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
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)
def migrate(): for game in get_games(): if not game["playtime"]: continue fix_playtime(game)
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')
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)
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')
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)
def get_game_list(filter_installed=False): games = pga.get_games(filter_installed=filter_installed) return [game['slug'] for game in games]
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)
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)
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)
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
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
def get_game_list(filter_installed=False): return [Game(game['slug']) for game in pga.get_games(filter_installed=filter_installed)]
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)
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")
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)
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')
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
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)
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