added automatic dark theme detection and dark mode switch

This commit is contained in:
2026-02-03 15:35:45 +01:00
committed by Florian Greistorfer
parent 2f37f78039
commit d1f7f62229
11 changed files with 370 additions and 143 deletions

View File

@@ -12,11 +12,7 @@ except ModuleNotFoundError:
RICH = False
if __package__ is None:
PACKAGE = ""
else:
PACKAGE = __package__
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__).removesuffix(PACKAGE))
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__)).removesuffix(__package__)
DEFAULT_THEME_PATH = os.path.join(SCRIPTDIR, "templates", "default.css")
DEFAULT_AUTHOR = "Author"

View File

@@ -19,7 +19,7 @@ def extract_colorscheme(theme_path: str) -> dict[str, str]:
dictionary containing color scheme variables and their hexadecimal values.
"""
logger.info("extracting color scheme from theme file", extra={"theme_path": theme_path})
pattern = r"--(color[1-4]|bcolor1):\s*(#[0-9a-fA-F]+|rgba?\([^)]*\)|hsla?\([^)]*\)|[a-zA-Z]+);"
pattern = r"--(color\d+|bcolor\d+):\s*(#[0-9a-fA-F]+|rgba?\([^)]*\)|hsla?\([^)]*\)|[a-zA-Z]+);"
colorscheme = {}
with open(theme_path, "r", encoding="utf-8") as f:

View File

@@ -20,11 +20,7 @@ from modules.argumentparser import Args
from modules.datatypes.metadata import Metadata, ImageMetadata, SubfolderMetadata
# Constants for file paths and exclusions
if __package__ is None:
PACKAGE = ""
else:
PACKAGE = __package__
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__).removesuffix(PACKAGE))
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__)).removesuffix(__package__)
FAVICON_PATH = ".static/favicon.ico"
GLOBAL_CSS_PATH = ".static/global.css"
EXCLUDES = ["index.html", "manifest.json", "robots.txt"]
@@ -393,7 +389,7 @@ def process_image(item: str, folder: str, _args: Args, baseurl: str, metadata: M
return image, metadata
def generate_html(folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str) -> set[str]:
def generate_html(folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str, darktheme: bool = False) -> set[str]:
"""
Generates HTML content for a folder of images.
@@ -463,7 +459,7 @@ def generate_html(folder: str, title: str, _args: Args, raw: list[str], version:
update_metadata(metadata, folder)
if should_generate_html(images, contains_files, _args):
subfoldertags = create_html_file(folder, title, foldername, images, subfolders, _args, version, logo, subfoldertags)
subfoldertags = create_html_file(folder, title, foldername, images, subfolders, _args, version, logo, subfoldertags, darktheme=darktheme)
else:
if os.path.exists(os.path.join(folder, "index.html")):
logger.info("removing existing index.html", extra={"folder": folder})
@@ -568,7 +564,16 @@ def format_html(html: str) -> str:
def create_html_file(
folder: str, title: str, foldername: str, images: list[ImageMetadata], subfolders: list[SubfolderMetadata], _args: Args, version: str, logo: str, subfoldertags: set[str]
folder: str,
title: str,
foldername: str,
images: list[ImageMetadata],
subfolders: list[SubfolderMetadata],
_args: Args,
version: str,
logo: str,
subfoldertags: set[str],
darktheme: bool = False,
) -> set[str]:
"""
Creates the HTML file using the template.
@@ -625,6 +630,7 @@ def create_html_file(
favicon=f"{_args.web_root_url}{FAVICON_PATH}",
stylesheet=f"{_args.web_root_url}{GLOBAL_CSS_PATH}",
theme=f"{_args.web_root_url}.static/theme.css",
darktheme=f"{_args.web_root_url}.static/theme-dark.css" if darktheme else None,
root=_args.web_root_url,
parent=f"{_args.web_root_url}{urllib.parse.quote(foldername)}",
header=f"{header} - LICENSE",
@@ -642,6 +648,7 @@ def create_html_file(
favicon=f"{_args.web_root_url}{FAVICON_PATH}",
stylesheet=f"{_args.web_root_url}{GLOBAL_CSS_PATH}",
theme=f"{_args.web_root_url}.static/theme.css",
darktheme=f"{_args.web_root_url}.static/theme-dark.css" if darktheme else None,
root=_args.web_root_url,
parent=parent,
header=header,
@@ -662,7 +669,7 @@ def create_html_file(
return set(sorted(alltags))
def list_folder(folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str) -> list[tuple[str, str, str]]:
def list_folder(folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str, darktheme: bool = False) -> list[tuple[str, str, str]]:
"""
lists and processes a folder, generating HTML files.
@@ -676,5 +683,5 @@ def list_folder(folder: str, title: str, _args: Args, raw: list[str], version: s
Returns:
list[tuple[str, str]]: list of thumbnails generated.
"""
generate_html(folder, title, _args, raw, version, logo)
generate_html(folder, title, _args, raw, version, logo, darktheme=darktheme)
return thumbnails

View File

@@ -21,11 +21,7 @@ from datetime import datetime
from pythonjsonlogger import jsonlogger
# Constants for file paths and exclusions
if __package__ is None:
PACKAGE = ""
else:
PACKAGE = __package__
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__).removesuffix(PACKAGE))
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__)).removesuffix(__package__)
LOG_DIR = os.path.join(SCRIPTDIR, "logs")
LATEST_LOG_FILE = os.path.join(LOG_DIR, "latest.jsonl")

View File

@@ -18,11 +18,7 @@ from modules.argumentparser import Args
from modules.css_color import extract_theme_color, extract_colorscheme
# Define constants for static files directory and icon sizes
if __package__ is None:
PACKAGE = ""
else:
PACKAGE = __package__
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__).removesuffix(PACKAGE))
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__)).removesuffix(__package__)
STATIC_FILES_DIR = os.path.join(SCRIPTDIR, "files")
ICON_SIZES = ["36x36", "48x48", "72x72", "96x96", "144x144", "192x192", "512x512"]