mirror of
https://github.com/anufrievroman/waypaper.git
synced 2024-11-22 15:46:39 +03:00
Merge pull request #71 from PhilippHeuer/feat/override-folder-and-state
feat: add folder cli arg, move app state into separate file
This commit is contained in:
commit
75a8832f05
@ -47,6 +47,8 @@ parser.add_argument("--restore", help=txt.msg_arg_rest, action="store_true")
|
||||
parser.add_argument("--random", help=txt.msg_arg_rand, action="store_true")
|
||||
parser.add_argument("--fill", help=txt.msg_arg_fill, choices=FILL_OPTIONS)
|
||||
parser.add_argument("--wallpaper", help=txt.msg_arg_wall)
|
||||
parser.add_argument("--folder", help=txt.msg_arg_folder)
|
||||
parser.add_argument("--state-file", help=txt.msg_arg_statefile)
|
||||
parser.add_argument("--backend", help=txt.msg_arg_back, choices=BACKEND_OPTIONS)
|
||||
parser.add_argument("--list", help=txt.msg_arg_list, action='store_true')
|
||||
args = parser.parse_args()
|
||||
@ -54,8 +56,13 @@ args = parser.parse_args()
|
||||
|
||||
def run():
|
||||
"""Read user arguments and either run GUI app or just reset the wallpaper"""
|
||||
|
||||
cf.read()
|
||||
cf.read_state() # read default state file, if use_xdg_state is True
|
||||
cf.read_parameters_from_user_arguments(args)
|
||||
if args.state_file:
|
||||
cf.read_state() # read from custom state file if provided
|
||||
cf.read_parameters_from_user_arguments(args) # ensure that user arguments override values from state file
|
||||
cf.check_validity()
|
||||
|
||||
# Set the wallpaper and quit:
|
||||
if args.restore or args.random:
|
||||
@ -99,7 +106,7 @@ def run():
|
||||
sys.exit(0)
|
||||
|
||||
# Start GUI:
|
||||
app = App(txt)
|
||||
app = App(txt, cf)
|
||||
app.run()
|
||||
|
||||
|
||||
|
@ -52,9 +52,9 @@ def cache_image(image_path: str, cache_dir: Path) -> None:
|
||||
class App(Gtk.Window):
|
||||
"""Main application class that controls GUI"""
|
||||
|
||||
def __init__(self, txt: Chinese|English|French|German|Polish|Russian|Belarusian|Spanish) -> None:
|
||||
def __init__(self, txt: Chinese|English|French|German|Polish|Russian|Belarusian|Spanish, cf: Config) -> None:
|
||||
super().__init__(title="Waypaper")
|
||||
self.cf = Config()
|
||||
self.cf = cf
|
||||
self.about = AboutData()
|
||||
self.txt = txt
|
||||
self.check_backends()
|
||||
@ -112,7 +112,11 @@ class App(Gtk.Window):
|
||||
for option in FILL_OPTIONS:
|
||||
capitalized_option = option[0].upper() + option[1:]
|
||||
self.fill_option_combo.append_text(capitalized_option)
|
||||
self.fill_option_combo.set_active(0)
|
||||
if self.cf.fill_option in FILL_OPTIONS:
|
||||
active_fill_option_index = FILL_OPTIONS.index(self.cf.fill_option)
|
||||
self.fill_option_combo.set_active(active_fill_option_index)
|
||||
else:
|
||||
self.fill_option_combo.set_active(0)
|
||||
self.fill_option_combo.connect("changed", self.on_fill_option_changed)
|
||||
self.fill_option_combo.set_tooltip_text(self.txt.tip_fill)
|
||||
|
||||
|
@ -3,8 +3,10 @@
|
||||
import configparser
|
||||
from argparse import Namespace
|
||||
import pathlib
|
||||
import os
|
||||
from sys import exit
|
||||
from platformdirs import user_config_path, user_pictures_path, user_cache_path, user_state_path
|
||||
from typing import List
|
||||
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_TRANSITION_TYPES, BACKEND_OPTIONS
|
||||
@ -41,13 +43,15 @@ class Config:
|
||||
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"
|
||||
self.state_dir = user_state_path(self.about.applicationName())
|
||||
self.state_file = self.state_dir / "state.ini"
|
||||
self.use_xdg_state = False
|
||||
|
||||
# Create config and cache folders:
|
||||
self.config_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.cache_dir.mkdir(parents=True,exist_ok=True)
|
||||
self.state_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.read()
|
||||
self.check_validity()
|
||||
|
||||
def select_wallpaper(self, path_str: str) -> None:
|
||||
self.selected_wallpaper = pathlib.Path(path_str)
|
||||
@ -70,9 +74,7 @@ class Config:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.config_file, 'utf-8')
|
||||
|
||||
# Read parameters:
|
||||
image_folder_str = config.get("Settings", "folder", fallback=self.image_folder)
|
||||
self.image_folder = pathlib.Path(image_folder_str).expanduser()
|
||||
# Read basic parameters:
|
||||
self.fill_option = config.get("Settings", "fill", fallback=self.fill_option)
|
||||
self.sort_option = config.get("Settings", "sort", fallback=self.sort_option)
|
||||
self.backend = config.get("Settings", "backend", fallback=self.backend)
|
||||
@ -87,22 +89,44 @@ class Config:
|
||||
self.include_subfolders = config.getboolean("Settings", "subfolders", fallback=self.include_subfolders)
|
||||
self.show_hidden = config.getboolean("Settings", "show_hidden", fallback=self.show_hidden)
|
||||
self.show_gifs_only = config.getboolean("Settings", "show_gifs_only", fallback=self.show_gifs_only)
|
||||
self.use_xdg_state = config.getboolean("Settings", "use_xdg_state", fallback=self.use_xdg_state)
|
||||
|
||||
# Read and convert strings representing lists and paths:
|
||||
image_folder_str = config.get("Settings", "folder", fallback=self.image_folder)
|
||||
monitors_str = config.get("Settings", "monitors", fallback=self.selected_monitor, raw=True)
|
||||
wallpapers_str = config.get("Settings", "wallpaper", fallback="", raw=True)
|
||||
self.image_folder = pathlib.Path(image_folder_str).expanduser()
|
||||
if monitors_str:
|
||||
self.monitors = [str(monitor) for monitor in monitors_str.split(",")]
|
||||
if wallpapers_str:
|
||||
self.wallpapers = [pathlib.Path(paper).expanduser() for paper in wallpapers_str.split(",")]
|
||||
|
||||
# Check the validity of the number of columns:
|
||||
# Read and check the validity of the number of columns:
|
||||
try:
|
||||
self.number_of_columns = config.getint("Settings", "number_of_columns", fallback=self.number_of_columns)
|
||||
self.number_of_columns = int(self.number_of_columns) if int(self.number_of_columns) > 0 else 3
|
||||
except Exception:
|
||||
self.number_of_columns = 3
|
||||
|
||||
# Convert strings to lists:
|
||||
def read_state(self) -> None:
|
||||
"""Load data from the state.ini file"""
|
||||
if not self.use_xdg_state:
|
||||
return
|
||||
|
||||
state = configparser.ConfigParser()
|
||||
state.read(self.state_file, 'utf-8')
|
||||
|
||||
# Read and convert strings representing lists and paths:
|
||||
image_folder_str = state.get("State", "folder", fallback=self.image_folder)
|
||||
monitors_str = state.get("State", "monitors", fallback=self.selected_monitor, raw=True)
|
||||
wallpapers_str = state.get("State", "wallpaper", fallback="", raw=True)
|
||||
self.image_folder = pathlib.Path(image_folder_str).expanduser()
|
||||
if monitors_str:
|
||||
self.monitors = [str(monitor) for monitor in monitors_str.split(",")]
|
||||
if wallpapers_str:
|
||||
self.wallpapers = [pathlib.Path(paper).expanduser() for paper in wallpapers_str.split(",")]
|
||||
|
||||
|
||||
def check_validity(self) -> None:
|
||||
"""Check if the config parameters are valid and correct them if needed"""
|
||||
if self.backend not in BACKEND_OPTIONS:
|
||||
@ -114,11 +138,17 @@ class Config:
|
||||
if self.swww_transition_type not in SWWW_TRANSITION_TYPES:
|
||||
self.swww_transition_type = "any"
|
||||
|
||||
# Check the validity of the number of columns:
|
||||
try:
|
||||
self.number_of_columns = int(self.number_of_columns) if int(self.number_of_columns) > 0 else 3
|
||||
except Exception:
|
||||
self.number_of_columns = 3
|
||||
|
||||
if 0 > int(self.swww_transition_angle) > 180:
|
||||
self.swww_transition_angle = 0
|
||||
if 0 > int(self.swww_transition_step) > 255:
|
||||
self.swww_transition_step = 90
|
||||
if 0 > int(self.swww_transition_duration):
|
||||
if 0 > float(self.swww_transition_duration):
|
||||
self.swww_transition_duration = 2
|
||||
if 0 > int(self.swww_transition_fps):
|
||||
self.swww_transition_fps = 60
|
||||
@ -148,10 +178,13 @@ class Config:
|
||||
if not config.has_section("Settings"):
|
||||
config.add_section("Settings")
|
||||
config.set("Settings", "language", self.lang)
|
||||
config.set("Settings", "folder", self.shorten_path(self.image_folder))
|
||||
config.set("Settings", "wallpaper", self.shortened_paths(self.wallpapers))
|
||||
|
||||
if not self.use_xdg_state:
|
||||
config.set("Settings", "folder", self.shorten_path(self.image_folder))
|
||||
config.set("Settings", "monitors", ",".join(self.monitors))
|
||||
config.set("Settings", "wallpaper", self.shortened_paths(self.wallpapers))
|
||||
|
||||
config.set("Settings", "backend", self.backend)
|
||||
config.set("Settings", "monitors", ",".join(self.monitors))
|
||||
config.set("Settings", "fill", self.fill_option)
|
||||
config.set("Settings", "sort", self.sort_option)
|
||||
config.set("Settings", "color", self.color)
|
||||
@ -165,9 +198,32 @@ class Config:
|
||||
config.set("Settings", "swww_transition_angle", str(self.swww_transition_angle))
|
||||
config.set("Settings", "swww_transition_duration", str(self.swww_transition_duration))
|
||||
config.set("Settings", "swww_transition_fps", str(self.swww_transition_fps))
|
||||
config.set("Settings", "use_xdg_state", str(self.use_xdg_state))
|
||||
with open(self.config_file, "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
# Save state file:
|
||||
self.save_state()
|
||||
|
||||
|
||||
def save_state(self) -> None:
|
||||
"""Save the current state of the application"""
|
||||
if not self.use_xdg_state:
|
||||
return
|
||||
|
||||
self.attribute_selected_wallpaper()
|
||||
|
||||
# Write state to the file:
|
||||
state = configparser.ConfigParser()
|
||||
state.read(self.state_file)
|
||||
if not state.has_section("State"):
|
||||
state.add_section("State")
|
||||
state.set("State", "folder", self.shorten_path(self.image_folder))
|
||||
state.set("State", "monitors", ",".join(self.monitors))
|
||||
state.set("State", "wallpaper", self.shortened_paths(self.wallpapers))
|
||||
with open(self.state_file, "w") as statefile:
|
||||
state.write(statefile)
|
||||
|
||||
def read_parameters_from_user_arguments(self, args: Namespace) -> None:
|
||||
"""
|
||||
Read user arguments provided at the run. These values take priority over config.ini
|
||||
@ -177,4 +233,9 @@ class Config:
|
||||
self.backend = args.backend
|
||||
if args.fill:
|
||||
self.fill_option = args.fill
|
||||
if args.folder:
|
||||
self.image_folder = pathlib.Path(args.folder).expanduser()
|
||||
if args.state_file:
|
||||
self.use_xdg_state = True # Use of a custom state file implies state is in a separate file, requires use_xdg_state
|
||||
self.state_file = pathlib.Path(args.state_file).expanduser()
|
||||
|
||||
|
@ -13,6 +13,8 @@ class English:
|
||||
self.msg_arg_rand = "set a random wallpaper"
|
||||
self.msg_arg_list = "list wallpapers in json to standard out"
|
||||
self.msg_arg_wall = "set the specified wallpaper"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Selected image path:"
|
||||
self.msg_select = "Select"
|
||||
@ -63,7 +65,9 @@ class German:
|
||||
self.msg_arg_back = "legt das Backend fest, welches zum Setzen des Hintergrundbildes verwendet werden soll"
|
||||
self.msg_arg_rand = "wählt ein zufälliges Hintergrundbild aus"
|
||||
self.msg_arg_list = "list wallpapers in json to standard out"
|
||||
self.msg_arg_wall = "set the specified wallpaper"
|
||||
self.msg_arg_wall = "setzt das angegebene Hintergrundbild"
|
||||
self.msg_arg_folder = "legt fest, welcher Ordner nach Hintergrundbildern durchsucht werden soll"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Pfad zum ausgewählten Bild:"
|
||||
self.msg_select = "Auswählen"
|
||||
@ -115,6 +119,8 @@ class French:
|
||||
self.msg_arg_rand = "définir un papier peint aléatoire"
|
||||
self.msg_arg_list = "list wallpapers in json to standard out"
|
||||
self.msg_arg_wall = "set the specified wallpaper"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Chemin de l'image sélectionnée :"
|
||||
self.msg_select = "Sélectionner"
|
||||
@ -166,6 +172,8 @@ class Polish:
|
||||
self.msg_arg_rand = "ustaw losową tapetę"
|
||||
self.msg_arg_list = "list wallpapers in json to standard out"
|
||||
self.msg_arg_wall = "set the specified wallpaper"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Wybrana ścieżka obrazu:"
|
||||
self.msg_select = "Wybierz"
|
||||
@ -217,6 +225,8 @@ class Russian:
|
||||
self.msg_arg_rand = "установить случайные обои"
|
||||
self.msg_arg_list = "вывести обои и мотиноры в формате json"
|
||||
self.msg_arg_wall = "указать путь к изображению"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Выбранный путь к изображению:"
|
||||
self.msg_select = "Выбрать"
|
||||
@ -268,6 +278,8 @@ class Belarusian:
|
||||
self.msg_arg_rand = "ўсталяваць выпадковыя шпалеры"
|
||||
self.msg_arg_list = "вывесці шпалеры і матыноры ў фармаце json"
|
||||
self.msg_arg_wall = "пазначыць шлях да выявы"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Абраны шлях да выявы:"
|
||||
self.msg_select = "Выбраць"
|
||||
@ -319,6 +331,8 @@ class Chinese:
|
||||
self.msg_arg_rand = "设置随机壁纸"
|
||||
self.msg_arg_list = "list wallpapers in json to standard out"
|
||||
self.msg_arg_wall = "set the specified wallpaper"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "选择的图像路径:"
|
||||
self.msg_select = "选择"
|
||||
@ -369,6 +383,8 @@ class Spanish:
|
||||
self.msg_arg_rand = "aplica una imagen de fondo aleatoria"
|
||||
self.msg_arg_list = 'imprime un listado de las imágenes de fondo al terminal en formato "JSON"'
|
||||
self.msg_arg_wall = "establece el fondo especificado"
|
||||
self.msg_arg_folder = "specify which folder to scan for wallpapers"
|
||||
self.msg_arg_statefile = "specify a custom file to store the application state"
|
||||
|
||||
self.msg_path = "Ubicación de la imagen:"
|
||||
self.msg_select = "Selecciona"
|
||||
|
Loading…
Reference in New Issue
Block a user