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