Example #1
0
    def add_installed_games(self):
        """Syncs installed Steam games with Lutris"""
        installed_appids = []
        for steamapps_path in self.steamapps_paths:
            for appmanifest_file in get_appmanifests(steamapps_path):
                app_manifest_path = os.path.join(steamapps_path,
                                                 appmanifest_file)
                app_manifest = AppManifest(app_manifest_path)
                installed_appids.append(app_manifest.steamid)
                self.install_from_steam(app_manifest)

        db_games = get_games(filters={"runner": "steam"})
        for db_game in db_games:
            steam_game = Game(db_game["id"])
            appid = steam_game.config.game_level["game"]["appid"]
            if appid not in installed_appids:
                steam_game.remove(no_signal=True)

        db_appids = defaultdict(list)
        db_games = get_games(filters={"service": "steam"})
        for db_game in db_games:
            db_appids[db_game["service_id"]].append(db_game["id"])

        for appid in db_appids:
            game_ids = db_appids[appid]
            if len(game_ids) == 1:
                continue
            for game_id in game_ids:
                steam_game = Game(game_id)
                if not steam_game.playtime:
                    steam_game.remove(no_signal=True)
                    steam_game.delete()
Example #2
0
    def get_service_games(self, service_name):
        """Switch the current service to service_name and return games if available"""
        service_games = ServiceGameCollection.get_for_service(service_name)
        if service_name == "lutris":
            lutris_games = {g["slug"]: g for g in games_db.get_games()}
        else:
            lutris_games = {
                g["service_id"]: g
                for g in games_db.get_games(
                    filters={"service": self.service.id})
            }

        def get_sort_value(game):
            sort_defaults = {
                "name": "",
                "year": 0,
                "lastplayed": 0.0,
                "installed_at": 0.0,
                "playtime": 0.0,
            }
            lutris_game = lutris_games.get(game["appid"])
            if not lutris_game:
                return sort_defaults[self.view_sorting]
            value = lutris_game[self.view_sorting]
            if value:
                return value
            return sort_defaults[self.view_sorting]

        return [
            self.combine_games(game, lutris_games.get(game["appid"]))
            for game in sorted(service_games,
                               key=get_sort_value,
                               reverse=not self.view_sorting_ascending)
            if self.game_matches(game)
        ]
Example #3
0
    def switch_to_service(self, service_name):
        """Switch the current service to service_name and return games if available"""
        def combine_games(service_game, lutris_game):
            if not lutris_game or service_game["appid"] != lutris_game[
                    "service_id"]:
                return service_game
            for field in ("platform", "runner", "year", "installed_at",
                          "lastplayed", "playtime", "installed"):
                service_game[field] = lutris_game[field]
            return service_game

        self.set_service(service_name)
        if service_name == "lutris":
            self.tabs_box.show(
            )  # Only the lutris service has the ability to search through all games.
            if self.website_button.props.active:
                return self.get_api_games()
        else:
            self.tabs_box.hide()

        service_games = ServiceGameCollection.get_for_service(service_name)
        if service_name == "lutris":
            lutris_games = {g["slug"]: g for g in games_db.get_games()}
        else:
            lutris_games = {
                g["service_id"]: g
                for g in games_db.get_games(
                    filters={"service": self.service.id})
            }

        def get_sort_value(game):
            sort_defaults = {
                "name": "",
                "year": 0,
                "lastplayed": 0.0,
                "installed_at": 0.0,
                "playtime": 0.0,
            }
            lutris_game = lutris_games.get(game["appid"])
            if not lutris_game:
                return sort_defaults[self.view_sorting]
            value = lutris_game[self.view_sorting]
            if value:
                return value
            return sort_defaults[self.view_sorting]

        if service_games:
            return [
                combine_games(game, lutris_games.get(game["appid"]))
                for game in sorted(service_games,
                                   key=get_sort_value,
                                   reverse=not self.view_sorting_ascending)
                if self.game_matches(game)
            ]
        if self.service.online and not self.service.is_connected():
            self.show_label(
                _("Connect your %s account to access your games") %
                self.service.name)
        return
