diff --git a/.gitignore b/.gitignore index 4c96479..1ead167 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -/subprojects/blueprint-compiler \ No newline at end of file +/subprojects/blueprint-compiler +/.flatpak +/.vscode \ No newline at end of file diff --git a/src/game.py b/src/game.py index 1aac5aa..8fe905b 100644 --- a/src/game.py +++ b/src/game.py @@ -66,15 +66,15 @@ class game(Gtk.Box): self.event_contoller_motion.connect("leave", self.hide_play) self.menu_button.get_popover().connect("notify::visible", self.hide_play) - def show_play(self, widget, *args): + def show_play(self, _widget, *args): self.play_revealer.set_reveal_child(True) self.title_revealer.set_reveal_child(False) - def hide_play(self, widget, *args): + def hide_play(self, _widget, *args): if not self.menu_button.get_active(): self.play_revealer.set_reveal_child(False) self.title_revealer.set_reveal_child(True) - def launch_game(self, widget): + def launch_game(self, _widget): self.parent_widget.set_active_game(None, None, self.game_id) self.parent_widget.get_application().on_launch_game_action(None) diff --git a/src/main.py b/src/main.py index de78215..d9b5f24 100644 --- a/src/main.py +++ b/src/main.py @@ -21,10 +21,6 @@ import sys import time import gi - -gi.require_version("Gtk", "4.0") -gi.require_version("Adw", "1") - from gi.repository import Adw, Gio, GLib, Gtk from .bottles_parser import bottles_parser @@ -38,6 +34,9 @@ from .steam_parser import steam_parser from .toggle_hidden import toggle_hidden from .window import CartridgesWindow +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") + class CartridgesApplication(Adw.Application): def __init__(self): @@ -58,6 +57,8 @@ class CartridgesApplication(Adw.Application): self.create_action("add_game", self.on_add_game_action, ["n"]) self.create_action("remove_game", self.on_remove_game_action) + self.win = None + def do_activate(self): # Create the main window @@ -104,7 +105,7 @@ class CartridgesApplication(Adw.Application): self.win.sort.connect("activate", self.win.on_sort_action) self.win.on_sort_action(self.win.sort, state_settings.get_value("sort-mode")) - def on_about_action(self, widget, callback=None): + def on_about_action(self, _widget, _callback=None): about = Adw.AboutWindow( transient_for=self.win, application_name=_("Cartridges"), @@ -125,25 +126,25 @@ class CartridgesApplication(Adw.Application): ) about.present() - def on_preferences_action(self, widget, callback=None): + def on_preferences_action(self, _widget, _callback=None): PreferencesWindow(self.win).present() - def on_steam_import_action(self, widget, callback=None): + def on_steam_import_action(self, _widget, _callback=None): games = steam_parser(self.win, self.on_steam_import_action) save_games(games) self.win.update_games(games.keys()) - def on_heroic_import_action(self, widget, callback=None): + def on_heroic_import_action(self, _widget, _callback=None): games = heroic_parser(self.win, self.on_heroic_import_action) save_games(games) self.win.update_games(games.keys()) - def on_bottles_import_action(self, widget, callback=None): + def on_bottles_import_action(self, _widget, _callback=None): games = bottles_parser(self.win, self.on_bottles_import_action) save_games(games) self.win.update_games(games.keys()) - def on_launch_game_action(self, widget, callback=None): + def on_launch_game_action(self, _widget, _callback=None): # Launch the game and update the last played value @@ -153,26 +154,26 @@ class CartridgesApplication(Adw.Application): data["last_played"] = int(time.time()) save_games({game_id: data}) - run_command(self.win, self.win.games[self.win.active_game_id].executable) + run_command(self.win.games[self.win.active_game_id].executable) self.win.update_games([game_id]) if self.win.stack.get_visible_child() == self.win.overview: self.win.show_overview(None, self.win.active_game_id) - def on_hide_game_action(self, widget, callback=None): + def on_hide_game_action(self, _widget, _callback=None): if self.win.stack.get_visible_child() == self.win.overview: self.win.on_go_back_action(None, None) toggle_hidden(self.win.active_game_id) self.win.update_games([self.win.active_game_id]) - def on_edit_details_action(self, widget, callback=None): + def on_edit_details_action(self, _widget, _callback=None): create_details_window(self.win, self.win.active_game_id) - def on_add_game_action(self, widget, callback=None): + def on_add_game_action(self, _widget, _callback=None): create_details_window(self.win) - def on_remove_game_action(self, widget, callback=None): + def on_remove_game_action(self, _widget, _callback=None): # Add "removed=True" to the game properties so it can be deleted on next init game_id = self.win.active_game_id @@ -193,7 +194,7 @@ class CartridgesApplication(Adw.Application): self.win.toasts[game_id] = toast self.win.toast_overlay.add_toast(toast) - def on_quit_action(self, widget, callback=None): + def on_quit_action(self, _widget, _callback=None): self.quit() def create_action(self, name, callback, shortcuts=None, win=None): diff --git a/src/preferences.py b/src/preferences.py index 60be7f0..5711db7 100644 --- a/src/preferences.py +++ b/src/preferences.py @@ -65,7 +65,7 @@ class PreferencesWindow(Adw.PreferencesWindow): filechooser = Gtk.FileDialog() - def set_steam_dir(source, result, user_data): + def set_steam_dir(_source, result, _unused): try: schema.set_string( "steam-location", @@ -74,7 +74,7 @@ class PreferencesWindow(Adw.PreferencesWindow): except GLib.GError: pass - def set_heroic_dir(source, result, user_data): + def set_heroic_dir(_source, result, _unused): try: schema.set_string( "heroic-location", @@ -83,7 +83,7 @@ class PreferencesWindow(Adw.PreferencesWindow): except GLib.GError: pass - def set_bottles_dir(source, result, user_data): + def set_bottles_dir(_source, result, _unused): try: schema.set_string( "bottles-location", @@ -92,7 +92,7 @@ class PreferencesWindow(Adw.PreferencesWindow): except GLib.GError: pass - def choose_folder(widget, function): + def choose_folder(_widget, function): filechooser.select_folder(parent_widget, None, function, None) self.steam_file_chooser_button.connect("clicked", choose_folder, set_steam_dir) diff --git a/src/utils/__init__.py b/src/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/bottles_parser.py b/src/utils/bottles_parser.py index 1248f24..906ceaf 100644 --- a/src/utils/bottles_parser.py +++ b/src/utils/bottles_parser.py @@ -48,7 +48,7 @@ def bottles_parser(parent_widget, action): else: filechooser = Gtk.FileDialog.new() - def set_bottles_dir(source, result, _): + def set_bottles_dir(_source, result, _unused): try: schema.set_string( "bottles-location", @@ -58,7 +58,7 @@ def bottles_parser(parent_widget, action): except GLib.GError: return - def choose_folder(widget): + def choose_folder(_widget): filechooser.select_folder(parent_widget, None, set_bottles_dir, None) def response(widget, response): @@ -84,9 +84,9 @@ def bottles_parser(parent_widget, action): bottles_games = {} current_time = int(time.time()) - open_file = open(os.path.join(bottles_dir, "library.yml"), "r") - data = open_file.read() - open_file.close() + with open(os.path.join(bottles_dir, "library.yml"), "r") as open_file: + data = open_file.read() + open_file.close() library = yaml.load(data, Loader=yaml.Loader) diff --git a/src/utils/create_details_window.py b/src/utils/create_details_window.py index 19561e2..a8f26a3 100644 --- a/src/utils/create_details_window.py +++ b/src/utils/create_details_window.py @@ -37,7 +37,7 @@ def create_details_window(parent_widget, game_id=None): games = parent_widget.games pixbuf = None - if game_id == None: + if game_id is None: window.set_title(_("Add New Game")) cover = Gtk.Picture.new_for_pixbuf(parent_widget.placeholder_pixbuf) name = Gtk.Entry() @@ -119,10 +119,10 @@ def create_details_window(parent_widget, game_id=None): main_box.append(general_page) window.set_content(main_box) - def choose_cover(widget): + def choose_cover(_widget): filechooser.open(window, None, set_cover, None) - def set_cover(source, result, _): + def set_cover(_source, result, _unused): nonlocal pixbuf try: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( @@ -132,10 +132,10 @@ def create_details_window(parent_widget, game_id=None): except GLib.GError: return - def close_window(widget, callback=None): + def close_window(_widget, _callback=None): window.close() - def apply_preferences(widget, callback=None): + def apply_preferences(_widget, _callback=None): nonlocal pixbuf nonlocal game_id @@ -144,7 +144,7 @@ def create_details_window(parent_widget, game_id=None): final_name = name.get_buffer().get_text() final_executable = executable.get_buffer().get_text() - if game_id == None: + if game_id is None: if final_name == "": create_dialog( @@ -191,7 +191,7 @@ def create_details_window(parent_widget, game_id=None): ) return - if pixbuf != None: + if pixbuf is not None: save_cover(None, parent_widget, None, pixbuf, game_id) values["name"] = final_name @@ -207,9 +207,9 @@ def create_details_window(parent_widget, game_id=None): ) if os.path.exists(path): - open_file = open(path, "r") - data = json.loads(open_file.read()) - open_file.close() + with open(path, "r") as open_file: + data = json.loads(open_file.read()) + open_file.close() data.update(values) save_games({game_id: data}) else: @@ -221,7 +221,7 @@ def create_details_window(parent_widget, game_id=None): window.close() parent_widget.show_overview(None, game_id) - def focus_executable(widget): + def focus_executable(_widget): window.set_focus(executable) cover_button.connect("clicked", choose_cover) diff --git a/src/utils/get_games.py b/src/utils/get_games.py index 7f473ce..5d84ed5 100644 --- a/src/utils/get_games.py +++ b/src/utils/get_games.py @@ -25,7 +25,7 @@ def get_games(game_ids=None): games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games") games = {} - if os.path.exists(games_dir) == False: + if not os.path.exists(games_dir): return {} if not game_ids: @@ -36,8 +36,8 @@ def get_games(game_ids=None): game_files.append(game_id + ".json") for game in game_files: - open_file = open(os.path.join(games_dir, game), "r") - data = json.loads(open_file.read()) - open_file.close() + with open(os.path.join(games_dir, game), "r") as open_file: + data = json.loads(open_file.read()) + open_file.close() games[data["game_id"]] = data return games diff --git a/src/utils/heroic_parser.py b/src/utils/heroic_parser.py index f788169..91da35d 100644 --- a/src/utils/heroic_parser.py +++ b/src/utils/heroic_parser.py @@ -50,7 +50,7 @@ def heroic_parser(parent_widget, action): else: filechooser = Gtk.FileDialog.new() - def set_heroic_dir(source, result, _): + def set_heroic_dir(_source, result, _unused): try: schema.set_string( "heroic-location", @@ -60,7 +60,7 @@ def heroic_parser(parent_widget, action): except GLib.GError: return - def choose_folder(widget): + def choose_folder(_widget): filechooser.select_folder(parent_widget, None, set_heroic_dir, None) def response(widget, response): @@ -90,13 +90,15 @@ def heroic_parser(parent_widget, action): if not schema.get_boolean("heroic-import-epic"): pass elif os.path.exists(os.path.join(heroic_dir, "lib-cache", "library.json")): - open_file = open(os.path.join(heroic_dir, "lib-cache", "library.json"), "r") - data = open_file.read() + with open( + os.path.join(heroic_dir, "lib-cache", "library.json"), "r" + ) as open_file: + data = open_file.read() + open_file.close() library = json.loads(data) - open_file.close() for game in library["library"]: - if game["is_installed"] == False: + if not game["is_installed"]: continue values = {} @@ -133,9 +135,11 @@ def heroic_parser(parent_widget, action): if not schema.get_boolean("heroic-import-gog"): pass elif os.path.exists(os.path.join(heroic_dir, "gog_store", "installed.json")): - open_file = open(os.path.join(heroic_dir, "gog_store", "installed.json"), "r") - data = open_file.read() - open_file.close() + with open( + os.path.join(heroic_dir, "gog_store", "installed.json"), "r" + ) as open_file: + data = open_file.read() + open_file.close() installed = json.loads(data) for item in installed["installed"]: values = {} @@ -150,9 +154,11 @@ def heroic_parser(parent_widget, action): continue # Get game title from library.json as it's not present in installed.json - open_file = open(os.path.join(heroic_dir, "gog_store", "library.json"), "r") - data = open_file.read() - open_file.close() + with open( + os.path.join(heroic_dir, "gog_store", "library.json"), "r" + ) as open_file: + data = open_file.read() + open_file.close() library = json.loads(data) for game in library["games"]: if game["app_name"] == app_name: @@ -178,9 +184,11 @@ def heroic_parser(parent_widget, action): if not schema.get_boolean("heroic-import-sideload"): pass elif os.path.exists(os.path.join(heroic_dir, "sideload_apps", "library.json")): - open_file = open(os.path.join(heroic_dir, "sideload_apps", "library.json"), "r") - data = open_file.read() - open_file.close() + with open( + os.path.join(heroic_dir, "sideload_apps", "library.json"), "r" + ) as open_file: + data = open_file.read() + open_file.close() library = json.loads(data) for item in library["games"]: values = {} diff --git a/src/utils/run_command.py b/src/utils/run_command.py index 53e0d8f..b78d64e 100644 --- a/src/utils/run_command.py +++ b/src/utils/run_command.py @@ -23,7 +23,7 @@ import sys from gi.repository import Gio -def run_command(parent_widget, executable): +def run_command(executable): subprocess.Popen( ["flatpak-spawn --host " + executable], shell=True, start_new_session=True ) diff --git a/src/utils/save_cover.py b/src/utils/save_cover.py index 62b7bda..857461e 100644 --- a/src/utils/save_cover.py +++ b/src/utils/save_cover.py @@ -24,22 +24,22 @@ from gi.repository import GdkPixbuf, Gio def save_cover(game, parent_widget, file_path, pixbuf=None, game_id=None): covers_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers") - if os.path.exists(covers_dir) == False: + if not os.path.exists(covers_dir): os.makedirs(covers_dir) - if game_id == None: + if game_id is None: game_id = game["game_id"] - if pixbuf == None: + if pixbuf is None: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(file_path, 600, 900, False) - def cover_callback(*args): + def cover_callback(*_unused): pass - file = Gio.File.new_for_path(os.path.join(covers_dir, game_id + ".jpg")) + open_file = Gio.File.new_for_path(os.path.join(covers_dir, game_id + ".jpg")) parent_widget.pixbufs[game_id] = pixbuf pixbuf.save_to_streamv_async( - file.replace(None, False, Gio.FileCreateFlags.NONE), + open_file.replace(None, False, Gio.FileCreateFlags.NONE), "jpeg", callback=cover_callback, ) diff --git a/src/utils/save_games.py b/src/utils/save_games.py index 9f9110a..16e7790 100644 --- a/src/utils/save_games.py +++ b/src/utils/save_games.py @@ -24,10 +24,10 @@ import os def save_games(games): games_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "games") - if os.path.exists(games_dir) == False: + if not os.path.exists(games_dir): os.makedirs(games_dir) for game in games: - open_file = open(os.path.join(games_dir, game + ".json"), "w") - open_file.write(json.dumps(games[game], indent=4, sort_keys=True)) - open_file.close() + with open(os.path.join(games_dir, game + ".json"), "w") as open_file: + open_file.write(json.dumps(games[game], indent=4, sort_keys=True)) + open_file.close() diff --git a/src/utils/steam_parser.py b/src/utils/steam_parser.py index 46cca04..926c499 100644 --- a/src/utils/steam_parser.py +++ b/src/utils/steam_parser.py @@ -45,7 +45,7 @@ def steam_parser(parent_widget, action): else: filechooser = Gtk.FileDialog.new() - def set_steam_dir(source, result, _): + def set_steam_dir(_source, result, _unused): try: schema.set_string( "steam-location", @@ -55,7 +55,7 @@ def steam_parser(parent_widget, action): except GLib.GError: return - def choose_folder(widget): + def choose_folder(_widget): filechooser.select_folder(parent_widget, None, set_steam_dir, None) def response(widget, response): @@ -94,9 +94,9 @@ def steam_parser(parent_widget, action): for appmanifest in appmanifests: values = {} - open_file = open(appmanifest, "r") - data = open_file.read() - open_file.close() + with open(appmanifest, "r") as open_file: + data = open_file.read() + open_file.close() for datatype in datatypes: value = re.findall('"' + datatype + '"\t\t"(.*)"\n', data) values[datatype] = value[0] diff --git a/src/utils/toggle_hidden.py b/src/utils/toggle_hidden.py index 43c0567..295b286 100644 --- a/src/utils/toggle_hidden.py +++ b/src/utils/toggle_hidden.py @@ -27,10 +27,10 @@ def toggle_hidden(game): if not os.path.exists(games_dir): return - file = open(os.path.join(games_dir, game + ".json"), "r") - data = json.loads(file.read()) - file.close() - file = open(os.path.join(games_dir, game + ".json"), "w") - data["hidden"] = not data["hidden"] - file.write(json.dumps(data, indent=4)) - file.close() + with open(os.path.join(games_dir, game + ".json"), "r") as open_file: + data = json.loads(open_file.read()) + open_file.close() + with open(os.path.join(games_dir, game + ".json"), "w") as open_file: + data["hidden"] = not data["hidden"] + open_file.write(json.dumps(data, indent=4)) + open_file.close() diff --git a/src/window.py b/src/window.py index 9cdef98..7fba43c 100644 --- a/src/window.py +++ b/src/window.py @@ -78,6 +78,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.previous_page = self.library_view self.toasts = {} self.pixbufs = {} + self.active_game_id = None self.overview.set_measure_overlay(self.overview_box, True) self.overview.set_clip_overlay(self.overview_box, False) @@ -86,15 +87,15 @@ class CartridgesWindow(Adw.ApplicationWindow): self.placeholder_pixbuf = GdkPixbuf.Pixbuf.new_from_resource_at_scale( "/hu/kramo/Cartridges/library_placeholder.svg", 200, 300, False ) - games = get_games() - for game in games: - if "removed" in games[game].keys(): + current_games = get_games() + for current_game in current_games: + if "removed" in current_games[current_game].keys(): os.remove( os.path.join( os.environ.get("XDG_DATA_HOME"), "cartridges", "games", - game + ".json", + current_game + ".json", ) ) try: @@ -103,7 +104,7 @@ class CartridgesWindow(Adw.ApplicationWindow): os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", - game + ".dat", + current_game + ".dat", ) ) except FileNotFoundError: @@ -157,12 +158,12 @@ class CartridgesWindow(Adw.ApplicationWindow): ) entry.get_parent().set_focusable(False) - if self.visible_widgets == {}: + if not self.visible_widgets: self.library_bin.set_child(self.notice_empty) else: self.library_bin.set_child(self.scrolledwindow) - if self.hidden_widgets == {}: + if not self.hidden_widgets: self.hidden_library_bin.set_child(self.hidden_notice_empty) else: self.hidden_library_bin.set_child(self.hidden_scrolledwindow) @@ -170,7 +171,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.library.invalidate_filter() self.hidden_library.invalidate_filter() - def search_changed(self, widget, hidden): + def search_changed(self, _widget, hidden): # Refresh search filter on keystroke in search box if not hidden: self.library.invalidate_filter() @@ -213,8 +214,8 @@ class CartridgesWindow(Adw.ApplicationWindow): self.hidden_library_bin.set_child(self.hidden_scrolledwindow) return filtered - def set_active_game(self, widget, _, game): - self.active_game_id = game + def set_active_game(self, _widget, _unused, game_id): + self.active_game_id = game_id def get_time(self, timestamp): date = datetime.datetime.fromtimestamp(timestamp) @@ -228,10 +229,10 @@ class CartridgesWindow(Adw.ApplicationWindow): else: return GLib.DateTime.new_from_unix_utc(timestamp).format("%x") - def show_overview(self, widget, game_id): - game = self.games[game_id] + def show_overview(self, _widget, game_id): + current_game = self.games[game_id] - if not game.hidden: + if not current_game.hidden: self.overview_menu_button.set_menu_model(self.game_options) else: self.overview_menu_button.set_menu_model(self.hidden_game_options) @@ -246,12 +247,14 @@ class CartridgesWindow(Adw.ApplicationWindow): self.overview_blurred_cover.set_pixbuf( pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR) ) - self.overview_title.set_label(game.name) - self.overview_header_bar_title.set_title(game.name) - self.overview_added.set_label(_("Added:") + " " + self.get_time(game.added)) + self.overview_title.set_label(current_game.name) + self.overview_header_bar_title.set_title(current_game.name) + self.overview_added.set_label( + _("Added:") + " " + self.get_time(current_game.added) + ) self.overview_last_played.set_label( - _("Last played:") + " " + self.get_time(game.last_played) - if game.last_played != 0 + _("Last played:") + " " + self.get_time(current_game.last_played) + if current_game.last_played != 0 else _("Last played: Never") ) @@ -308,26 +311,26 @@ class CartridgesWindow(Adw.ApplicationWindow): else: return self.a_z_sort(child1, child2) - def on_go_back_action(self, widget, _, x=None, y=None): + def on_go_back_action(self, _widget, _unused, _x=None, _y=None): if self.stack.get_visible_child() == self.hidden_library_view: self.on_show_library_action(None, None) elif self.stack.get_visible_child() == self.overview: self.on_go_to_parent_action(None, None) - def on_go_to_parent_action(self, widget, _): + def on_go_to_parent_action(self, _widget, _unused): if self.stack.get_visible_child() == self.overview: if self.previous_page == self.library_view: self.on_show_library_action(None, None) else: self.on_show_hidden_action(None, None) - def on_show_library_action(self, widget, _): + def on_show_library_action(self, _widget, _unused): self.stack.set_transition_type(Gtk.StackTransitionType.UNDER_RIGHT) self.stack.set_visible_child(self.library_view) self.lookup_action("show_hidden").set_enabled(True) self.previous_page = self.library_view - def on_show_hidden_action(self, widget, _): + def on_show_hidden_action(self, _widget, _unused): if self.stack.get_visible_child() == self.library_view: self.stack.set_transition_type(Gtk.StackTransitionType.OVER_LEFT) else: @@ -352,7 +355,7 @@ class CartridgesWindow(Adw.ApplicationWindow): elif state == "oldest": sort_func = self.oldest_sort - elif state == "last_played": + else: sort_func = self.last_played_sort Gio.Settings(schema_id="hu.kramo.Cartridge.State").set_string( @@ -361,7 +364,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.library.set_sort_func(sort_func) self.hidden_library.set_sort_func(sort_func) - def on_toggle_search_action(self, widget, _): + def on_toggle_search_action(self, _widget, _unused): if self.stack.get_visible_child() == self.library_view: search_bar = self.search_bar search_entry = self.search_entry @@ -382,7 +385,7 @@ class CartridgesWindow(Adw.ApplicationWindow): else: search_entry.set_text("") - def on_escape_action(self, widget, _): + def on_escape_action(self, _widget, _unused): if self.stack.get_visible_child() == self.overview: self.on_go_back_action(None, None) return @@ -402,7 +405,7 @@ class CartridgesWindow(Adw.ApplicationWindow): search_button.set_active(False) search_entry.set_text("") - def on_undo_remove_action(self, widget, game_id=None): + def on_undo_remove_action(self, _widget, game_id=None): # Remove the "removed=True" property from the game and dismiss the toast if not game_id: @@ -417,7 +420,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.toasts[game_id].dismiss() self.toasts.pop(game_id) - def on_open_menu_action(self, widget, _): + def on_open_menu_action(self, _widget, _unused): if self.stack.get_visible_child() != self.overview: self.primary_menu_button.set_active(True) else: