2024-05-27 02:45:23 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
from os import chdir, getenv, system
|
|
|
|
import logging
|
|
|
|
import tomllib
|
|
|
|
from datetime import datetime, time
|
|
|
|
from apscheduler.schedulers.blocking import BlockingScheduler
|
|
|
|
from apscheduler.triggers.cron import CronTrigger
|
|
|
|
|
|
|
|
# setup logging
|
|
|
|
chdir(str(getenv("HOME")) + "/.local/share/wallman/")
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
logging.basicConfig(filename="wallman.log", encoding="utf-8", level=logging.DEBUG)
|
|
|
|
|
|
|
|
# read config
|
|
|
|
# a = list(data["changing_times"].values())
|
|
|
|
# print(a[0])
|
|
|
|
|
|
|
|
class ConfigError(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class _ConfigLib:
|
|
|
|
def _initialize_config(self) -> dict:
|
|
|
|
chdir(str(getenv("HOME")) + "/.config/wallman/")
|
|
|
|
with open("wallman.toml", "rb") as config_file:
|
|
|
|
data = tomllib.load(config_file)
|
|
|
|
return data
|
|
|
|
# a = list(data["changing_times"].values())
|
|
|
|
# print(a[0])
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.config_file: dict = self._initialize_config() # Full config
|
|
|
|
# Dictionaries
|
|
|
|
self.config_wallpaper_sets: dict = self.config_file["wallpaper_sets"]
|
|
|
|
self.config_changing_times: dict = self.config_file["changing_times"]
|
|
|
|
# Values in Dicts
|
|
|
|
self.config_wallpaper_sets_enabled: bool = self.config_wallpaper_sets["enabled"]
|
|
|
|
self.config_used_sets: list = self.config_wallpaper_sets["used_sets"]
|
|
|
|
self.config_wallpapers_per_set: int = self.config_wallpaper_sets["wallpapers_per_set"]
|
|
|
|
self.config_total_changing_times: int = len(self.config_changing_times)
|
|
|
|
|
|
|
|
class ConfigValidity(_ConfigLib):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
2024-05-27 14:52:01 +02:00
|
|
|
self.chosen_wallpaper_set = False
|
2024-05-27 02:45:23 +02:00
|
|
|
|
|
|
|
def _check_wallpapers_per_set_and_changing_times(self) -> None:
|
|
|
|
# Check if the amount of wallpapers_per_set and given changing times match
|
|
|
|
if self.config_total_changing_times == self.config_wallpapers_per_set:
|
|
|
|
logger.debug("The amount of changing times and wallpapers per set is set correctly")
|
|
|
|
else:
|
|
|
|
logger.error("The amount of changing times and the amount of wallpapers per set does not match.")
|
|
|
|
raise ConfigError("Please provide an amount of changing_times equal to wallpapers_per_set.")
|
|
|
|
|
|
|
|
def _check_wallpaper_sets_validity(self) -> None:
|
|
|
|
if len(self.config_wallpaper_sets) != 3:
|
|
|
|
logger.error("An insufficient amount of parameters for wallpaper_sets has been provided, exiting...")
|
|
|
|
raise ConfigError("wallpaper_sets should have exactly 3 elements")
|
|
|
|
|
|
|
|
def _check_wallpaper_dicts(self)-> None:
|
|
|
|
# This block checks if a dictionary for each wallpaper set exists
|
|
|
|
for wallpaper_set in self.config_used_sets:
|
|
|
|
if wallpaper_set in self.config_file:
|
|
|
|
logger.debug(f"The dictionary {wallpaper_set} has been found in config.")
|
|
|
|
else:
|
|
|
|
logger.error(f"No dictionary {wallpaper_set} has been found in the config.")
|
|
|
|
raise ConfigError(f"The dictionary {wallpaper_set} has not been found in the config")
|
|
|
|
|
|
|
|
def _check_wallpaper_amount(self) -> None:
|
|
|
|
# This block checks if if each wallpaper set dictionary provides enough wallpapers to satisfy wallpapers_per_set
|
|
|
|
for wallpaper_set in self.config_used_sets:
|
|
|
|
if len(self.config_file[wallpaper_set]) == self.config_wallpapers_per_set:
|
|
|
|
logger.debug(f"Dictionary {wallpaper_set} has sufficient values.")
|
|
|
|
else:
|
|
|
|
logger.error(f"Dictionary {wallpaper_set} does not have sufficient entries")
|
|
|
|
raise ConfigError(f"Dictionary {wallpaper_set} does not have the correct amount of entries")
|
|
|
|
|
|
|
|
def validate_config(self) -> None:
|
|
|
|
self._check_wallpapers_per_set_and_changing_times()
|
|
|
|
self._check_wallpaper_sets_validity()
|
|
|
|
self._check_wallpaper_dicts()
|
|
|
|
self._check_wallpaper_amount()
|
|
|
|
logger.debug("The config file has been validated successfully (No Errors)")
|
|
|
|
|
|
|
|
class WallpaperLogic(_ConfigLib):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
|
|
|
|
2024-05-27 14:52:01 +02:00
|
|
|
# Returns a list of a split string that contains a changing time from the config file
|
2024-05-27 02:45:23 +02:00
|
|
|
def _clean_times(self, desired_time) -> list:
|
|
|
|
unclean_times = list(self.config_changing_times.values())[desired_time]
|
|
|
|
return unclean_times.split(":")
|
|
|
|
|
|
|
|
def _choose_wallpaper_set(self) -> None:
|
|
|
|
from random import choice as choose_from
|
2024-05-27 14:52:01 +02:00
|
|
|
self.chosen_wallpaper_set = choose_from(self.config_used_sets)
|
|
|
|
self.wallpaper_list = list(self.config_file[self.chosen_wallpaper_set].values())
|
|
|
|
logger.debug(f"Chose wallpaper set {self.chosen_wallpaper_set}")
|
2024-05-27 02:45:23 +02:00
|
|
|
|
2024-05-27 14:52:01 +02:00
|
|
|
# Verify if a given time is in a given range
|
2024-05-27 02:45:23 +02:00
|
|
|
def _time_in_range(self, start, end, x) -> bool:
|
|
|
|
if start <= end:
|
|
|
|
return start <= x <= end
|
|
|
|
else:
|
|
|
|
return start <= x or x < end
|
|
|
|
|
|
|
|
def set_wallpaper_by_time(self) -> None:
|
2024-05-27 14:52:01 +02:00
|
|
|
# Ensure use of a consistent wallpaper set
|
|
|
|
if self.chosen_wallpaper_set is False:
|
2024-05-27 02:45:23 +02:00
|
|
|
self._choose_wallpaper_set()
|
|
|
|
for time_range in range(self.config_total_changing_times - 1):
|
|
|
|
clean_time = self._clean_times(time_range)
|
|
|
|
clean_time_two = self._clean_times(time_range + 1)
|
|
|
|
# Check if the current time is between a given and the following changing time and if so, set that wallpaper. If not, keep trying.
|
|
|
|
if self._time_in_range(time(int(clean_time[0]), int(clean_time[1]), int(clean_time[2])), time(int(clean_time_two[0]), int(clean_time_two[1]), int(clean_time_two[2])), datetime.now().time()):
|
|
|
|
system(f"feh --bg-scale --no-fehbg {self.wallpaper_list[time_range]}")
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
system(f"feh --bg-scale --no-fehbg {self.wallpaper_list[-1]}")
|
|
|
|
|
|
|
|
def schedule_wallpapers(self):
|
|
|
|
scheduler = BlockingScheduler()
|
2024-05-27 14:52:01 +02:00
|
|
|
# Create a scheduled job for every changing time
|
2024-05-27 02:45:23 +02:00
|
|
|
for changing_time in range(len(self.config_changing_times)):
|
|
|
|
clean_time = self._clean_times(changing_time)
|
|
|
|
scheduler.add_job(self.set_wallpaper_by_time, trigger=CronTrigger(hour=clean_time[0], minute=clean_time[1], second=clean_time[2]))
|
|
|
|
scheduler.start()
|
|
|
|
logger.info("The scheduler has been started.")
|