Esempio n. 1
0
def sync_game_details(remote_library):
    """Update local game details,

    :return: A set of ids of the updated games.
    """
    if not remote_library:
        return set()
    updated = set()

    for remote_game in remote_library:
        slug = remote_game["slug"]
        sync_required = False
        local_game = pga.get_game_by_field(slug, "slug")
        if not local_game:
            continue
        if local_game[
                "updated"] and remote_game["updated"] > local_game["updated"]:
            # The remote game's info is more recent than the local game
            sync_required = True
        else:
            for key in remote_game.keys():
                if (key in local_game.keys() and remote_game[key]
                        and not local_game[key]):
                    # Remote game has data that is missing from the local game.
                    logger.info("Key %s is not present, forcing update", key)
                    sync_required = True
                    break

        if not sync_required:
            continue

        logger.debug("Syncing details for %s", slug)
        game_id = pga.add_or_update(
            id=local_game["id"],
            name=local_game["name"],
            runner=local_game["runner"],
            slug=slug,
            year=remote_game["year"],
            updated=remote_game["updated"],
            steamid=remote_game["steamid"],
        )
        updated.add(game_id)

        if not local_game.get(
                "has_custom_banner") and remote_game["banner_url"]:
            path = resources.get_icon_path(slug, resources.BANNER)
            resources.download_media(remote_game["banner_url"],
                                     path,
                                     overwrite=True)
        if not local_game.get("has_custom_icon") and remote_game["icon_url"]:
            path = resources.get_icon_path(slug, resources.ICON)
            resources.download_media(remote_game["icon_url"],
                                     path,
                                     overwrite=True)

    if updated:
        logger.debug("%d games updated", len(updated))
    return updated
Esempio n. 2
0
def sync_game_details(remote_library):
    """Update local game details,

    :return: A set of ids of the updated games.
    """
    if not remote_library:
        return set()
    updated = set()

    for remote_game in remote_library:
        slug = remote_game['slug']
        sync_required = False
        local_game = pga.get_game_by_field(slug, 'slug')
        if not local_game:
            continue

        if local_game[
                'updated'] and remote_game['updated'] > local_game['updated']:
            # The remote game's info is more recent than the local game
            sync_required = True
        else:
            for key in remote_game.keys():
                if key in local_game.keys(
                ) and remote_game[key] and not local_game[key]:
                    # Remote game has data that is missing from the local game.
                    sync_required = True
                    break

        if not sync_required:
            continue

        logger.debug("Syncing details for %s" % slug)
        game_id = pga.add_or_update(name=local_game['name'],
                                    runner=local_game['runner'],
                                    slug=slug,
                                    year=remote_game['year'],
                                    updated=remote_game['updated'],
                                    steamid=remote_game['steamid'])
        updated.add(game_id)

        if not local_game.get(
                'has_custom_banner') and remote_game['banner_url']:
            path = resources.get_icon_path(slug, resources.BANNER)
            resources.download_media(remote_game['banner_url'],
                                     path,
                                     overwrite=True)
        if not local_game.get('has_custom_icon') and remote_game['icon_url']:
            path = resources.get_icon_path(slug, resources.ICON)
            resources.download_media(remote_game['icon_url'],
                                     path,
                                     overwrite=True)

    if updated:
        logger.debug("%d games updated", len(updated))
    return updated
Esempio n. 3
0
 def on_custom_image_reset_clicked(self, _widget, image_type):
     if image_type == "banner":
         self.game.has_custom_banner = False
         dest_path = resources.get_icon_path(self.game.slug, icon_type="banner")
     elif image_type == "icon":
         self.game.has_custom_icon = False
         dest_path = resources.get_icon_path(self.game.slug, icon_type="icon")
     else:
         raise ValueError("Unsupported image type %s" % image_type)
     os.remove(dest_path)
     self._set_image(image_type)