Example #4
0
 def match_games(self):
     """Matching lutris games is much simpler... No API call needed."""
     service_games = {
         str(game["appid"]): game for game in ServiceGameCollection.get_for_service(self.id)
     }
     for lutris_game in get_games():
         self.match_game(service_games.get(lutris_game["slug"]), lutris_game)
Example #5
0
    def install(self, db_game):
        """Install a service game"""
        appid = db_game["appid"]
        logger.debug("Installing %s from service %s", appid, self.id)
        if self.local:
            return self.simple_install(db_game)
        service_installers = self.get_installers_from_api(appid)
        # Check if the game is not already installed
        for service_installer in service_installers:
            existing_game = self.match_existing_game(
                get_games(filters={
                    "installer_slug": service_installer["slug"],
                    "installed": "1"
                }), appid)
            if existing_game:
                return
        if not service_installers:
            installer = self.generate_installer(db_game)
            if installer:
                service_installers.append(installer)
        if not service_installers:
            logger.error("No installer found for %s", db_game)
            return

        application = Gio.Application.get_default()
        application.show_installer_window(service_installers,
                                          service=self,
                                          appid=appid)
Example #6
0
 def get_games_from_filters(self):
     service_name = self.filters.get("service")
     if service_name in services.get_services():
         self.set_service(service_name)
         service_games = ServiceGameCollection.get_for_service(service_name)
         if service_games:
             return [
                 game
                 for game in sorted(service_games,
                                    key=lambda game: game.get(
                                        self.view_sorting) or game["name"],
                                    reverse=not self.view_sorting_ascending)
                 if self.game_matches(game)
             ]
         if self.service.online and not self.service.is_connected():
             self.show_label(
                 _("Connect your %s account to access your games") %
                 self.service.name)
         return
     self.unset_service()
     dynamic_categories = {
         "running": self.get_running_games,
         "installed": self.get_installed_games
     }
     if self.filters.get("dynamic_category") in dynamic_categories:
         return dynamic_categories[self.filters["dynamic_category"]]()
     if self.filters.get("category"):
         game_ids = categories_db.get_game_ids_for_category(
             self.filters["category"])
         return games_db.get_games_by_ids(game_ids)
     searches, filters, excludes = self.get_sql_filters()
     return games_db.get_games(searches=searches,
                               filters=filters,
                               excludes=excludes,
                               sorts=self.sort_params)
Example #7
0
 def test_get_game_list(self):
     self.game_id = games_db.add_game(name="LutrisTest", runner="Linux")
     game_list = games_db.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')
Example #8
0
 def match_games(self):
     """Matching of service games to lutris games"""
     service_games = {
         str(game["appid"]): game
         for game in ServiceGameCollection.get_for_service(self.id)
     }
     logger.debug("Matching games %s", service_games)
     lutris_games = api.get_api_games(list(service_games.keys()),
                                      service=self.id)
     for lutris_game in lutris_games:
         for provider_game in lutris_game["provider_games"]:
             if provider_game["service"] != self.id:
                 continue
             self.match_game(service_games.get(provider_game["slug"]),
                             lutris_game)
     unmatched_service_games = get_games(
         searches={"installer_slug": self.matcher},
         excludes={"service": self.id})
     for lutris_game in api.get_api_games(
             game_slugs=[g["slug"] for g in unmatched_service_games]):
         for provider_game in lutris_game["provider_games"]:
             if provider_game["service"] != self.id:
                 continue
             self.match_game(service_games.get(provider_game["slug"]),
                             lutris_game)
Example #9
0
 def get_games_from_filters(self):
     service_name = self.filters.get("service")
     if service_name in services.SERVICES:
         if self.service.online and not self.service.is_authenticated():
             self.show_label(
                 _("Connect your %s account to access your games") %
                 self.service.name)
             return []
         return self.get_service_games(service_name)
     dynamic_categories = {
         "recent": self.get_recent_games,
         "running": self.get_running_games,
     }
     if self.filters.get("dynamic_category") in dynamic_categories:
         return dynamic_categories[self.filters["dynamic_category"]]()
     if self.filters.get("category") and self.filters["category"] != "all":
         game_ids = categories_db.get_game_ids_for_category(
             self.filters["category"])
     else:
         game_ids = None
     searches, filters, excludes = self.get_sql_filters()
     games = games_db.get_games(searches=searches,
                                filters=filters,
                                excludes=excludes,
                                sorts=self.sort_params)
     if game_ids is not None:
         return [game for game in games if game["id"] in game_ids]
     return games
