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)
def scan_directory(dirname): slugs_map = get_game_slugs_and_folders(dirname) directories = get_used_directories() api_games = get_api_games(list(slugs_map.keys())) slugs_seen = set() slugs_installed = set() for api_game in api_games: if api_game["slug"] in slugs_seen: continue slugs_seen.add(api_game["slug"]) game_folder = find_game_folder(dirname, api_game, slugs_map) if game_folder in directories: slugs_installed.add(api_game["slug"]) continue full_path, installer = find_game(game_folder, api_game) if full_path: logger.info("Found %s in %s", api_game["name"], full_path) try: install_game(installer, game_folder) except MissingGameDependency as ex: logger.error("Skipped %s: %s", api_game["name"], ex) download_lutris_media(installer["game_slug"]) slugs_installed.add(api_game["slug"]) installed_map = {slug: folder for slug, folder in slugs_map.items() if slug in slugs_installed} missing_map = {slug: folder for slug, folder in slugs_map.items() if slug not in slugs_installed} return installed_map, missing_map
def get_missing_media(self, slugs=None): """Query the Lutris.net API for missing icons""" slugs = slugs or self.game_slugs unavailable_banners = [ slug for slug in slugs if not self.has_icon(slug, "banner") ] unavailable_icons = [ slug for slug in slugs if not self.has_icon(slug, "icon") ] # Remove duplicate slugs missing_media_slugs = list( set(unavailable_banners) | set(unavailable_icons)) if not missing_media_slugs: return logger.debug("Requesting missing icons from API for %d games", len(missing_media_slugs)) lutris_media = api.get_api_games(missing_media_slugs) if not lutris_media: return for game in lutris_media: if game["slug"] in unavailable_banners and game["banner_url"]: self.medias["banner"][game["slug"]] = game["banner_url"] if game["slug"] in unavailable_icons and game["icon_url"]: self.medias["icon"][game["slug"]] = game["icon_url"] self.media_loaded = True self.emit("media-loaded")
def get_missing_media(self, slugs=None): """Query the Lutris.net API for missing icons""" slugs = slugs or self.game_slugs unavailable_banners = {slug for slug in slugs if not self.has_icon(slug, "banner")} unavailable_icons = {slug for slug in slugs if not self.has_icon(slug, "icon")} # Remove duplicate slugs missing_media_slugs = ((unavailable_banners - self.banner_misses) | (unavailable_icons - self.icon_misses)) if not missing_media_slugs: return if len(missing_media_slugs) > 10: logger.debug("Requesting missing icons from API for %d games", len(missing_media_slugs)) else: logger.debug("Requesting missing icons from API for %s", ", ".join(missing_media_slugs)) lutris_media = api.get_api_games(list(missing_media_slugs), inject_aliases=True) if not lutris_media: return for game in lutris_media: if game["slug"] in unavailable_banners and game["banner_url"]: self.medias["banner"][game["slug"]] = game["banner_url"] unavailable_banners.remove(game["slug"]) if game["slug"] in unavailable_icons and game["icon_url"]: self.medias["icon"][game["slug"]] = game["icon_url"] unavailable_icons.remove(game["slug"]) self.banner_misses = unavailable_banners self.icon_misses = unavailable_icons self.media_loaded = True self.emit("media-loaded")
def run_no_installer_dialog(self): """Open dialog for 'no script available' situation.""" dlg = NoInstallerDialog(self) if dlg.result == dlg.MANUAL_CONF: game_data = pga.get_game_by_field(self.game_slug, "slug") if game_data and "slug" in game_data: # Game data already exist locally. game = Game(game_data["id"]) else: # Try to load game data from remote. games = api.get_api_games([self.game_slug]) if games and len(games) >= 1: remote_game = games[0] game_data = { "name": remote_game["name"], "slug": remote_game["slug"], "year": remote_game["year"], "updated": remote_game["updated"], "steamid": remote_game["steamid"], } game = Game(pga.add_game(**game_data)) else: game = None AddGameDialog(self.parent, game=game) elif dlg.result == dlg.NEW_INSTALLER: webbrowser.open(settings.GAME_URL % self.game_slug)
def get_missing_media(game_slugs): """Query the Lutris.net API for missing icons""" unavailable_banners = [ slug for slug in game_slugs if not has_icon(slug, BANNER) ] unavailable_icons = [ slug for slug in game_slugs if not has_icon(slug, ICON) ] # Remove duplicate slugs missing_media_slugs = list( set(unavailable_banners) | set(unavailable_icons)) if not missing_media_slugs: return logger.debug("Requesting missing icons from API for %d games", len(missing_media_slugs)) lutris_media = api.get_api_games(missing_media_slugs) if not lutris_media: logger.warning("Unable to get games, check your network connectivity") return available_banners = {} available_icons = {} for game in lutris_media: if game["slug"] in unavailable_banners and game["banner_url"]: available_banners[game["slug"]] = game["banner_url"] if game["slug"] in unavailable_icons and game["icon_url"]: available_icons[game["slug"]] = game["icon_url"] return available_banners, available_icons
def sync(cls, games, full=False): """Import GOG games to the Lutris library""" gog_ids = [game.appid for game in games] if not gog_ids: return ([], []) lutris_games = api.get_api_games(gog_ids, query_type="gogid") added_games = [] for game in lutris_games: lutris_data = pga.get_game_by_field(game["slug"], field="slug") or {} game_data = { "name": game["name"], "slug": game["slug"], "installed": lutris_data.get("installed"), "configpath": lutris_data.get("configpath"), "year": game["year"], "updated": game["updated"], "gogid": game.get( "gogid" ), # GOG IDs will be added at a later stage in the API } added_games.append(pga.add_or_update(**game_data)) if not full: return added_games, games return added_games, []
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())
def get_installers_from_api(self, appid): """Query the lutris API for an appid and get existing installers for the service""" lutris_games = api.get_api_games([appid], service=self.id) service_installers = [] if lutris_games: lutris_game = lutris_games[0] installers = fetch_script(lutris_game["slug"]) for installer in installers: if self.matcher in installer["version"].lower(): service_installers.append(installer) return service_installers
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) } 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["slug"])
def fetch_icon(slug, callback): lutris_media = api.get_api_games([slug]) if not lutris_media: return game = lutris_media[0] for media_type in ('banner', 'icon'): url = game.get("%s_url" % media_type) if url: download_media( url, get_icon_path(slug, BANNER if media_type == "banner" else ICON)) else: logger.error("No URL found in %s", game) callback([slug])
def sync(cls, games, full=False): """Import GOG games to the Lutris library""" gog_ids = [game.appid for game in games] if not gog_ids: return ([], []) lutris_games = api.get_api_games(gog_ids, query_type="gogid") added_games = [] for game in lutris_games: game_data = { "name": game["name"], "slug": game["slug"], "year": game["year"], "updated": game["updated"], "gogid": game.get("gogid"), # GOG IDs will be added at a later stage in the API } added_games.append(pga.add_or_update(**game_data)) if not full: return added_games return added_games, []
def sync(cls, games, full=True): """Import Humble Bundle games to the library""" humbleids = [game.appid for game in games] if not humbleids: return ([], []) lutris_games = api.get_api_games(humbleids, query_type="humblestoreid") added_games = [] for game in lutris_games: game_data = { "name": game["name"], "slug": game["slug"], "year": game["year"], "updated": game["updated"], "humblestoreid": game["humblestoreid"], } added_games.append(pga.add_or_update(**game_data)) if not full: return added_games, games return added_games, []
def install(self, db_game): appid = db_game["appid"] logger.debug("Installing %s from service %s", appid, self.id) lutris_games = api.get_api_games([appid], service=self.id) service_installers = [] if lutris_games: lutris_game = lutris_games[0] installers = fetch_script(lutris_game["slug"]) for installer in installers: if self.matcher in installer["version"].lower(): service_installers.append(installer) if not service_installers: installer = self.generate_installer(db_game) if installer: service_installers.append(installer) if service_installers: application = Gio.Application.get_default() application.show_installer_window(service_installers, service=self, appid=appid)
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) } 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 service_game = service_games.get(provider_game["slug"]) if not service_game: continue conditions = { "appid": service_game["appid"], "service": self.id } sql.db_update(PGA_DB, "service_games", {"lutris_slug": lutris_game["slug"]}, conditions=conditions)
def manually_configure_game(self): game_data = pga.get_game_by_field(self.game_slug, "slug") if game_data and "slug" in game_data: # Game data already exist locally. game = Game(game_data["id"]) else: # Try to load game data from remote. games = api.get_api_games([self.game_slug]) if games and len(games) >= 1: remote_game = games[0] game_data = { "name": remote_game["name"], "slug": remote_game["slug"], "year": remote_game["year"], "updated": remote_game["updated"], "steamid": remote_game["steamid"], } game = Game(pga.add_game(**game_data)) else: game = None AddGameDialog(self.parent, game=game)