Esempio n. 4
0
File: sync.py Progetto: Freso/lutris
def sync_game_details(remote_library):
    """Update local game details,

    :return: A set of ids of the updated games.
    """
    if not remote_library:
        return set()
    updated = set()

    for remote_game in remote_library:
        slug = remote_game['slug']
        sync_required = False
        local_game = pga.get_game_by_field(slug, 'slug')
        if not local_game:
            continue

        if local_game['updated'] and remote_game['updated'] > local_game['updated']:
            # The remote game's info is more recent than the local game
            sync_required = True
        else:
            for key in remote_game.keys():
                if key in local_game.keys() and remote_game[key] and not local_game[key]:
                    # Remote game has data that is missing from the local game.
                    sync_required = True
                    break

        if not sync_required:
            continue

        logger.debug("Syncing details for %s" % slug)
        game_id = pga.add_or_update(
            name=local_game['name'],
            runner=local_game['runner'],
            slug=slug,
            year=remote_game['year'],
            updated=remote_game['updated'],
            steamid=remote_game['steamid']
        )
        updated.add(game_id)

        if not local_game.get('has_custom_banner') and remote_game['banner_url']:
            path = resources.get_icon_path(slug, resources.BANNER)
            resources.download_media(remote_game['banner_url'], path, overwrite=True)
        if not local_game.get('has_custom_icon') and remote_game['icon_url']:
            path = resources.get_icon_path(slug, resources.ICON)
            resources.download_media(remote_game['icon_url'], path, overwrite=True)

    if updated:
        logger.debug("%d games updated", len(updated))
    return updated
Esempio n. 5
0
    def on_custom_image_select(self, _widget, image_type):
        dialog = Gtk.FileChooserNative.new(
            _("Please choose a custom image"),
            self,
            Gtk.FileChooserAction.OPEN,
            None,
            None,
        )

        image_filter = Gtk.FileFilter()
        image_filter.set_name(_("Images"))
        image_filter.add_pixbuf_formats()
        dialog.add_filter(image_filter)

        response = dialog.run()
        if response == Gtk.ResponseType.ACCEPT:
            image_path = dialog.get_filename()
            if image_type == "banner":
                self.game.has_custom_banner = True
                dest_path = os.path.join(settings.BANNER_PATH, "%s.jpg" % self.game.slug)
                size = BANNER_SIZE
                file_format = "jpeg"
            else:
                self.game.has_custom_icon = True
                dest_path = resources.get_icon_path(self.game.slug)
                size = ICON_SIZE
                file_format = "png"
            pixbuf = get_pixbuf(image_path, size)
            pixbuf.savev(dest_path, file_format, [], [])
            self._set_image(image_type)

            if image_type == "icon":
                system.update_desktop_icons()

        dialog.destroy()
Esempio n. 6
0
def get_pixbuf_for_game(game_slug, icon_type, is_installed=True):
    if icon_type.startswith("banner"):
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_banner.png")
        icon_path = resources.get_banner_path(game_slug)
    elif icon_type.startswith("icon"):
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_icon.png")
        icon_path = resources.get_icon_path(game_slug)
    else:
        logger.error("Invalid icon type '%s'", icon_type)
        return None

    size = IMAGE_SIZES[icon_type]

    pixbuf = get_pixbuf(icon_path, size, fallback=default_icon_path)
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(),
                                                "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Esempio n. 7
0
def get_pixbuf_for_game(game_slug, icon_type, is_installed=True):
    if icon_type.startswith("banner"):
        default_icon_path = os.path.join(datapath.get(), "media/default_banner.png")
        icon_path = resources.get_banner_path(game_slug)
    elif icon_type.startswith("icon"):
        default_icon_path = os.path.join(datapath.get(), "media/default_icon.png")
        icon_path = resources.get_icon_path(game_slug)
    else:
        logger.error("Invalid icon type '%s'", icon_type)
        return None

    size = IMAGE_SIZES[icon_type]

    pixbuf = get_pixbuf(icon_path, size, fallback=default_icon_path)
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(), "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Esempio n. 8
0
 def on_media_loaded(self, _response):
     """Callback to handle a response from the API with the new media"""
     if not self.medias:
         return
     for media_type in ("banner", "icon"):
         self.download_icons([(slug, self.medias[media_type][slug],
                               get_icon_path(slug, media_type))
                              for slug in self.medias[media_type]],
                             media_type)
