From 24eac24c3398dcdad824f35f911317b39029eec5 Mon Sep 17 00:00:00 2001 From: kramo <93832451+kra-mo@users.noreply.github.com> Date: Tue, 14 Mar 2023 18:42:05 +0100 Subject: [PATCH] Better image handling --- src/game.py | 8 +++++--- src/main.py | 4 ++-- src/utils/bottles_parser.py | 4 ++-- src/utils/create_details_window.py | 7 ++++--- src/utils/get_cover.py | 14 ++++++-------- src/utils/heroic_parser.py | 12 ++++++------ src/utils/save_cover.py | 14 ++++++++------ src/utils/steam_parser.py | 4 ++-- src/window.py | 29 +++++++++++++---------------- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/game.py b/src/game.py index 6122174..63c8131 100644 --- a/src/game.py +++ b/src/game.py @@ -19,6 +19,8 @@ from gi.repository import Gtk +from .get_cover import get_cover + @Gtk.Template(resource_path='/hu/kramo/Cartridges/gtk/game.ui') class game(Gtk.Box): __gtype_name__ = 'game' @@ -33,7 +35,7 @@ class game(Gtk.Box): play_revealer = Gtk.Template.Child() title_revealer = Gtk.Template.Child() - def __init__(self, parent_widget, data, pixbuf, **kwargs): + def __init__(self, parent_widget, data, **kwargs): super().__init__(**kwargs) self.parent_widget = parent_widget @@ -49,10 +51,10 @@ class game(Gtk.Box): else: self.removed = False - self.pixbuf = pixbuf + self.pixbuf = get_cover(self.game_id, self.parent_widget) - self.title.set_label(self.name) self.cover.set_pixbuf(self.pixbuf) + self.title.set_label(self.name) self.event_contoller_motion = Gtk.EventControllerMotion.new() self.add_controller(self.event_contoller_motion) diff --git a/src/main.py b/src/main.py index edc9d1c..fe3435e 100644 --- a/src/main.py +++ b/src/main.py @@ -122,7 +122,7 @@ class CartridgesApplication(Adw.Application): data["last_played"] = int(time.time()) save_games({game_id : data}) - run_command(self.win, self.win.games_temp[self.win.active_game_id].executable) + run_command(self.win, self.win.games[self.win.active_game_id].executable) self.win.update_games([game_id]) @@ -155,7 +155,7 @@ class CartridgesApplication(Adw.Application): self.win.on_go_back_action(None, None) # Create toast for undoing the remove action - toast = Adw.Toast.new(self.win.games_temp[game_id].name + " " + (_("removed"))) + toast = Adw.Toast.new(self.win.games[game_id].name + " " + (_("removed"))) toast.set_button_label(_("Undo")) toast.connect("button-clicked", self.win.on_undo_remove_action, game_id) toast.set_priority(Adw.ToastPriority.HIGH) diff --git a/src/utils/bottles_parser.py b/src/utils/bottles_parser.py index b99f681..69ea015 100644 --- a/src/utils/bottles_parser.py +++ b/src/utils/bottles_parser.py @@ -78,7 +78,7 @@ def bottles_parser(parent_widget, action): values["game_id"] = "bottles_" + game["id"] - if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed: + if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed: continue values["name"] = game["name"] @@ -89,7 +89,7 @@ def bottles_parser(parent_widget, action): values["last_played"] = 0 if game["thumbnail"]: - values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(bottles_dir, "bottles", game["bottle"]["path"], "grids", game["thumbnail"].split(":")[1])) + save_cover(values, parent_widget, os.path.join(bottles_dir, "bottles", game["bottle"]["path"], "grids", game["thumbnail"].split(":")[1])) bottles_games[values["game_id"]] = values diff --git a/src/utils/create_details_window.py b/src/utils/create_details_window.py index d173481..de7b533 100644 --- a/src/utils/create_details_window.py +++ b/src/utils/create_details_window.py @@ -23,6 +23,7 @@ def create_details_window(parent_widget, game_id = None): from .create_dialog import create_dialog from .save_games import save_games from .save_cover import save_cover + from .get_cover import get_cover window = Adw.Window( modal = True, @@ -31,7 +32,7 @@ def create_details_window(parent_widget, game_id = None): transient_for = parent_widget ) - games = parent_widget.games_temp + games = parent_widget.games pixbuf = None if game_id == None: @@ -42,7 +43,7 @@ def create_details_window(parent_widget, game_id = None): apply_button = Gtk.Button.new_with_label(_("Confirm")) else: window.set_title(_("Edit Game Details")) - cover = Gtk.Picture.new_for_pixbuf((parent_widget.visible_widgets | parent_widget.hidden_widgets)[game_id].pixbuf) + cover = Gtk.Picture.new_for_pixbuf(get_cover(game_id, parent_widget)) name = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new(games[game_id].name, -1)) executable = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new((games[game_id].executable), -1)) apply_button = Gtk.Button.new_with_label(_("Apply")) @@ -173,7 +174,7 @@ def create_details_window(parent_widget, game_id = None): return if pixbuf != None: - values["pixbuf_options"] = save_cover(None, parent_widget, None, pixbuf, game_id) + save_cover(None, parent_widget, None, pixbuf, game_id) values["name"] = final_name values["executable"] = final_executable diff --git a/src/utils/get_cover.py b/src/utils/get_cover.py index 9301dfb..e528dba 100644 --- a/src/utils/get_cover.py +++ b/src/utils/get_cover.py @@ -17,17 +17,15 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -def get_cover(game_id, pixbuf_options, parent_widget): +def get_cover(game_id, parent_widget): from gi.repository import GdkPixbuf - import os, zlib + import os - cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game_id + ".dat") + if game_id in parent_widget.pixbufs.keys(): + return parent_widget.pixbufs[game_id] + cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game_id + ".png") if os.path.isfile(cover_path) == False: return parent_widget.placeholder_pixbuf - open_file = open(cover_path, "rb") - data = zlib.decompress(open_file.read()) - open_file.close() - - return GdkPixbuf.Pixbuf.new_from_data(data, *pixbuf_options) + return GdkPixbuf.Pixbuf.new_from_file(cover_path) diff --git a/src/utils/heroic_parser.py b/src/utils/heroic_parser.py index 2ce874a..3aaf557 100644 --- a/src/utils/heroic_parser.py +++ b/src/utils/heroic_parser.py @@ -83,7 +83,7 @@ def heroic_parser(parent_widget, action): app_name = game["app_name"] values["game_id"] = "heroic_epic_" + app_name - if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed: + if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed: continue values["name"] = game["title"] @@ -95,7 +95,7 @@ def heroic_parser(parent_widget, action): image_path = os.path.join(heroic_dir, "images-cache", hashlib.sha256((game["art_square"] + "?h=400&resize=1&w=300").encode()).hexdigest()) if os.path.exists(image_path): - values["pixbuf_options"] = save_cover(values, parent_widget, image_path) + save_cover(values, parent_widget, image_path) heroic_games[values["game_id"]] = values @@ -113,7 +113,7 @@ def heroic_parser(parent_widget, action): values["game_id"] = "heroic_gog_" + app_name - if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed: + if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed: continue # Get game title from library.json as it's not present in installed.json @@ -127,7 +127,7 @@ def heroic_parser(parent_widget, action): image_path = os.path.join(heroic_dir, "images-cache", hashlib.sha256(game["art_square"].encode()).hexdigest()) if os.path.exists(image_path): - values["pixbuf_options"] = save_cover(values, parent_widget, image_path) + save_cover(values, parent_widget, image_path) break values["executable"] = "xdg-open heroic://launch/" + app_name @@ -152,7 +152,7 @@ def heroic_parser(parent_widget, action): values["game_id"] = "heroic_sideload_" + app_name - if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed: + if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed: continue values["name"] = item["title"] @@ -164,7 +164,7 @@ def heroic_parser(parent_widget, action): image_path = os.path.join(heroic_dir, "images-cache", hashlib.sha256(item["art_square"].encode()).hexdigest()) if os.path.exists(image_path): - values["pixbuf_options"] = save_cover(values, parent_widget, image_path) + save_cover(values, parent_widget, image_path) heroic_games[values["game_id"]] = values diff --git a/src/utils/save_cover.py b/src/utils/save_cover.py index 3222c76..06c8cb4 100644 --- a/src/utils/save_cover.py +++ b/src/utils/save_cover.py @@ -18,8 +18,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later def save_cover(game, parent_widget, file_path, pixbuf = None, game_id = None): - from gi.repository import GdkPixbuf - import os, zlib + from gi.repository import Gio, GdkPixbuf + import os covers_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers") if os.path.exists(covers_dir) == False: @@ -33,7 +33,9 @@ def save_cover(game, parent_widget, file_path, pixbuf = None, game_id = None): if pixbuf == None: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(file_path, 600, 900, False) - open_file = open(cover_path, "wb") - open_file.write(zlib.compress(bytes(pixbuf.get_pixels()), 1)) - open_file.close() - return [pixbuf.get_colorspace(), pixbuf.get_has_alpha(), pixbuf.get_bits_per_sample(), pixbuf.get_width(), pixbuf.get_height(), pixbuf.get_rowstride()] + def cover_callback(*args): + pass + + file = Gio.File.new_for_path(os.path.join(covers_dir, game_id + ".png")) + parent_widget.pixbufs[game_id] = pixbuf + pixbuf.save_to_streamv_async(file.replace(None, False, Gio.FileCreateFlags.NONE), "png", None, None, None, cover_callback) diff --git a/src/utils/steam_parser.py b/src/utils/steam_parser.py index beaee63..8c3c194 100644 --- a/src/utils/steam_parser.py +++ b/src/utils/steam_parser.py @@ -87,7 +87,7 @@ def steam_parser(parent_widget, action): values["game_id"] = "steam_" + values["appid"] - if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed: + if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed: continue values["executable"] = "xdg-open steam://rungameid/" + values["appid"] @@ -97,7 +97,7 @@ def steam_parser(parent_widget, action): values["last_played"] = 0 if os.path.isfile(os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg")): - values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg")) + save_cover(values, parent_widget, os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg")) steam_games[values["game_id"]] = values diff --git a/src/window.py b/src/window.py index 8af8a22..58abeb5 100644 --- a/src/window.py +++ b/src/window.py @@ -68,14 +68,14 @@ class CartridgesWindow(Adw.ApplicationWindow): def __init__(self, **kwargs): super().__init__(**kwargs) - self.games_temp = {} + self.games = {} self.visible_widgets = {} self.hidden_widgets = {} self.filtered = {} self.hidden_filtered = {} self.previous_page = self.library_view self.toasts = {} - self.busy_games = [] + self.pixbufs = {} self.overview.set_measure_overlay(self.overview_box, True) self.overview.set_clip_overlay(self.overview_box, False) @@ -119,16 +119,13 @@ class CartridgesWindow(Adw.ApplicationWindow): current_game = current_games[game_id] - entry = game(self, current_game, get_cover(current_game["game_id"], current_game["pixbuf_options"] if "pixbuf_options" in current_game.keys() else None, self)) - self.games_temp[current_game["game_id"]] = entry + entry = game(self, current_game) + self.games[current_game["game_id"]] = entry if entry.removed: continue - if game_id in self.busy_games: - continue - - if not self.games_temp[game_id].hidden: + if not self.games[game_id].hidden: self.visible_widgets[game_id] = entry self.library.append(entry) else: @@ -212,7 +209,7 @@ class CartridgesWindow(Adw.ApplicationWindow): return GLib.DateTime.new_from_unix_utc(timestamp).format("%x") def show_overview(self, widget, game_id): - game = self.games_temp[game_id] + game = self.games[game_id] if not game.hidden: self.overview_menu_button.set_menu_model(self.game_options) @@ -224,7 +221,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.stack.set_visible_child(self.overview) self.active_game_id = game_id - pixbuf = (self.visible_widgets | self.hidden_widgets)[self.active_game_id].pixbuf + pixbuf = get_cover(self.active_game_id, self) self.overview_cover.set_pixbuf(pixbuf) self.overview_blurred_cover.set_pixbuf(pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR)) self.overview_title.set_label(game.name) @@ -256,8 +253,8 @@ class CartridgesWindow(Adw.ApplicationWindow): return self.a_z_sort(child1, child2) def newest_sort(self, child1, child2): - time1 = self.games_temp[child1.get_first_child().game_id].added - time2 = self.games_temp[child2.get_first_child().game_id].added + time1 = self.games[child1.get_first_child().game_id].added + time2 = self.games[child2.get_first_child().game_id].added if time1 > time2: return -1 elif time1 < time2: @@ -266,8 +263,8 @@ class CartridgesWindow(Adw.ApplicationWindow): return self.a_z_sort(child1, child2) def oldest_sort(self, child1, child2): - time1 = self.games_temp[child1.get_first_child().game_id].added - time2 = self.games_temp[child2.get_first_child().game_id].added + time1 = self.games[child1.get_first_child().game_id].added + time2 = self.games[child2.get_first_child().game_id].added if time1 > time2: return 1 elif time1 < time2: @@ -276,8 +273,8 @@ class CartridgesWindow(Adw.ApplicationWindow): return self.a_z_sort(child1, child2) def last_played_sort(self, child1, child2): - time1 = self.games_temp[child1.get_first_child().game_id].last_played - time2 = self.games_temp[child2.get_first_child().game_id].last_played + time1 = self.games[child1.get_first_child().game_id].last_played + time2 = self.games[child2.get_first_child().game_id].last_played if time1 > time2: return -1 elif time1 < time2: