diff --git a/photoalbum/cli.py b/photoalbum/cli.py index c82e67f..e37aa66 100644 --- a/photoalbum/cli.py +++ b/photoalbum/cli.py @@ -63,10 +63,9 @@ def cmd_init(args: Namespace) -> None: skel_files.append(album_file_path) - if not album_file_path.exists(): - album_file_path.parent.mkdir(exist_ok=True) - album_file_path.write_bytes(skel_file_path.read_bytes()) - logger.debug(f"Created skeleton file {album_file_path}") + album_file_path.parent.mkdir(exist_ok=True) + album_file_path.write_bytes(skel_file_path.read_bytes()) + logger.debug(f"Created skeleton file {album_file_path}") print("Some basic files have been created for your album. Edit them as you need:") for p in skel_files: diff --git a/photoalbum/config.py b/photoalbum/config.py index 4effe99..6187895 100644 --- a/photoalbum/config.py +++ b/photoalbum/config.py @@ -11,7 +11,7 @@ logger = logging.getLogger(__name__) @dataclass class Config: # Size of thumbnails when looking at a folder page - thumbnail_size: tuple[int, int] = (128, 128) + thumbnail_size: tuple[int, int] = (256, 256) # Size of the image when looking at the standalone image page view_size: tuple[int, int] = (1920, 1080) diff --git a/photoalbum/generate.py b/photoalbum/generate.py index 0a002a1..e6a755b 100644 --- a/photoalbum/generate.py +++ b/photoalbum/generate.py @@ -6,8 +6,7 @@ from typing import Iterator from jinja2 import Environment, FileSystemLoader, select_autoescape from PIL import Image, UnidentifiedImageError -from rich.console import Console -from rich.progress import track +from rich.progress import Progress, track from photoalbum.config import Config @@ -18,7 +17,7 @@ logger = logging.getLogger(__name__) class ImageDirectory: path: Path children: list["ImageDirectory"] - images: list[Path] + images: list["ImagePath"] is_root: bool = False def walk(self) -> Iterator["ImageDirectory"]: @@ -26,7 +25,7 @@ class ImageDirectory: for child in self.children: yield from child.walk() - def image_paths(self) -> list[Path]: + def image_paths(self) -> list["ImagePath"]: """ Iterate through all images in this dir and children """ @@ -36,6 +35,29 @@ class ImageDirectory: return images +@dataclass +class ImagePath: + path: Path + + def thumbnail_filename(self) -> str: + return self.path.stem + ".thumb" + self.path.suffix + + def thumbnail_path(self) -> Path: + return self.path.parent / "slides" / self.thumbnail_filename() + + def display_filename(self) -> str: + return self.path.stem + ".screen" + self.path.suffix + + def display_path(self) -> Path: + return self.path.parent / "slides" / self.display_filename() + + def html_filename(self) -> str: + return self.path.with_suffix(".html").name + + def html_path(self) -> Path: + return self.path.parent / "slides" / self.html_filename() + + def generate(config: Config, album_path: Path) -> None: """ Main generation function @@ -75,7 +97,7 @@ def find_images(root_path: Path) -> ImageDirectory: for filename in sorted(filenames): file_path = dirpath / filename if is_image(file_path): - image_dir.images.append(file_path) + image_dir.images.append(ImagePath(file_path)) image_dirs[image_dir.path] = image_dir @@ -99,22 +121,22 @@ def generate_thumbnails(config: Config, root_dir: ImageDirectory) -> None: """ for image_path in track(root_dir.image_paths(), description="Making thumbnails..."): logger.debug(image_path) - orig_img = Image.open(image_path) + orig_img = Image.open(image_path.path) - slides_path = image_path.parent / "slides" + slides_path = image_path.path.parent / "slides" slides_path.mkdir(exist_ok=True) thumb_img = orig_img.copy() thumb_img.thumbnail(config.thumbnail_size) - thumb_filename = image_path.stem + ".thumb" + image_path.suffix - thumb_img.save(slides_path / thumb_filename) - logger.info(f'Generated thumbnail size "{image_path}" -> "{thumb_filename}"') + thumb_path = image_path.thumbnail_path() + thumb_img.save(thumb_path) + logger.info(f'Generated thumbnail size "{image_path.path}" -> "{thumb_path}"') screen_img = orig_img.copy() screen_img.thumbnail(config.view_size) - screen_filename = image_path.stem + ".screen" + image_path.suffix - screen_img.save(slides_path / screen_filename) - logger.info(f'Generated screen size "{image_path}" -> "{screen_filename}"') + screen_path = image_path.display_path() + screen_img.save(screen_path) + logger.info(f'Generated screen size "{image_path.path}" -> "{screen_path}"') def generate_html(config: Config, root_dir: ImageDirectory) -> None: @@ -129,20 +151,30 @@ def generate_html(config: Config, root_dir: ImageDirectory) -> None: album_tmpl = jinja_env.get_template("album.html") photo_tmpl = jinja_env.get_template("photo.html") - with Console().status("Rendering HTML..."): + with Progress() as progress: + task = progress.add_task("Rendering HTML...", total=len(root_dir.image_paths())) + for album_dir in root_dir.walk(): html_path = album_dir.path / "index.html" logger.debug(f"Rendering {html_path}") with html_path.open("w") as f: - f.write(album_tmpl.render()) + f.write( + album_tmpl.render( + album_dir=album_dir, + ) + ) for image_path in album_dir.images: # TODO: If a file with a matching name but .txt or .md, add that as the # description for the image - html_path = ( - image_path.parent / "slides" / image_path.with_suffix(".html").name - ) + html_path = image_path.html_path() html_path.parent.mkdir(exist_ok=True) logger.debug(f"Rendering {html_path}") with html_path.open("w") as f: - f.write(photo_tmpl.render()) + f.write( + photo_tmpl.render( + image_path=image_path, + ) + ) + + progress.update(task, advance=1) diff --git a/photoalbum/skel/_templates/album.html b/photoalbum/skel/_templates/album.html index 5c9a5d4..67e98a0 100644 --- a/photoalbum/skel/_templates/album.html +++ b/photoalbum/skel/_templates/album.html @@ -1 +1,29 @@ -This is the album template +{% extends "base.html" %} + +{% block content %} + {% if album_dir.children %} +