diff --git a/immichup.py b/immichup.py index 683ae06..f0b5fcb 100755 --- a/immichup.py +++ b/immichup.py @@ -24,11 +24,10 @@ from typing import Any, Sequence import httpx - LOG = logging.getLogger("immichup") TAG_PORTRAIT = "aspect:portrait" TAG_LANDSCAPE = "aspect:landscape" -STUDIO_RE = re.compile(r"\b@(\S+)\b") +STUDIO_RE = re.compile(r"@([^_\s]+)") def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace: @@ -68,7 +67,8 @@ def parse_filename(image_path: Path) -> tuple[list[str], str | None] | None: if not people: return None match = STUDIO_RE.search(filename) - return people, match.group(1) if match else None + studio = match.group(1) if match else None + return people, studio def read_jpeg_dimensions(path: Path) -> tuple[int, int]: @@ -216,6 +216,7 @@ def process_image(path: Path, client: ImmichClient | None, dry_run: bool) -> boo albums = [person.lower() for person in people] tags = list(albums) if studio: + albums.append(f"@{studio.lower()}") tags.append(studio.lower()) tags.append(TAG_PORTRAIT if width <= height else TAG_LANDSCAPE) if dry_run: diff --git a/immichup_test.py b/immichup_test.py new file mode 100644 index 0000000..d919f8f --- /dev/null +++ b/immichup_test.py @@ -0,0 +1,53 @@ +#!/usr/bin/env -S uv run --script +# /// script +# dependencies = ["pytest", "httpx>=0.27,<1"] +# /// + +import sys +from pathlib import Path +from unittest.mock import Mock, patch + +import pytest + +import immichup + + +@pytest.mark.parametrize( + "filename, expected_studio", + [ + ("Irina Dreyt -- @Mavrin__0007-upscaled.jpg", "Mavrin"), + ("Irina Dreyt -- @Mavrin__0155.jpg", "Mavrin"), + ("Irina Dreyt -- @MAVRIN__0007-UPSCALED.jpg", "MAVRIN"), + ("Irina Dreyt -- @Mavrin -- Shoot__0007-upscaled.jpg", "Mavrin"), + ("Irina Dreyt -- @Studio_Name-2.jpg", "Studio"), + ("Irina Dreyt -- Shoot__0007-upscaled.jpg", None), + ], +) +def test_studio_excludes_image_number_and_upscale_suffix( + filename: str, + expected_studio: str | None, +) -> None: + assert immichup.parse_filename(image_path=Path(filename)) == (["Irina Dreyt"], expected_studio) + + +@pytest.mark.parametrize( + "filename", + [ + "Irina Dreyt -- @Mavrin__0007-upscaled.jpg", + "Irina Dreyt -- @MAVRIN__0155.jpg", + ], +) +def test_studio_album_and_tag_use_lowercase_name_without_image_suffix(filename: str) -> None: + path = Path(filename) + client = Mock(spec=immichup.ImmichClient) + with patch.object(immichup, "read_jpeg_dimensions", return_value=(600, 800)): + assert immichup.process_image(path=path, client=client, dry_run=False) + client.upload_image.assert_called_once_with( + path, + ["irina dreyt", "@mavrin"], + ["irina dreyt", "mavrin", "aspect:portrait"], + ) + + +if __name__ == "__main__": + sys.exit(pytest.main(args=[str(Path(__file__).resolve()), *sys.argv[1:]]))