fix: format

This commit is contained in:
2 * r + 2 * t
2026-03-09 21:25:33 +11:00
parent 6e59149fbf
commit cc155cf432
5 changed files with 40 additions and 37 deletions
+1 -1
View File
@@ -1,4 +1,3 @@
from pathlib import Path
import json import json
import re import re
import shutil import shutil
@@ -6,6 +5,7 @@ import subprocess
import time import time
from argparse import Namespace from argparse import Namespace
from datetime import datetime from datetime import datetime
from pathlib import Path
from caelestia.utils.notify import close_notification, notify from caelestia.utils.notify import close_notification, notify
from caelestia.utils.paths import recording_notif_path, recording_path, recordings_dir, user_config_path from caelestia.utils.paths import recording_notif_path, recording_path, recordings_dir, user_config_path
+13 -10
View File
@@ -140,9 +140,12 @@ class Command:
monitor_x = monitor.get("x") monitor_x = monitor.get("x")
monitor_y = monitor.get("y") monitor_y = monitor.get("y")
if not all(isinstance(x, (int, float)) for x in [monitor_height, monitor_width, monitor_scale, monitor_x, monitor_y]): if not all(
isinstance(x, (int, float))
for x in [monitor_height, monitor_width, monitor_scale, monitor_x, monitor_y]
):
return return
monitor_height = monitor_height / monitor_scale monitor_height = monitor_height / monitor_scale
monitor_width = monitor_width / monitor_scale monitor_width = monitor_width / monitor_scale
@@ -232,7 +235,7 @@ class Command:
window_id = event.split(">>>")[1].split(",")[0] window_id = event.split(">>>")[1].split(",")[0]
else: else:
window_id = event.split(">>")[1].split(",")[0] window_id = event.split(">>")[1].split(",")[0]
# Remove any leading > characters # Remove any leading > characters
window_id = window_id.lstrip(">") window_id = window_id.lstrip(">")
@@ -268,9 +271,9 @@ class Command:
data = event[13:] # Remove "openwindow>>>" data = event[13:] # Remove "openwindow>>>"
else: else:
data = event[12:] # Remove "openwindow>>" data = event[12:] # Remove "openwindow>>"
window_id, workspace, window_class, title = data.split(",", 3) window_id, workspace, window_class, title = data.split(",", 3)
# Remove any leading > characters # Remove any leading > characters
window_id = window_id.lstrip(">") window_id = window_id.lstrip(">")
@@ -348,19 +351,19 @@ class Command:
# Find all windows that match the pattern # Find all windows that match the pattern
matching_windows = self._find_matching_windows(temp_rule) matching_windows = self._find_matching_windows(temp_rule)
if not matching_windows: if not matching_windows:
print(f"No windows found matching pattern '{temp_rule.name}' with match type '{temp_rule.match_type}'") print(f"No windows found matching pattern '{temp_rule.name}' with match type '{temp_rule.match_type}'")
return return
print(f"Found {len(matching_windows)} matching window(s)") print(f"Found {len(matching_windows)} matching window(s)")
# Apply rule to all matching windows # Apply rule to all matching windows
success_count = 0 success_count = 0
for window in matching_windows: for window in matching_windows:
window_id = window["address"][2:] # Remove "0x" prefix window_id = window["address"][2:] # Remove "0x" prefix
window_title = window.get("title", "") window_title = window.get("title", "")
print(f"Applying rule to window 0x{window_id}: '{window_title}'") print(f"Applying rule to window 0x{window_id}: '{window_title}'")
success = self._apply_window_actions(window_id, temp_rule.width, temp_rule.height, temp_rule.actions) success = self._apply_window_actions(window_id, temp_rule.width, temp_rule.height, temp_rule.actions)
if success: if success:
@@ -386,7 +389,7 @@ class Command:
return return
window_id = address[2:] # Remove "0x" prefix window_id = address[2:] # Remove "0x" prefix
print(f"Applying rule to active window 0x{window_id}: '{window_title}'") print(f"Applying rule to active window 0x{window_id}: '{window_title}'")
success = self._apply_window_actions(window_id, temp_rule.width, temp_rule.height, temp_rule.actions) success = self._apply_window_actions(window_id, temp_rule.width, temp_rule.height, temp_rule.actions)
if success: if success:
@@ -411,7 +414,7 @@ class Command:
window_title = window.get("title", "") window_title = window.get("title", "")
initial_title = window.get("initialTitle", "") initial_title = window.get("initialTitle", "")
# Check if window matches the pattern # Check if window matches the pattern
matches = False matches = False
if temp_rule.match_type == "initialTitle": if temp_rule.match_type == "initialTitle":
+2
View File
@@ -12,9 +12,11 @@ def log_exception(func):
Used by the `apply_()` functions so that an exception, when applying Used by the `apply_()` functions so that an exception, when applying
a theme, does not prevent the other themes from being applied. a theme, does not prevent the other themes from being applied.
""" """
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
try: try:
func(*args, **kwargs) func(*args, **kwargs)
except Exception as e: except Exception as e:
log_message(f'Error during execution of "{func.__name__}()": {str(e)}') log_message(f'Error during execution of "{func.__name__}()": {str(e)}')
return wrapper return wrapper
+23 -25
View File
@@ -1,11 +1,10 @@
import fcntl
import json import json
import re import re
import subprocess
from pathlib import Path
import tempfile
import shutil import shutil
import fcntl import subprocess
import sys import tempfile
from pathlib import Path
from caelestia.utils.colour import get_dynamic_colours from caelestia.utils.colour import get_dynamic_colours
from caelestia.utils.logging import log_exception from caelestia.utils.logging import log_exception
@@ -60,7 +59,7 @@ def gen_replace_dynamic(colours: dict[str, str], template: Path, mode: str) -> s
colours_dyn = get_dynamic_colours(colours) colours_dyn = get_dynamic_colours(colours)
template_content = template.read_text() template_content = template.read_text()
template_filled = re.sub(dotField, fill_colour, template_content) template_filled = re.sub(dotField, fill_colour, template_content)
template_filled = re.sub(modeField, mode, template_filled) template_filled = re.sub(modeField, mode, template_filled)
return template_filled return template_filled
@@ -117,6 +116,7 @@ def write_file(path: Path, content: str) -> None:
f.flush() f.flush()
shutil.move(f.name, path) shutil.move(f.name, path)
@log_exception @log_exception
def apply_terms(sequences: str) -> None: def apply_terms(sequences: str) -> None:
state = c_state_dir / "sequences.txt" state = c_state_dir / "sequences.txt"
@@ -129,6 +129,7 @@ def apply_terms(sequences: str) -> None:
try: try:
# Use non-blocking write with timeout to prevent hangs # Use non-blocking write with timeout to prevent hangs
import os import os
fd = os.open(str(pt), os.O_WRONLY | os.O_NONBLOCK | os.O_NOCTTY) fd = os.open(str(pt), os.O_WRONLY | os.O_NONBLOCK | os.O_NOCTTY)
try: try:
os.write(fd, sequences.encode()) os.write(fd, sequences.encode())
@@ -155,6 +156,7 @@ def apply_discord(scss: str) -> None:
for client in "Equicord", "Vencord", "BetterDiscord", "equibop", "vesktop", "legcord": for client in "Equicord", "Vencord", "BetterDiscord", "equibop", "vesktop", "legcord":
write_file(config_dir / client / "themes/caelestia.theme.css", conf) write_file(config_dir / client / "themes/caelestia.theme.css", conf)
@log_exception @log_exception
def apply_pandora(colours: dict[str, str], mode: str) -> None: def apply_pandora(colours: dict[str, str], mode: str) -> None:
template = gen_replace(colours, templates_dir / "pandora.json", hash=True) template = gen_replace(colours, templates_dir / "pandora.json", hash=True)
@@ -197,36 +199,32 @@ def apply_htop(colours: dict[str, str]) -> None:
def sync_papirus_colors(hex_color: str) -> None: def sync_papirus_colors(hex_color: str) -> None:
"""Sync Papirus folder icon colors using hue/saturation analysis""" """Sync Papirus folder icon colors using hue/saturation analysis"""
try: try:
result = subprocess.run( result = subprocess.run(["which", "papirus-folders"], capture_output=True, check=False)
["which", "papirus-folders"],
capture_output=True,
check=False
)
if result.returncode != 0: if result.returncode != 0:
return return
except Exception: except Exception:
return return
papirus_paths = [ papirus_paths = [
Path("/usr/share/icons/Papirus"), Path("/usr/share/icons/Papirus"),
Path("/usr/share/icons/Papirus-Dark"), Path("/usr/share/icons/Papirus-Dark"),
Path.home() / ".local/share/icons/Papirus", Path.home() / ".local/share/icons/Papirus",
Path.home() / ".icons/Papirus", Path.home() / ".icons/Papirus",
] ]
if not any(p.exists() for p in papirus_paths): if not any(p.exists() for p in papirus_paths):
return return
r = int(hex_color[0:2], 16) r = int(hex_color[0:2], 16)
g = int(hex_color[2:4], 16) g = int(hex_color[2:4], 16)
b = int(hex_color[4:6], 16) b = int(hex_color[4:6], 16)
# Brightness and saturation # Brightness and saturation
max_val = max(r, g, b) max_val = max(r, g, b)
min_val = min(r, g, b) min_val = min(r, g, b)
brightness = max_val brightness = max_val
saturation = 0 if max_val == 0 else ((max_val - min_val) * 100) // max_val saturation = 0 if max_val == 0 else ((max_val - min_val) * 100) // max_val
# Low saturation = grayscale # Low saturation = grayscale
if saturation < 20: if saturation < 20:
if brightness < 85: if brightness < 85:
@@ -241,13 +239,13 @@ def sync_papirus_colors(hex_color: str) -> None:
color = _determine_hue_color(r, g, b, brightness, use_pale) color = _determine_hue_color(r, g, b, brightness, use_pale)
else: else:
color = _determine_hue_color(r, g, b, brightness, False) color = _determine_hue_color(r, g, b, brightness, False)
try: try:
subprocess.Popen( subprocess.Popen(
["sudo", "-n", "papirus-folders", "-C", color, "-u"], ["sudo", "-n", "papirus-folders", "-C", color, "-u"],
stderr=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
start_new_session=True start_new_session=True,
) )
except Exception: except Exception:
pass pass
@@ -259,7 +257,7 @@ def _determine_hue_color(r: int, g: int, b: int, brightness: int, use_pale: bool
r_ratio = (r * 100) // b if b > 0 else 0 r_ratio = (r * 100) // b if b > 0 else 0
g_ratio = (g * 100) // b if b > 0 else 0 g_ratio = (g * 100) // b if b > 0 else 0
rg_diff = abs(r - g) rg_diff = abs(r - g)
if r_ratio > 70 and g_ratio > 70: if r_ratio > 70 and g_ratio > 70:
# Both R and G high relative to B = light blue/periwinkle # Both R and G high relative to B = light blue/periwinkle
if rg_diff < 15: if rg_diff < 15:
@@ -307,7 +305,7 @@ def _determine_hue_color(r: int, g: int, b: int, brightness: int, use_pale: bool
def apply_gtk(colours: dict[str, str], mode: str) -> None: def apply_gtk(colours: dict[str, str], mode: str) -> None:
gtk_template = gen_replace(colours, templates_dir / "gtk.css", hash=True) gtk_template = gen_replace(colours, templates_dir / "gtk.css", hash=True)
thunar_template = gen_replace(colours, templates_dir / "thunar.css", hash=True) thunar_template = gen_replace(colours, templates_dir / "thunar.css", hash=True)
for gtk_version in ["gtk-3.0", "gtk-4.0"]: for gtk_version in ["gtk-3.0", "gtk-4.0"]:
gtk_config_dir = config_dir / gtk_version gtk_config_dir = config_dir / gtk_version
write_file(gtk_config_dir / "gtk.css", gtk_template) write_file(gtk_config_dir / "gtk.css", gtk_template)
@@ -316,7 +314,7 @@ def apply_gtk(colours: dict[str, str], mode: str) -> None:
subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/gtk-theme", "'adw-gtk3-dark'"]) subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/gtk-theme", "'adw-gtk3-dark'"])
subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'prefer-{mode}'"]) subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'prefer-{mode}'"])
subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/icon-theme", f"'Papirus-{mode.capitalize()}'"]) subprocess.run(["dconf", "write", "/org/gnome/desktop/interface/icon-theme", f"'Papirus-{mode.capitalize()}'"])
sync_papirus_colors(colours["primary"]) sync_papirus_colors(colours["primary"])
@@ -378,14 +376,14 @@ def apply_colours(colours: dict[str, str], mode: str) -> None:
# Use file-based lock to prevent concurrent theme changes # Use file-based lock to prevent concurrent theme changes
lock_file = c_state_dir / "theme.lock" lock_file = c_state_dir / "theme.lock"
c_state_dir.mkdir(parents=True, exist_ok=True) c_state_dir.mkdir(parents=True, exist_ok=True)
try: try:
with open(lock_file, 'w') as lock_fd: with open(lock_file, "w") as lock_fd:
try: try:
fcntl.flock(lock_fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) fcntl.flock(lock_fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except BlockingIOError: except BlockingIOError:
return return
try: try:
cfg = json.loads(user_config_path.read_text())["theme"] cfg = json.loads(user_config_path.read_text())["theme"]
except (FileNotFoundError, json.JSONDecodeError, KeyError): except (FileNotFoundError, json.JSONDecodeError, KeyError):
@@ -421,7 +419,7 @@ def apply_colours(colours: dict[str, str], mode: str) -> None:
if check("enableCava"): if check("enableCava"):
apply_cava(colours) apply_cava(colours)
apply_user_templates(colours, mode) apply_user_templates(colours, mode)
finally: finally:
try: try:
lock_file.unlink() lock_file.unlink()
+1 -1
View File
@@ -125,6 +125,7 @@ def get_colours_for_wall(wall: Path | str, no_smart: bool) -> None:
"colours": get_colours_for_image(get_thumb(wall, cache), scheme), "colours": get_colours_for_image(get_thumb(wall, cache), scheme),
} }
def convert_gif(wall: Path) -> Path: def convert_gif(wall: Path) -> Path:
cache = wallpapers_cache_dir / compute_hash(wall) cache = wallpapers_cache_dir / compute_hash(wall)
output_path = cache / "first_frame.png" output_path = cache / "first_frame.png"
@@ -143,7 +144,6 @@ def convert_gif(wall: Path) -> Path:
return output_path return output_path
def set_wallpaper(wall: Path | str, no_smart: bool) -> None: def set_wallpaper(wall: Path | str, no_smart: bool) -> None:
# Make path absolute # Make path absolute
wall = Path(wall).resolve() wall = Path(wall).resolve()