Esempio n. 9
0
    def fetch_icon(self, slug):
        if not self.media_loaded:
            self.games_to_refresh.add(slug)
            return

        for media_type in ('banner', 'icon'):
            url = self.medias[media_type].get(slug)
            if url:
                download_media(url, get_icon_path(slug, media_type))
                self.emit('icon-loaded', slug, media_type)
Esempio n. 10
0
    def fetch_icon(self, slug):
        if not self.media_loaded:
            self.games_to_refresh.add(slug)
            return

        for media_type in ("banner", "icon"):
            url = self.medias[media_type].get(slug)
            if url:
                logger.debug("Getting %s for %s: %s", media_type, slug, url)
                download_media(url, get_icon_path(slug, media_type))
                self.emit("icon-loaded", slug, media_type)
Esempio n. 11
0
    def on_custom_image_reset_clicked(self, _widget, image_type):
        dest_path = ""
        if ImageType.banner & image_type:
            self.game.has_custom_banner = False
            dest_path = resources.get_banner_path(self.game.slug)
        if ImageType.icon & image_type:
            self.game.has_custom_icon = False
            dest_path = resources.get_icon_path(self.game.slug)

        os.remove(dest_path)
        self._set_image(image_type)
Esempio n. 12
0
    def on_custom_image_select(self, _widget, image_type):
        dialog = Gtk.FileChooserDialog(
            _("Please choose a custom image"),
            self,
            Gtk.FileChooserAction.OPEN,
            (
                Gtk.STOCK_CANCEL,
                Gtk.ResponseType.CANCEL,
                Gtk.STOCK_OPEN,
                Gtk.ResponseType.OK,
            ),
        )

        image_filter = Gtk.FileFilter()
        image_filter.set_name(_("Images"))
        image_filter.add_pixbuf_formats()
        dialog.add_filter(image_filter)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            image_path = dialog.get_filename()
            if image_type == "banner":
                self.game.has_custom_banner = True
                dest_path = resources.get_icon_path(self.game.slug,
                                                    icon_type=image_type)
                size = BANNER_SIZE
                file_format = "jpeg"
            else:
                self.game.has_custom_icon = True
                dest_path = resources.get_icon_path(self.game.slug,
                                                    icon_type="icon")
                size = ICON_SIZE
                file_format = "png"
            pixbuf = get_pixbuf(image_path, size)
            pixbuf.savev(dest_path, file_format, [], [])
            self._set_image(image_type)

            if image_type == "icon":
                system.update_desktop_icons()

        dialog.destroy()
Esempio n. 13
0
 def on_custom_image_reset_clicked(self, _widget, image_type):
     if image_type == "banner":
         self.game.has_custom_banner = False
         dest_path = os.path.join(settings.BANNER_PATH, "%s.jpg" % self.game.slug)
     elif image_type == "icon":
         self.game.has_custom_icon = False
         dest_path = resources.get_icon_path(self.game.slug)
     else:
         raise ValueError("Unsupported image type %s" % image_type)
     if os.path.isfile(dest_path):
         os.remove(dest_path)
     self._set_image(image_type)
Esempio n. 14
0
def sync_game_details(remote_library):
    """Update local game details,

    :return: A set of ids of the updated games.
    """
    if not remote_library:
        return set()
    updated = set()

    for remote_game in remote_library:
        slug = remote_game["slug"]
        sync_required = False
        local_game = pga.get_game_by_field(slug, "slug")
        if not local_game:
            continue
        if local_game["updated"] and remote_game["updated"] > local_game["updated"]:
            # The remote game's info is more recent than the local game
            sync_required = True

        if not sync_required:
            continue

        logger.debug("Syncing details for %s", slug)
        game_id = pga.add_or_update(
            id=local_game["id"],
            name=local_game["name"],
            runner=local_game["runner"],
            slug=slug,
            year=remote_game["year"],
            updated=remote_game["updated"],
            steamid=remote_game["steamid"],
        )
        updated.add(game_id)

        if not local_game.get("has_custom_banner") and remote_game["banner_url"]:
            path = resources.get_banner_path(slug)
            resources.download_media(remote_game["banner_url"], path, overwrite=True)
        if not local_game.get("has_custom_icon") and remote_game["icon_url"]:
            path = resources.get_icon_path(slug)
            resources.download_media(remote_game["icon_url"], path, overwrite=True)

    if updated:
        logger.debug("%d games updated", len(updated))
    return updated
Esempio n. 15
0
def sync_game_details(remote_library):
    """Update local game details,

    :return: A set of ids of the updated games.
    """
    if not remote_library:
        return set()
    updated = set()

    for remote_game in remote_library:
        slug = remote_game["slug"]
        sync_required = False
        local_game = pga.get_game_by_field(slug, "slug")
        if not local_game:
            continue
        if local_game["updated"] and remote_game["updated"] > local_game["updated"]:
            # The remote game's info is more recent than the local game
            sync_required = True

        if not sync_required:
            continue

        logger.debug("Syncing details for %s", slug)
        game_id = pga.add_or_update(
            id=local_game["id"],
            name=local_game["name"],
            runner=local_game["runner"],
            slug=slug,
            year=remote_game["year"],
            updated=remote_game["updated"],
            steamid=remote_game["steamid"],
        )
        updated.add(game_id)

        if not local_game.get("has_custom_banner") and remote_game["banner_url"]:
            path = resources.get_banner_path(slug)
            resources.download_media(remote_game["banner_url"], path, overwrite=True)
        if not local_game.get("has_custom_icon") and remote_game["icon_url"]:
            path = resources.get_icon_path(slug)
            resources.download_media(remote_game["icon_url"], path, overwrite=True)

    if updated:
        logger.debug("%d games updated", len(updated))
    return updated
Esempio n. 16
0
def get_pixbuf_for_game(game_slug, image_type, is_installed=True):
    icon_path = ""
    default_icon_path = ""

    if ImageType.banner & image_type:
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_banner.png")
        icon_path = resources.get_banner_path(game_slug)

    if ImageType.icon == image_type:
        default_icon_path = os.path.join(datapath.get(),
                                         "media/default_icon.png")
        icon_path = resources.get_icon_path(game_slug)

    size = IMAGE_SIZES[image_type]

    pixbuf = get_pixbuf(icon_path, size, fallback=default_icon_path)
    if not is_installed:
        unavailable_game_overlay = os.path.join(datapath.get(),
                                                "media/unavailable.png")
        transparent_pixbuf = get_overlay(unavailable_game_overlay, size).copy()
        pixbuf.composite(
            transparent_pixbuf,
            0,
            0,
            size[0],
            size[1],
            0,
            0,
            1,
            1,
            GdkPixbuf.InterpType.NEAREST,
            100,
        )
        return transparent_pixbuf
    return pixbuf
Esempio n. 17
0
 def has_icon(self, game_slug, media_type=None):
     """Return True if the game_slug has the icon of `icon_type`"""
     media_type = media_type or self.icon_type
     return system.path_exists(get_icon_path(game_slug, media_type))
Esempio n. 18
0
    def on_custom_image_select(self, _widget, image_type):
        dialog = Gtk.FileChooserDialog(
            _("Please choose a custom image"),
            self,
            Gtk.FileChooserAction.OPEN,
            (
                Gtk.STOCK_CANCEL,
                Gtk.ResponseType.CANCEL,
                Gtk.STOCK_OPEN,
                Gtk.ResponseType.OK,
            ),
        )

        image_filter = Gtk.FileFilter()
        image_filter.set_name(_("Images"))
        image_filter.add_pixbuf_formats()
        dialog.add_filter(image_filter)

        try:
            main_file_path = self.game.runner.get_main_file()
        except AttributeError:
            main_file_path = None
        path_type = PATH_TYPE.UNKNOWN
        if ImageType.banner & image_type:
            path_type = PATH_TYPE.BANNER
        if ImageType.icon & image_type:
            path_type = PATH_TYPE.ICON

        def_path = default_path_handler.get(
            # unfortuantely the original path is not stored
            entry=None,
            # No default for images
            default=None,
            main_file_path=main_file_path,
            install_path=self.lutris_config.game_config.get("game_path"),
            path_type=path_type)
        if os.path.isfile(def_path):
            if self.action != Gtk.FileChooserAction.SELECT_FOLDER:
                dialog.set_filename(os.path.basename(def_path))
            def_path = os.path.dirname(def_path)

        dialog.set_current_folder(def_path)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            image_path = dialog.get_filename()
            default_path_handler.set_selected(image_path, image_type)
            file_format = ""
            dest_path = ""
            size = None
            if ImageType.banner & image_type:
                self.game.has_custom_banner = True
                dest_path = resources.get_banner_path(self.game.slug)
                size = BANNER_SIZE
                file_format = "jpeg"
            if ImageType.icon & image_type:
                self.game.has_custom_icon = True
                dest_path = resources.get_icon_path(self.game.slug)
                size = ICON_SIZE
                file_format = "png"

            pixbuf = get_pixbuf(image_path, size)
            pixbuf.savev(dest_path, file_format, [], [])
            self._set_image(image_type)

            if ImageType.icon & image_type:
                resources.update_desktop_icons()

        dialog.destroy()
Esempio n. 19
0
    def play(self):
        url = self.game_config.get("main_file")
        if not url:
            return {
                "error":
                "CUSTOM",
                "text": ("The web address is empty, \n"
                         "verify the game's configuration."),
            }

        # check if it's an url or a file
        is_url = urlparse(url).scheme != ""

        if not is_url:
            if not system.path_exists(url):
                return {
                    "error":
                    "CUSTOM",
                    "text": ("The file " + url + " does not exist, \n"
                             "verify the game's configuration."),
                }
            url = "file://" + url

        game_data = pga.get_game_by_field(self.config.game_config_id,
                                          "configpath")

        # keep the old behavior from browser runner, but with support for extra arguments!
        if self.runner_config.get("external_browser"):
            # is it possible to disable lutris runtime here?
            browser = self.runner_config.get(
                "custom_browser_executable") or "xdg-open"

            args = self.runner_config.get("custom_browser_args")
            if args == "":
                args = '"$GAME"'
            arguments = string.Template(args).safe_substitute({
                "GAME": url,
                "URL": url
            })

            command = [browser]

            for arg in shlex.split(arguments):
                command.append(arg)

            return {"command": command}

        icon = resources.get_icon_path(game_data.get("slug"))
        if not system.path_exists(icon):
            icon = DEFAULT_ICON

        command = [
            self.get_executable(),
            os.path.join(settings.RUNNER_DIR,
                         "web/electron/resources/app.asar"),
            url,
            "--name",
            game_data.get("name"),
            "--icon",
            icon,
        ]

        if self.runner_config.get("fullscreen"):
            command.append("--fullscreen")

        if self.runner_config.get("frameless"):
            command.append("--frameless")

        if self.runner_config.get("disable_resizing"):
            command.append("--disable-resizing")

        if self.runner_config.get("disable_menu_bar"):
            command.append("--disable-menu-bar")

        if self.runner_config.get("window_size"):
            command.append("--window-size")
            command.append(self.runner_config.get("window_size"))

        if self.runner_config.get("maximize_window"):
            command.append("--maximize-window")

        if self.runner_config.get("disable_scrolling"):
            command.append("--disable-scrolling")

        if self.runner_config.get("hide_cursor"):
            command.append("--hide-cursor")

        if self.runner_config.get("open_links"):
            command.append("--open-links")

        if self.runner_config.get("remove_margin"):
            command.append("--remove-margin")

        if self.runner_config.get("devtools"):
            command.append("--devtools")

        return {"command": command, "env": self.get_env(False)}
