Esempio n. 1
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)
Esempio n. 2
0
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
Esempio n. 3
0
    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")
Esempio n. 4
0
    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")
Esempio n. 5
0
    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)
Esempio n. 6
0
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
Esempio n. 7
0
    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)
Esempio n. 8
0
 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, []
Esempio n. 9
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())
Esempio n. 10
0
 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
Esempio n. 11
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)
     }
     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"])
Esempio n. 12
0
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])
Esempio n. 13
0
 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, []
Esempio n. 14
0
 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, []
Esempio n. 15
0
    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)
Esempio n. 16
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)
     }
     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)
Esempio n. 17
0
    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)