Example #10
0
 def get_games_from_filters(self):
     service_name = self.filters.get("service")
     self.tabs_box.hide()
     if service_name in services.get_services():
         if service_name == "lutris":
             self.tabs_box.show(
             )  # Only the lutris service has the ability to search through all games.
             if self.website_button.props.active:
                 return self.get_api_games()
         if self.service.online and not self.service.is_authenticated():
             self.show_label(
                 _("Connect your %s account to access your games") %
                 self.service.name)
             return []
         return self.get_service_games(service_name)
     dynamic_categories = {
         "recent": self.get_recent_games,
         "running": self.get_running_games,
     }
     if self.filters.get("dynamic_category") in dynamic_categories:
         return dynamic_categories[self.filters["dynamic_category"]]()
     if self.filters.get("category") and self.filters["category"] != "all":
         game_ids = categories_db.get_game_ids_for_category(
             self.filters["category"])
         return games_db.get_games_by_ids(game_ids)
     searches, filters, excludes = self.get_sql_filters()
     return games_db.get_games(searches=searches,
                               filters=filters,
                               excludes=excludes,
                               sorts=self.sort_params)
Example #11
0
 def match_game(self, service_game, api_game):
     """Match a service game to a lutris game referenced by its slug"""
     if not service_game:
         return
     logger.debug("Matching service game %s with API game %s", service_game, api_game)
     conditions = {"appid": service_game["appid"], "service": self.id}
     sql.db_update(
         PGA_DB,
         "service_games",
         {"lutris_slug": api_game["slug"]},
         conditions=conditions
     )
     unmatched_lutris_games = get_games(
         searches={"installer_slug": self.matcher},
         filters={"slug": api_game["slug"]},
         excludes={"service": self.id}
     )
     for game in unmatched_lutris_games:
         logger.debug("Updating unmatched game %s", game)
         sql.db_update(
             PGA_DB,
             "games",
             {"service": self.id, "service_id": service_game["appid"]},
             conditions={"id": game["id"]}
         )
Example #12
0
    def get_games_from_filters(self):
        if self.filters.get("service"):
            service_name = self.filters["service"]
            if service_name in services.get_services():
                self.service = services.get_services()[service_name]()
                if self.service.online:
                    self.service.connect("service-login",
                                         self.on_service_games_updated)
                    self.service.connect("service-logout",
                                         self.on_service_logout)
                self.service.connect("service-games-loaded",
                                     self.on_service_games_updated)

                service_games = ServiceGameCollection.get_for_service(
                    service_name)
                if service_games:
                    return [
                        game for game in sorted(
                            service_games,
                            key=lambda game: game.get(self.view_sorting) or
                            game["name"],
                            reverse=not self.view_sorting_ascending,
                        ) if self.game_matches(game)
                    ]

                if not self.service.online or self.service.is_connected():
                    AsyncCall(self.service.load, None)
                    spinner = Gtk.Spinner(visible=True)
                    spinner.start()
                    self.blank_overlay.add(spinner)
                else:
                    self.blank_overlay.add(
                        Gtk.Label(
                            _("Connect your %s account to access your games") %
                            self.service.name,
                            visible=True,
                        ))
                self.blank_overlay.props.visible = True
                return
            self.unset_service()
        dynamic_categories = {
            "running": self.get_running_games,
            "installed": self.get_installed_games,
        }
        if self.filters.get("dynamic_category") in dynamic_categories:
            return dynamic_categories[self.filters["dynamic_category"]]()
        self.unset_service()
        if self.filters.get("category"):
            game_ids = categories_db.get_game_ids_for_category(
                self.filters["category"])
            return games_db.get_games_by_ids(game_ids)

        searches, filters, excludes = self.get_sql_filters()
        return games_db.get_games(
            searches=searches,
            filters=filters,
            excludes=excludes,
            sorts=self.sort_params,
        )
