Add cover images to albums. If a cover.jpg doesn't exist, use the first image

This commit is contained in:
Nick Pegg 2024-08-04 11:57:08 -07:00
parent 2875805444
commit 217950eeaf
3 changed files with 62 additions and 16 deletions

View file

@ -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:

View file

@ -9,19 +9,30 @@
</p>
{% endif %}
{% if not album_dir.is_root %}
<h1>{{album_dir.path.name}}</h1>
{% endif %}
{% if album_dir.children %}
<ul id="album-children">
<div id="album-children">
{% for child in album_dir.children %}
<li class="album">
<div class="album">
<a href="{{child.path.name}}/">
<div>
{% if child.cover_path %}
<img src="{{child.path.name}}/slides/{{child.cover_path.thumbnail_filename()}}" />
{% endif %}
</div>
<div>
{{child.path.name}}
</div>
</a>
</li>
</div>
{% endfor %}
</ul>
</div>
{% endif %}
{% if album_dir.images %}
<h2>Photos</h2>
<div id="album-photos">
{% for image in album_dir.images %}
<div class="thumbnail">

View file

@ -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;