From f7235f551f779f3760a124170c5c67c96f87919a Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 1 Jan 2024 18:59:30 +0100 Subject: [PATCH] Improvements of initial backend handling This improved how the installed backnends are checked and makes sure that only installed backends are reconded into config. This addresses the issue #23 and generally improved the code. --- setup.py | 2 +- waypaper/__main__.py | 6 ++--- waypaper/app.py | 52 +++++++++++++++++++------------------------- waypaper/changer.py | 9 ++++---- waypaper/common.py | 15 ++++++++----- waypaper/config.py | 25 +++++++++++---------- waypaper/options.py | 4 ++-- 7 files changed, 54 insertions(+), 59 deletions(-) diff --git a/setup.py b/setup.py index f565aed..7b4b4f1 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setuptools.setup( ] }, install_requires=["PyGObject", "importlib_metadata", "platformdirs", "Pillow"], - version='2.0.3', + version='2.0.4', python_requires='>3.9', classifiers=[ "Development Status :: 4 - Beta", diff --git a/waypaper/__main__.py b/waypaper/__main__.py index 90866c2..fc2cb1e 100644 --- a/waypaper/__main__.py +++ b/waypaper/__main__.py @@ -7,7 +7,7 @@ import argparse from waypaper.config import Config from waypaper.app import App from waypaper.changer import change_wallpaper -from waypaper.common import get_random_file, check_missing_backends +from waypaper.common import get_random_file from waypaper.aboutdata import AboutData from waypaper.options import FILL_OPTIONS, BACKEND_OPTIONS from waypaper.translations import English, German, French, Russian, Polish, Chinese @@ -39,12 +39,10 @@ parser.add_argument("--backend", help=txt.msg_arg_back, choices=BACKEND_OPTIONS) args = parser.parse_args() - def run(): """Read user arguments and either run GUI app or just reset the wallpaper""" cf.read_parameters_from_user_arguments(args) - missing_backends = check_missing_backends() # Set the wallpaper and quit: if args.restore: @@ -55,7 +53,7 @@ def run(): if wallpaper is None: continue - change_wallpaper(wallpaper, cf, monitor, txt, missing_backends) + change_wallpaper(wallpaper, cf, monitor, txt) time.sleep(0.1) exit(0) diff --git a/waypaper/app.py b/waypaper/app.py index 7063206..61263c2 100644 --- a/waypaper/app.py +++ b/waypaper/app.py @@ -4,14 +4,14 @@ import subprocess import threading import os import gi +import shutil from pathlib import Path -from platformdirs import user_cache_path from PIL import Image from waypaper.aboutdata import AboutData from waypaper.changer import change_wallpaper from waypaper.config import Config -from waypaper.common import get_image_paths, get_random_file, check_missing_backends +from waypaper.common import get_image_paths, get_random_file from waypaper.options import FILL_OPTIONS, BACKEND_OPTIONS, SORT_OPTIONS, SORT_DISPLAYS gi.require_version("Gtk", "3.0") @@ -27,7 +27,7 @@ def read_webp_image(image_path): return pixbuf -def cache_image(image_path, cachedir): +def cache_image(image_path, cache_dir): """Resize and cache images using gtk library""" ext = os.path.splitext(image_path)[1].lower() if ext == ".webp": @@ -38,7 +38,7 @@ def cache_image(image_path, cachedir): scaled_width = 240 scaled_height = int(scaled_width / aspect_ratio) scaled_pixbuf = pixbuf.scale_simple(scaled_width, scaled_height, GdkPixbuf.InterpType.BILINEAR) - output_file = cachedir / Path(os.path.basename(image_path)) + output_file = cache_dir / Path(os.path.basename(image_path)) scaled_pixbuf.savev(str(output_file), "jpeg", [], []) @@ -47,15 +47,14 @@ class App(Gtk.Window): def __init__(self, txt): super().__init__(title="Waypaper") + self.cf = Config() + self.about = AboutData() self.txt = txt self.check_backends() self.set_default_size(780, 600) self.connect("delete-event", Gtk.main_quit) self.selected_index = 0 self.highlighted_image_row = 0 - self.aboutData = AboutData() - self.cachePath = user_cache_path(self.aboutData.applicationName()) - self.cf = Config() self.init_ui() # Start the image processing in a separate thread: @@ -96,16 +95,13 @@ class App(Gtk.Window): # Create a backend dropdown menu: self.backend_option_combo = Gtk.ComboBoxText() - for backend, is_missing in zip(BACKEND_OPTIONS, self.missing_backends): - if not is_missing: - self.backend_option_combo.append_text(backend) + for backend in self.cf.installed_backends: + self.backend_option_combo.append_text(backend) # Set as active line the backend from config, if it is installed: - try: - installed_backends = [value for value, miss in zip(BACKEND_OPTIONS, self.missing_backends) if not miss] - active_num = installed_backends.index(self.cf.backend) - except: - active_num = 0 + active_num = 0 + if self.cf.backend in self.cf.installed_backends: + active_num = self.cf.installed_backends.index(self.cf.backend) self.backend_option_combo.set_active(active_num) self.backend_option_combo.connect("changed", self.on_backend_option_changed) self.backend_option_combo.set_tooltip_text(self.txt.tip_backend) @@ -192,7 +188,6 @@ class App(Gtk.Window): def monitor_option_display(self): """Display monitor option if backend is swww""" self.options_box.remove(self.monitor_option_combo) - # if "swww" not in self.missing_backends and self.cf.backend not in ["wallutils", "feh"]: if self.cf.backend == "swww": # Check available monitors: @@ -219,12 +214,9 @@ class App(Gtk.Window): def check_backends(self): - """Before running the app, check which backends are installed""" - self.missing_backends = check_missing_backends() - - # Show error message if no backends are installed: - if all(self.missing_backends): - self.show_message(sefl.txt.err_backend) + """Before running the app, check which backends are installed or show the error""" + if not self.cf.installed_backends: + self.show_message(self.txt.err_backend) exit() @@ -275,9 +267,9 @@ class App(Gtk.Window): self.image_paths.remove(image_path) continue # If this image is not cached yet, resize and cache it: - cached_image_path = self.cachePath/os.path.basename(image_path) + cached_image_path = self.cf.cache_dir / os.path.basename(image_path) if not cached_image_path.exists(): - cache_image(image_path, self.cachePath) + cache_image(image_path, self.cf.cache_dir) # Load cached thumbnail: thumbnail = GdkPixbuf.Pixbuf.new_from_file(str(cached_image_path)) @@ -406,7 +398,7 @@ class App(Gtk.Window): self.load_image_grid() print(self.txt.msg_path, self.cf.selected_wallpaper) self.cf.fill_option = self.fill_option_combo.get_active_text() or self.cf.fill_option - change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt, self.missing_backends) + change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt) self.cf.save() @@ -433,17 +425,17 @@ class App(Gtk.Window): return print(self.txt.msg_path, self.cf.selected_wallpaper) self.cf.fill_option = self.fill_option_combo.get_active_text() or self.cf.fill_option - change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt, self.missing_backends) + change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt) self.cf.save() def clear_cache(self): """Delete cache folder and reprocess the images""" try: - shutil.rmtree(self.cachePath) - os.makedirs(self.cachePath) + shutil.rmtree(self.cf.cache_dir) + os.makedirs(self.cf.cache_dir) except OSError as e: - print(f"{self.txt.err_cache} '{self.cachePath}': {e}") + print(f"{self.txt.err_cache} '{self.cf.cache_dir}': {e}") threading.Thread(target=self.process_images).start() @@ -501,7 +493,7 @@ class App(Gtk.Window): print(self.txt.msg_path, self.cf.selected_wallpaper) self.cf.backend = self.backend_option_combo.get_active_text() self.cf.fill_option = self.fill_option_combo.get_active_text() or self.cf.fill_option - change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt, self.missing_backends) + change_wallpaper(self.cf.selected_wallpaper, self.cf, self.cf.selected_monitor, self.txt) self.cf.save() # Prevent other default key handling: diff --git a/waypaper/changer.py b/waypaper/changer.py index c8237cd..e31b13e 100644 --- a/waypaper/changer.py +++ b/waypaper/changer.py @@ -6,13 +6,14 @@ import time from waypaper.options import BACKEND_OPTIONS -def change_wallpaper(image_path, cf, monitor, txt, missing_backends): - """Run a system command to change the wallpaper depending on the backend""" +def change_wallpaper(image_path, cf, monitor, txt): + """Run system commands to change the wallpaper depending on the backend""" fill_option = cf.fill_option color = cf.color backend = cf.backend swww_transition = cf.swww_transition + installed_backends = cf.installed_backends try: # swaybg backend: @@ -41,14 +42,12 @@ def change_wallpaper(image_path, cf, monitor, txt, missing_backends): "tile": "no", } fill = fill_types[fill_option.lower()] - is_swaybg_installed = not missing_backends[BACKEND_OPTIONS.index("swaybg")] - if is_swaybg_installed: + if "swaybg" in installed_backends: try: subprocess.Popen(["killall", "swaybg"]) time.sleep(0.005) except Exception as e: print(f"{ERR_KILL} {e}") - print(missing_backends) subprocess.Popen(["swww", "init"]) command = ["swww", "img", image_path] command.extend(["--resize", fill]) diff --git a/waypaper/common.py b/waypaper/common.py index 26ab8bb..768769f 100644 --- a/waypaper/common.py +++ b/waypaper/common.py @@ -38,12 +38,15 @@ def get_random_file(folder, include_subfolders): return None -def check_missing_backends(): +def check_installed_backends(): """Check which backends are installed in the system""" - missing_backends = [] + installed_backends = [] for backend in BACKEND_OPTIONS: if backend == "wallutils": - backend = "setwallpaper" - is_backend_missing = not bool(shutil.which(backend)) - missing_backends.append(is_backend_missing) - return missing_backends + binary_name = "setwallpaper" + else: + binary_name = backend + is_installed = bool(shutil.which(binary_name)) + if is_installed: + installed_backends.append(backend) + return installed_backends diff --git a/waypaper/config.py b/waypaper/config.py index aeaebc8..d6ee83b 100644 --- a/waypaper/config.py +++ b/waypaper/config.py @@ -7,31 +7,34 @@ from sys import exit from platformdirs import user_config_path, user_pictures_path, user_cache_path from waypaper.aboutdata import AboutData -from waypaper.options import FILL_OPTIONS, SORT_OPTIONS, SWWW_TRANSITIONS +from waypaper.options import FILL_OPTIONS, SORT_OPTIONS, SWWW_TRANSITIONS, BACKEND_OPTIONS +from waypaper.common import check_installed_backends + class Config: """User configuration loaded from the config.ini file""" def __init__(self): self.image_folder = user_pictures_path() + self.installed_backends = check_installed_backends() self.selected_wallpaper = "" self.selected_monitor = "All" - self.fill_option = "fill" - self.sort_option = "name" - self.backend = "swaybg" + self.fill_option = FILL_OPTIONS[0] + self.sort_option = SORT_OPTIONS[0] + self.backend = self.installed_backends[0] if self.installed_backends else BACKEND_OPTIONS[0] self.color = "#ffffff" - self.swww_transition = "any" + self.swww_transition = SWWW_TRANSITIONS[0] self.lang = "en" self.monitors = [self.selected_monitor] self.wallpaper = [] self.include_subfolders = False - self.aboutData = AboutData() - self.cachePath = user_cache_path(self.aboutData.applicationName()) - self.configPath = user_config_path(self.aboutData.applicationName()) - self.config_file = self.configPath / "config.ini" + self.about = AboutData() + self.cache_dir = user_cache_path(self.about.applicationName()) + self.config_dir = user_config_path(self.about.applicationName()) + self.config_file = self.config_dir / "config.ini" # Create config and cache folders: - self.configPath.mkdir(parents=True, exist_ok=True) - self.cachePath.mkdir(parents=True,exist_ok=True) + self.config_dir.mkdir(parents=True, exist_ok=True) + self.cache_dir.mkdir(parents=True,exist_ok=True) self.read() diff --git a/waypaper/options.py b/waypaper/options.py index f8cdd8a..bd9b36e 100644 --- a/waypaper/options.py +++ b/waypaper/options.py @@ -14,5 +14,5 @@ IMAGE_EXTENSIONS = { BACKEND_OPTIONS[3]: ['.gif', '.jpg', '.jpeg', '.png'], } -SWWW_TRANSITIONS = ["none", "simple", "fade", "wipe", "left", "right", "top", "bottom", - "wave", "grow", "center", "any", "outer", "random"] +SWWW_TRANSITIONS = ["any", "none", "simple", "fade", "wipe", "left", "right", "top", + "bottom", "wave", "grow", "center", "outer", "random"]