Example #13
0
 def add_games():
     """Adds installed games in order of last use"""
     installed_games = get_games(filters={"installed": 1})
     installed_games.sort(
         key=lambda game: max(game["lastplayed"] or 0, game["installed_at"] or 0),
         reverse=True,
     )
     return installed_games
Example #14
0
 def installed_game_slugs(self):
     previous_access = self._installed_games_accessed or 0
     self._installed_games_accessed = time.time()
     if self._installed_games_accessed - previous_access > 1:
         self._installed_games = [
             g["slug"] for g in get_games(filters={"installed": "1"})
         ]
     return self._installed_games
Example #15
0
 def get_recent_games(self):
     """Return a list of currently running games"""
     searches, _filters, excludes = self.get_sql_filters()
     games = games_db.get_games(searches=searches, filters={'installed': '1'}, excludes=excludes)
     return sorted(
         games,
         key=lambda game: max(game["installed_at"] or 0, game["lastplayed"] or 0),
         reverse=True
     )
Example #16
0
def sync_media():
    """Downlad all missing media"""
    banners_available = {
        fn.split(".")[0]
        for fn in os.listdir(settings.BANNER_PATH)
    }
    icons_available = {
        fn.split(".")[0].replace("lutris_", "")
        for fn in os.listdir(settings.ICON_PATH) if fn.startswith("lutris_")
    }
    covers_available = {
        fn.split(".")[0]
        for fn in os.listdir(settings.COVERART_PATH)
    }
    complete_games = banners_available.intersection(
        icons_available).intersection(covers_available)
    all_slugs = {game["slug"] for game in get_games()}
    slugs = all_slugs - complete_games
    if not slugs:
        return
    games = get_api_games(list(slugs))

    alias_map = {}
    api_slugs = set()
    for game in games:
        api_slugs.add(game["slug"])
        for alias in game["aliases"]:
            if alias["slug"] in slugs:
                alias_map[game["slug"]] = alias["slug"]
    alias_slugs = set(alias_map.values())
    used_alias_slugs = alias_slugs - api_slugs
    for alias_slug in used_alias_slugs:
        for game in games:
            if alias_slug in [alias["slug"] for alias in game["aliases"]]:
                game["slug"] = alias_map[game["slug"]]
                continue
    banner_urls = {
        game["slug"]: game["banner_url"]
        for game in games
        if game["slug"] not in banners_available and game["banner_url"]
    }
    icon_urls = {
        game["slug"]: game["icon_url"]
        for game in games
        if game["slug"] not in icons_available and game["icon_url"]
    }
    cover_urls = {
        game["slug"]: game["coverart"]
        for game in games
        if game["slug"] not in covers_available and game["coverart"]
    }
    logger.debug("Syncing %s banners, %s icons and %s covers",
                 len(banner_urls), len(icon_urls), len(cover_urls))
    download_media(banner_urls, LutrisBanner())
    download_media(icon_urls, LutrisIcon())
    download_media(cover_urls, LutrisCoverart())
Example #17
0
def migrate():
    """Run migration"""
    for pga_game in get_games():
        game = Game(pga_game["id"])
        if game.runner_name != "mess":
            continue
        if "mess" in game.config.game_level:
            game.config.game_level["mame"] = game.config.game_level.pop("mess")
        game.runner_name = "mame"
        game.save()
Example #18
0
    def __init__(self, game_id, parent=None):
        super().__init__(parent=parent)
        self.set_size_request(640, 128)
        self.game = Game(game_id)
        self.delete_files = False
        container = Gtk.VBox(visible=True)
        self.get_content_area().add(container)

        title_label = Gtk.Label(visible=True)
        title_label.set_line_wrap(True)
        title_label.set_alignment(0, 0.5)
        title_label.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
        title_label.set_markup(
            "<span font_desc='14'><b>Uninstall %s</b></span>" %
            gtk_safe(self.game.name))

        container.pack_start(title_label, False, False, 4)

        self.folder_label = Gtk.Label(visible=True)
        self.folder_label.set_alignment(0, 0.5)

        self.delete_button = Gtk.Button(_("Uninstall"), visible=True)
        self.delete_button.connect("clicked", self.on_delete_clicked)

        if not self.game.directory:
            self.folder_label.set_markup("No file will be deleted")
        elif len(get_games(searches={"directory": self.game.directory})) > 1:
            self.folder_label.set_markup(
                "The folder %s is used by other games and will be kept." %
                self.game.directory)
        elif is_removeable(self.game.directory):
            self.delete_button.set_sensitive(False)
            self.folder_label.set_markup("<i>Calculating sizeā€¦</i>")
            AsyncCall(get_disk_size, self.folder_size_cb, self.game.directory)
        else:
            self.folder_label.set_markup(
                "Content of %s are protected and will not be deleted." %
                reverse_expanduser(self.game.directory))
        container.pack_start(self.folder_label, False, False, 4)

        self.confirm_delete_button = Gtk.CheckButton()
        self.confirm_delete_button.set_active(True)
        container.pack_start(self.confirm_delete_button, False, False, 4)

        button_box = Gtk.HBox(visible=True)
        button_box.set_margin_top(30)
        style_context = button_box.get_style_context()
        style_context.add_class("linked")
        cancel_button = Gtk.Button(_("Cancel"), visible=True)
        cancel_button.connect("clicked", self.on_close)
        button_box.add(cancel_button)
        button_box.add(self.delete_button)
        container.pack_end(button_box, False, False, 0)
        self.show()
Example #19
0
def migrate():
    """Run migration"""
    for game in get_games():
        if not game.get("steamid"):
            continue
        if game["runner"] and game["runner"] != "steam":
            continue
        print("Migrating Steam game %s" % game["name"])
        sql.db_update(settings.PGA_DB, "games", {
            "service": "steam",
            "service_id": game["steamid"]
        }, {"id": game["id"]})
Example #20
0
def fill_missing_platforms():
    """Sets the platform on games where it's missing.
    This should never happen.
    """
    pga_games = get_games(filters={"installed": 1})
    for pga_game in pga_games:
        if pga_game.get("platform") or not pga_game["runner"]:
            continue
        game = Game(game_id=pga_game["id"])
        game.set_platform_from_runner()
        if game.platform:
            logger.info("Platform for %s set to %s", game.name, game.platform)
            game.save(save_config=False)
Example #21
0
    def get_service_games(self, service_name):
        """Switch the current service to service_name and return games if available"""
        service_games = ServiceGameCollection.get_for_service(service_name)
        if service_name == "lutris":
            lutris_games = {g["slug"]: g for g in games_db.get_games()}
        else:
            lutris_games = {
                g["service_id"]: g
                for g in games_db.get_games(
                    filters={"service": self.service.id})
            }

        def get_sort_value(game):
            sort_defaults = {
                "name": "",
                "year": 0,
                "lastplayed": 0.0,
                "installed_at": 0.0,
                "playtime": 0.0,
            }
            view_sorting = self.view_sorting
            lutris_game = lutris_games.get(game["appid"])
            if not lutris_game:
                return sort_defaults.get(view_sorting, "")
            value = lutris_game.get(view_sorting)
            if value:
                return value
            # Users may have obsolete view_sorting settings, so
            # we must tolerate them. We treat them all as blank.
            return sort_defaults.get(view_sorting, "")

        return [
            self.combine_games(game, lutris_games.get(game["appid"]))
            for game in sorted(service_games,
                               key=get_sort_value,
                               reverse=not self.view_sorting_ascending)
            if self.game_matches(game)
        ]
