From 217950eeaff4f08605c569ad144d0f8e93845f21 Mon Sep 17 00:00:00 2001 From: Nick Pegg Date: Sun, 4 Aug 2024 11:57:08 -0700 Subject: [PATCH] Add cover images to albums. If a cover.jpg doesn't exist, use the first image --- photoalbum/generate.py | 46 ++++++++++++++++++++------- photoalbum/skel/_templates/album.html | 19 ++++++++--- photoalbum/skel/static/index.css | 13 ++++++++ 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/photoalbum/generate.py b/photoalbum/generate.py index d4d84b7..a5e2191 100644 --- a/photoalbum/generate.py +++ b/photoalbum/generate.py @@ -2,7 +2,7 @@ import logging from dataclasses import dataclass from pathlib import Path from pprint import pformat -from typing import Iterator +from typing import Iterator, Optional from jinja2 import Environment, FileSystemLoader, select_autoescape from PIL import Image, UnidentifiedImageError @@ -20,6 +20,8 @@ class ImageDirectory: images: list["ImagePath"] is_root: bool = False + cover_path: Optional["ImagePath"] = None + def walk(self) -> Iterator["ImageDirectory"]: yield self for child in self.children: @@ -34,6 +36,13 @@ class ImageDirectory: images += image_dir.images return images + def cover_image_paths(self) -> list["ImagePath"]: + images = [] + for image_dir in self.walk(): + if image_dir.cover_path is not None: + images.append(image_dir.cover_path) + return images + @dataclass class ImagePath: @@ -97,8 +106,20 @@ 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(ImagePath(file_path)) + ip = ImagePath(file_path) + # Set a cover image for the album. Use "cover.jpg" if one exists, + # otherwise use the first image we find. + if file_path.stem == "cover": + image_dir.cover_path = ip + # Don't add the cover image to the list of images, we want to handle + # that separately + continue + + image_dir.images.append(ip) + + if image_dir.cover_path is None and len(image_dir.images) > 0: + image_dir.cover_path = image_dir.images[0] image_dirs[image_dir.path] = image_dir return image_dirs[root_path] @@ -119,8 +140,10 @@ def generate_thumbnails(config: Config, root_dir: ImageDirectory) -> None: """ Find all of the images and generate thumbnails and on-screen versions """ - for image_path in track(root_dir.image_paths(), description="Making thumbnails..."): - logger.debug(image_path) + # Include cover images here because we want thumbnails for all of them + + all_images = root_dir.image_paths() + root_dir.cover_image_paths() + for image_path in track(all_images, description="Making thumbnails..."): orig_img = Image.open(image_path.path) slides_path = image_path.path.parent / "slides" @@ -156,9 +179,7 @@ def generate_html(config: Config, root_dir: ImageDirectory) -> None: for album_dir in root_dir.walk(): html_path = album_dir.path / "index.html" - root_path = root_dir.path.relative_to( - html_path.parent, walk_up=True - ) + root_path = root_dir.path.relative_to(html_path.parent, walk_up=True) logger.debug(f"Rendering {html_path}") with html_path.open("w") as f: @@ -172,18 +193,19 @@ def generate_html(config: Config, root_dir: ImageDirectory) -> None: for pos, image_path in enumerate(album_dir.images): # TODO: If a file with a matching name but .txt or .md, add that as the # description for the image + if image_path.path.stem == "cover": + continue + html_path = image_path.html_path() - root_path = root_dir.path.relative_to( - html_path.parent, walk_up=True - ) + root_path = root_dir.path.relative_to(html_path.parent, walk_up=True) html_path.parent.mkdir(exist_ok=True) prev_image = None next_image = None if pos != 0: - prev_image = album_dir.images[pos-1] + prev_image = album_dir.images[pos - 1] if pos < len(album_dir.images) - 1: - next_image = album_dir.images[pos+1] + next_image = album_dir.images[pos + 1] logger.debug(f"Rendering {html_path}") with html_path.open("w") as f: diff --git a/photoalbum/skel/_templates/album.html b/photoalbum/skel/_templates/album.html index 102e8cd..618b23e 100644 --- a/photoalbum/skel/_templates/album.html +++ b/photoalbum/skel/_templates/album.html @@ -9,19 +9,30 @@

{% endif %} + {% if not album_dir.is_root %} +

{{album_dir.path.name}}

+ {% endif %} {% if album_dir.children %} - + {% endif %} {% if album_dir.images %} +

Photos

{% for image in album_dir.images %}
diff --git a/photoalbum/skel/static/index.css b/photoalbum/skel/static/index.css index 2012e51..e02f270 100644 --- a/photoalbum/skel/static/index.css +++ b/photoalbum/skel/static/index.css @@ -25,6 +25,7 @@ body { #content > * { width: fit-content; + margin-top: 1em; margin-left: auto; margin-right: auto; } @@ -33,6 +34,18 @@ ul { padding-left: 1.5em; } +#album-children { + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +#album-children > * { + margin: 1em; + padding: 0.75em; + background-color: lightgrey; +} + #album-photos { display: flex; flex-wrap: wrap;