172 lines
8.5 KiB
Python
172 lines
8.5 KiB
Python
from datetime import datetime
|
||
from pathlib import Path
|
||
import re
|
||
import unittest
|
||
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
ART = ROOT / "_art"
|
||
JOB = "7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d"
|
||
ARMENIA = [f"/img/arts/uploads/{JOB}/{index:02}.jpg" for index in (9, 8, 7, 6, 5, 4)] + [
|
||
"/img/arts/uploads/474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c/00.jpg"]
|
||
ROMANIA = [f"/img/arts/uploads/{JOB}/{index:02}.jpg" for index in (0, 1)] + [
|
||
f"/img/arts/uploads/c53f20236f166632bff163339c8e789cc09b0d7e63c5b531b1fc20705460975b/{index:02}.jpg"
|
||
for index in range(5)] + [
|
||
"/img/arts/uploads/260cc99527c13f256d4ea39d0959f5daa942c888ea882852e73fd94f6c30b7db/00.jpg",
|
||
"/img/arts/uploads/b18a2f1c7127077c801160782012cb164759f0b9dd41762205b45e4c9a07d673/00.jpg"]
|
||
COLLECTIONS = [
|
||
("Iran - Hamadan, Kermanshah, Tabriz", [
|
||
"Taq-e-Bostan_000521270020.jpg", "Taq-e-Bostan_000521270019.jpg",
|
||
"Taq-e-Bostan_000521270018.jpg", "Tabriz_000521270013.jpg",
|
||
"Tabriz_000521270012.jpg", "Iran_000521270023.jpg",
|
||
"Iran_000521270021.jpg", "Hamadan_000521270035.jpg",
|
||
"Hamadan_000521270034.jpg", "Hamadan_000521270033.jpg",
|
||
"Hamadan_000521270032.jpg", "Hamadan_000521270031.jpg",
|
||
"Ganjname,-Hamadan_000521270029.jpg", "Cowboy-from-Hamadan_000521270030.jpg",
|
||
"Bistoon_000521270027.jpg", "Bistoon_000521270026.jpg",
|
||
"Bistoon_000521270025.jpg", "Bazaar-e-Tabriz_000521270010.jpg",
|
||
"Bazaar-e-Tabriz_000521270009.jpg", "Bazaar-e-Tabriz_000521270008.jpg",
|
||
"Babataher.jpg",
|
||
]),
|
||
("Kazakhstan - World Nomad Games", [
|
||
"x_DSC-0999.jpg", "x_DSC-0994.jpg",
|
||
"World-Nomad-Games,-Kazakhstan_DSC-0685.jpg",
|
||
"World-Nomad-Games,-Kazakhstan_DSC-0536.jpg",
|
||
"World-Nomad-Games,-Kazakhstan_DSC-0472.jpg",
|
||
"World-Nomad-Games,-Kazakhstan_DSC-0298.jpg",
|
||
"World-Nomad-Games,-Kazakhstan_DSC-0251.jpg",
|
||
"Kazakhstan_DSC-0870.jpg", "Kazakhstan_DSC-0865.jpg",
|
||
]),
|
||
("Dresden & Berlin", [
|
||
"x_000512370028.jpg", "x_000512370027.jpg", "x_000512370026.jpg",
|
||
"x_000512370024.jpg", "x_000512370022.jpg", "x_000512370013.jpg",
|
||
"x_000512350002.jpg", "x_000512350001.jpg",
|
||
"Let-me-tell-you-a-story_000512370015.jpg", "Dresden_000512370034.jpg",
|
||
"Dresden_000512370033.jpg", "Dresden_000512370032.jpg",
|
||
"Dresden_000512370019.jpg", "Dresden_000512370018.jpg",
|
||
"Dresden_000512370017.jpg", "Dresden_000512370016.jpg",
|
||
]),
|
||
("Iran - Tehran & Qom", [
|
||
"Home_000512360003.jpg", "Somewhere-in-Tehran_2.jpg",
|
||
"Somewhere-in-Tehran.jpg", "Grandmother's-old-room.jpg",
|
||
]),
|
||
("Prague", [
|
||
"x_000512370006.jpg", "x_000512370005.jpg", "x_000512370003.jpg",
|
||
"Prague_000512370012.jpg", "Prague_000512360031.jpg",
|
||
"Prague_000512360030.jpg", "Prague_000512360029.jpg",
|
||
"Prague_000512360027.jpg", "Prague_000512360021.jpg",
|
||
"Prague_000512360020.jpg", "Prague_000512360019.jpg",
|
||
]),
|
||
("Belfast & Tallaght", [
|
||
"x_000512350014.jpg", "x_000512350012.jpg", "x_000512350011.jpg",
|
||
"x_000512350006.jpg", "x_000512350004.jpg", "x_000512350003.jpg",
|
||
"Bobby-Sands.jpg", "Belfast_000512350032.jpg", "Belfast_000512350027.jpg",
|
||
"Belfast_000512350026.jpg", "Belfast_000512350022.jpg",
|
||
"Belfast_000512350018.jpg",
|
||
]),
|
||
]
|
||
PARIS = "85a558a3fcf582e6f0637d6927bb5a074de422f30a389ab9589630b9c163fc0e"
|
||
PARIS_LILLE = "e013523e4dda324d603c89f93ef3e83abbcd82cb11a16f85e53b670e8613d34f"
|
||
|
||
|
||
class PhotoHighlightTests(unittest.TestCase):
|
||
def test_uploaded_photos_are_individual_and_grouped(self):
|
||
records = []
|
||
for path in ART.glob("*photo-*.md"):
|
||
content = path.read_text()
|
||
images = re.findall(r'<img src="([^"]+/uploads/[^"]+)"', content)
|
||
self.assertEqual(len(images), 1, path)
|
||
date = re.search(r'^date: "([^"]+)"', content, re.MULTILINE)
|
||
anchor = re.search(r'^anchor: "([^"]+)"', content, re.MULTILINE)
|
||
records.append((datetime.fromisoformat(date.group(1)), images[0],
|
||
anchor.group(1) if anchor else None, content))
|
||
records.sort(reverse=True)
|
||
grouped = [record for record in records if record[1] in ARMENIA + ROMANIA]
|
||
self.assertEqual([record[1] for record in grouped], ROMANIA + ARMENIA)
|
||
self.assertEqual(grouped[0][2], "Romania")
|
||
self.assertEqual(grouped[9][2], "Armenia")
|
||
self.assertIn("Transmission of Flesh by Erfan Ashourioun", grouped[11][3])
|
||
|
||
def test_2026_highlights_follow_supplied_chronology(self):
|
||
anchors = {}
|
||
for path in ART.glob("*photo-*.md"):
|
||
content = path.read_text()
|
||
anchor = re.search(r'^anchor: "([^"]+)"', content, re.MULTILINE)
|
||
if anchor and anchor.group(1) in {"Foto 64", "Armenia", "Romania"}:
|
||
date = datetime.fromisoformat(re.search(
|
||
r'^date: "([^"]+)"', content, re.MULTILINE).group(1))
|
||
anchors[anchor.group(1)] = date
|
||
self.assertLess(anchors["Foto 64"], anchors["Armenia"])
|
||
self.assertLess(anchors["Armenia"], anchors["Romania"])
|
||
|
||
def test_existing_collection_highlight_starts(self):
|
||
for anchor, filenames in COLLECTIONS:
|
||
first = next(path for path in ART.glob("*.md")
|
||
if filenames[0] in path.read_text())
|
||
self.assertIn(f'anchor: "{anchor}"', first.read_text())
|
||
|
||
def test_existing_collection_order_uses_distinct_seconds(self):
|
||
for _, filenames in COLLECTIONS:
|
||
records = []
|
||
for path in ART.glob("*.md"):
|
||
content = path.read_text()
|
||
image = re.search(r'/img/arts/[^/]+/([^)]+)\)', content)
|
||
if image:
|
||
if image.group(1) not in filenames:
|
||
continue
|
||
date = re.search(r'^date: "([^"]+)"', content, re.MULTILINE)
|
||
records.append((datetime.fromisoformat(date.group(1)), image.group(1)))
|
||
records.sort(reverse=True)
|
||
self.assertEqual([filename for _, filename in records], filenames)
|
||
self.assertEqual(len({date for date, _ in records}), len(filenames))
|
||
|
||
def test_paris_and_lille_is_one_contiguous_highlight(self):
|
||
records = []
|
||
anchors = []
|
||
for job, count in ((PARIS_LILLE, 13), (PARIS, 10)):
|
||
for index in range(count):
|
||
path = ART / f"2026-09-19-photo-{job}-{index:02}.md"
|
||
content = path.read_text()
|
||
date = re.search(r'^date: "([^"]+)"', content, re.MULTILINE)
|
||
records.append((datetime.fromisoformat(date.group(1)), job, index))
|
||
anchors.extend(re.findall(r'^anchor: "([^"]+)"', content, re.MULTILINE))
|
||
records.sort(reverse=True)
|
||
self.assertEqual([(job, index) for _, job, index in records],
|
||
[(PARIS_LILLE, index) for index in range(13)] +
|
||
[(PARIS, index) for index in range(10)])
|
||
self.assertEqual(anchors, ["Paris & Lille"])
|
||
self.assertTrue(all(date.year == 2025 for date, _, _ in records))
|
||
former_paris = (ART / f"2026-09-19-photo-{PARIS}-00.md").read_text()
|
||
self.assertEqual(former_paris.count(f'<div id="photo-{PARIS}"></div>'), 1)
|
||
|
||
def test_recent_analog_highlights_use_2025_in_supplied_order(self):
|
||
groups = (
|
||
("bf23ab31ef7b33150e9e99cb31f14b1bc27bc8143293a32bb1d4ac2193a493c6",
|
||
2, "Iranian Martyrs’ Memorial Cemetery"),
|
||
("18a628ae4ea72d0f9a68de6acfbc698449fe10e49ecf990a8ddced0b2e32949d",
|
||
3, "Geneva"),
|
||
)
|
||
newest = []
|
||
for job, count, anchor in groups:
|
||
records = []
|
||
anchors = []
|
||
for index in range(count):
|
||
content = (ART / f"2026-09-19-photo-{job}-{index:02}.md").read_text()
|
||
date = datetime.fromisoformat(re.search(
|
||
r'^date: "([^"]+)"', content, re.MULTILINE).group(1))
|
||
records.append(date)
|
||
anchors.extend(re.findall(r'^anchor: "([^"]+)"', content, re.MULTILINE))
|
||
self.assertTrue(all(date.year == 2025 for date in records))
|
||
self.assertEqual(anchors, [anchor])
|
||
newest.append(max(records))
|
||
paris_date = datetime.fromisoformat(re.search(
|
||
r'^date: "([^"]+)"',
|
||
(ART / f"2026-09-19-photo-{PARIS_LILLE}-00.md").read_text(),
|
||
re.MULTILINE).group(1))
|
||
self.assertGreater(newest[0], newest[1])
|
||
self.assertGreater(newest[1], paris_date)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|