Example #22
0
    def install(self, db_game, update=False):
        """Install a service game, or starts the installer of the game.

        Args:
            db_game (dict or str): Database fields of the game to add, or (for Lutris service only
                the slug of the game.)

        Returns:
            str: The slug of the game that was installed, to be run. None if the game should not be
                run now. Many installers start from here, but continue running after this returns;
                they return None.
        """
        appid = db_game["appid"]
        logger.debug("Installing %s from service %s", appid, self.id)

        # Local services (aka game libraries that don't require any type of online interaction) can
        # be added without going through an install dialog.
        if self.local:
            return self.simple_install(db_game)
        if update:
            service_installers = self.get_update_installers(db_game)
        else:
            service_installers = self.get_installers_from_api(appid)
        # Check if the game is not already installed
        for service_installer in service_installers:
            existing_game = self.match_existing_game(
                get_games(filters={
                    "installer_slug": service_installer["slug"],
                    "installed": "1"
                }), appid)
            if existing_game:
                logger.debug("Found existing game, aborting install")
                return
        if update:
            installer = None
        else:
            installer = self.generate_installer(db_game)
        if installer:
            if service_installers:
                installer[
                    "version"] = installer["version"] + " (auto-generated)"
            service_installers.append(installer)
        if not service_installers:
            logger.error("No installer found for %s", db_game)
            return

        application = Gio.Application.get_default()
        application.show_installer_window(service_installers,
                                          service=self,
                                          appid=appid)
Example #23
0
 def install(self, db_game):
     appid = db_game["appid"]
     db_games = get_games(filters={"service_id": appid, "installed": "1", "service": "steam"})
     existing_game = self.match_existing_game(db_games, appid)
     if existing_game:
         logger.debug("Found steam game: %s", existing_game)
         game = Game(existing_game.id)
         game.save()
         return
     service_installers = self.get_installers_from_api(appid)
     if not service_installers:
         service_installers = [self.generate_installer(db_game)]
     application = Gio.Application.get_default()
     application.show_installer_window(service_installers, service=self, appid=appid)
Example #24
0
def scan_directory(dirname):
    files = os.listdir(dirname)
    folder_extentions = {os.path.splitext(filename)[1] for filename in files}
    core_matches = {}
    for core in RECOMMENDED_CORES:
        for ext in RECOMMENDED_CORES[core].get("extensions", []):
            if ext in folder_extentions:
                core_matches[ext] = core
    added_games = []
    for filename in files:
        name, ext = os.path.splitext(filename)
        if ext not in core_matches:
            continue
        for flag in ROM_FLAGS:
            name = name.replace(" (%s)" % flag, "")
        for flag in EXTRA_FLAGS:
            name = name.replace("[%s]" % flag, "")
        if ", The" in name:
            name = "The %s" % name.replace(", The", "")
        name = name.strip()
        print("Importing '%s'" % name)
        slug = slugify(name)
        core = core_matches[ext]
        config = {
            "game": {
                "core": core_matches[ext],
                "main_file": os.path.join(dirname, filename)
            }
        }
        installer_slug = "%s-libretro-%s" % (slug, core)
        existing_game = get_games(filters={
            "installer_slug": installer_slug,
            "installed": "1"
        })
        if existing_game:
            game = Game(existing_game[0]["id"])
            game.remove()
        configpath = write_game_config(slug, config)
        game_id = add_game(name=name,
                           runner="libretro",
                           slug=slug,
                           directory=dirname,
                           installed=1,
                           installer_slug=installer_slug,
                           configpath=configpath)
        print("Imported %s" % name)
        added_games.append(game_id)
    return added_games
Example #25
0
 def get_games_from_filters(self):
     service_name = self.filters.get("service")
     if service_name in services.get_services():
         return self.switch_to_service(service_name)
     self.unset_service()
     dynamic_categories = {
         "recent": self.get_recent_games,
         "running": self.get_running_games,
     }
     if self.filters.get("dynamic_category") in dynamic_categories:
         return dynamic_categories[self.filters["dynamic_category"]]()
     if self.filters.get("category") and self.filters["category"] != "all":
         game_ids = categories_db.get_game_ids_for_category(
             self.filters["category"])
         return games_db.get_games_by_ids(game_ids)
     searches, filters, excludes = self.get_sql_filters()
     return games_db.get_games(searches=searches,
                               filters=filters,
                               excludes=excludes,
                               sorts=self.sort_params)