Esempio n. 20
0
    def play(self):
        url = self.game_config.get("main_file")
        if not url:
            return {
                "error":
                "CUSTOM",
                "text":
                _("The web address is empty, \n"
                  "verify the game's configuration."),
            }

        # check if it's an url or a file
        is_url = urlparse(url).scheme != ""

        if not is_url:
            if not system.path_exists(url):
                return {
                    "error":
                    "CUSTOM",
                    "text":
                    _("The file %s does not exist, \n"
                      "verify the game's configuration.") % url,
                }
            url = "file://" + url

        game_data = get_game_by_field(self.config.game_config_id, "configpath")

        # keep the old behavior from browser runner, but with support for extra arguments!
        if self.runner_config.get("external_browser"):
            # is it possible to disable lutris runtime here?
            browser = self.runner_config.get(
                "custom_browser_executable") or "xdg-open"

            args = self.runner_config.get("custom_browser_args")
            args = args or '"$GAME"'
            arguments = string.Template(args).safe_substitute({
                "GAME": url,
                "URL": url
            })

            command = [browser]

            for arg in split_arguments(arguments):
                command.append(arg)

            return {"command": command}

        icon = resources.get_icon_path(game_data.get("slug"))
        if not system.path_exists(icon):
            icon = DEFAULT_ICON

        command = [
            self.get_executable(),
            os.path.join(settings.RUNNER_DIR,
                         "web/electron/resources/app.asar"),
            url,
            "--name",
            game_data.get("name"),
            "--icon",
            icon,
        ]

        for key in [
                "fullscreen",
                "frameless",
                "devtools",
                "disable_resizing",
                "disable_menu_bar",
                "maximize_window",
                "disable_scrolling",
                "hide_cursor",
                "open_links",
                "remove_margin",
        ]:
            if self.runner_config.get(key):
                converted_opt_name = key.replace("_", "-")
                command.append("--{option}".format(option=converted_opt_name))

        if self.runner_config.get("window_size"):
            command.append("--window-size")
            command.append(self.runner_config.get("window_size"))
        if self.runner_config.get("user_agent"):
            command.append("--user-agent")
            command.append(self.runner_config.get("user_agent"))
        if linux.LINUX_SYSTEM.is_flatpak:
            command.append("--no-sandbox")

        return {"command": command, "env": self.get_env(False)}
Esempio n. 21
0
    def play(self):
        url = self.game_config.get("main_file")
        if not url:
            return {
                "error": "CUSTOM",
                "text": (
                    "The web address is empty, \n" "verify the game's configuration."
                ),
            }

        # check if it's an url or a file
        is_url = urlparse(url).scheme != ""

        if not is_url:
            if not system.path_exists(url):
                return {
                    "error": "CUSTOM",
                    "text": (
                        "The file " + url + " does not exist, \n"
                        "verify the game's configuration."
                    ),
                }
            url = "file://" + url

        game_data = pga.get_game_by_field(self.config.game_config_id, "configpath")

        # keep the old behavior from browser runner, but with support for extra arguments!
        if self.runner_config.get("external_browser"):
            # is it possible to disable lutris runtime here?
            browser = self.runner_config.get("custom_browser_executable") or "xdg-open"

            args = self.runner_config.get("custom_browser_args")
            args = args or '"$GAME"'
            arguments = string.Template(args).safe_substitute({"GAME": url, "URL": url})

            command = [browser]

            for arg in shlex.split(arguments):
                command.append(arg)

            return {"command": command}

        icon = resources.get_icon_path(game_data.get("slug"))
        if not system.path_exists(icon):
            icon = DEFAULT_ICON

        command = [
            self.get_executable(),
            os.path.join(settings.RUNNER_DIR, "web/electron/resources/app.asar"),
            url,
            "--name",
            game_data.get("name"),
            "--icon",
            icon,
        ]

        for key in [
            "fullscreen",
            "frameless",
            "devtools",
            "disable_resizing",
            "disable_menu_bar",
            "maximize_window",
            "disable_scrolling",
            "hide_cursor",
            "open_links",
            "remove_margin",
        ]:
            if self.runner_config.get(key):
                converted_opt_name = key.replace("_", "-")
                command.append("--{option}".format(option=converted_opt_name))

        if self.runner_config.get("window_size"):
            command.append("--window-size")
            command.append(self.runner_config.get("window_size"))

        return {"command": command, "env": self.get_env(False)}