Example #26
0
 def install(self, db_game):
     steam_game = get_game_by_field(self.client_installer, "installer_slug")
     if not steam_game:
         installers = get_installers(game_slug=self.client_installer, )
     else:
         installers = [self.generate_installer(db_game, steam_game)]
         appid = db_game["appid"]
         db_games = get_games(filters={
             "service_id": appid,
             "installed": "1",
             "service": self.id
         })
         existing_game = self.match_existing_game(db_games, appid)
         if existing_game:
             logger.debug("Found steam game: %s", existing_game)
             game = Game(existing_game.id)
             game.save()
             return
     application = Gio.Application.get_default()
     application.show_installer_window(installers,
                                       service=self,
                                       appid=appid)
Example #27
0
    def install(self, db_game):
        """Install a service game, or starts the installer of the game.

        Args:
            db_game (dict or str): Database fields of the game to add, or (for Lutris service only
                the slug of the game.)

        Returns:
            str: The slug of the game that was installed, to be run. None if the game should not be
                run now. Many installers start from here, but continue running after this returns;
                they return None.
        """
        appid = db_game["appid"]
        logger.debug("Installing %s from service %s", appid, self.id)
        if self.local:
            return self.simple_install(db_game)
        service_installers = self.get_installers_from_api(appid)
        # Check if the game is not already installed
        for service_installer in service_installers:
            existing_game = self.match_existing_game(
                get_games(filters={
                    "installer_slug": service_installer["slug"],
                    "installed": "1"
                }), appid)
            if existing_game:
                return
        if not service_installers:
            installer = self.generate_installer(db_game)
            if installer:
                service_installers.append(installer)
        if not service_installers:
            logger.error("No installer found for %s", db_game)
            return

        application = Gio.Application.get_default()
        application.show_installer_window(service_installers,
                                          service=self,
                                          appid=appid)
Example #28
0
def scan_directory(dirname):
    """Add a directory of ROMs as Lutris games"""
    files = os.listdir(dirname)
    folder_extentions = {os.path.splitext(filename)[1] for filename in files}
    core_matches = {}
    for core in RECOMMENDED_CORES:
        for ext in RECOMMENDED_CORES[core].get("extensions", []):
            if ext in folder_extentions:
                core_matches[ext] = core
    added_games = []
    for filename in files:
        name, ext = os.path.splitext(filename)
        if ext not in core_matches:
            continue
        logger.info("Importing '%s'", name)
        slug = slugify(name)
        core = core_matches[ext]
        config = {
            "game": {
                "core": core_matches[ext],
                "main_file": os.path.join(dirname, filename)
            }
        }
        installer_slug = "%s-libretro-%s" % (slug, core)
        existing_game = get_games(filters={"installer_slug": installer_slug})
        if existing_game:
            game = Game(existing_game[0]["id"])
            game.remove()
        configpath = write_game_config(slug, config)
        game_id = add_game(name=name,
                           runner="libretro",
                           slug=slug,
                           directory=dirname,
                           installed=1,
                           installer_slug=installer_slug,
                           configpath=configpath)
        added_games.append(game_id)
    return added_games
Example #29
0
    def install(self, db_game):
        steam_game = get_game_by_field("steam-wine", "installer_slug")
        if not steam_game:
            logger.error("Steam for Windows is not installed in Lutris")
            return

        appid = db_game["appid"]
        db_games = get_games(filters={
            "service_id": appid,
            "installed": "1",
            "service": self.id
        })
        existing_game = self.match_existing_game(db_games, appid)
        if existing_game:
            logger.debug("Found steam game: %s", existing_game)
            game = Game(existing_game.id)
            game.save()
            return
        application = Gio.Application.get_default()
        application.show_installer_window(
            [self.generate_installer(db_game, steam_game)],
            service=self,
            appid=appid)
Example #30
0
 def get_media_urls(self):
     return {
         game["slug"]: self.url_pattern % game["slug"]
         for game in get_games()
     }