Merge photo highlights by name and capture year
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""Keep one gallery highlight link per name and capture year."""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
||||
def field(content, name):
|
||||
match = re.search(rf"^{re.escape(name)}: (.+)$", content.split("---", 2)[1], re.MULTILINE)
|
||||
if not match:
|
||||
return None
|
||||
value = match.group(1).strip()
|
||||
return json.loads(value) if value.startswith('"') else value
|
||||
|
||||
|
||||
def normalize_highlights(art):
|
||||
"""Place each link on the newest photo in its named, dated group."""
|
||||
groups = {}
|
||||
for path in Path(art).glob("*.md"):
|
||||
content = path.read_text()
|
||||
name = field(content, "highlight_name") or field(content, "anchor")
|
||||
date = field(content, "date")
|
||||
if not name or not date:
|
||||
continue
|
||||
taken = datetime.fromisoformat(str(date))
|
||||
if taken.tzinfo is None:
|
||||
taken = taken.replace(tzinfo=timezone.utc)
|
||||
groups.setdefault((name, taken.year), []).append((taken, path, content))
|
||||
|
||||
changed = []
|
||||
for (name, _), entries in groups.items():
|
||||
# An old single anchor is already the only link; a newer named photo
|
||||
# moves the link without changing any photo's capture date or position.
|
||||
newest = max(entries, key=lambda entry: (entry[0], entry[1].name))[1]
|
||||
if len(entries) == 1 and field(entries[0][2], "anchor") == name:
|
||||
continue
|
||||
for _, path, content in entries:
|
||||
old = content
|
||||
had_anchor = field(content, "anchor") is not None
|
||||
if (path == newest and had_anchor and
|
||||
all(field(other[2], "anchor") is None for other in entries if other[1] != path)):
|
||||
continue
|
||||
if had_anchor:
|
||||
content = re.sub(r"^anchor: .+\n", "", content, count=1, flags=re.MULTILINE)
|
||||
if path == newest:
|
||||
content = content.replace("categories: art\n", "categories: art\n" +
|
||||
f"anchor: {json.dumps(name, ensure_ascii=False)}\n", 1)
|
||||
elif had_anchor:
|
||||
title = field(content, "title")
|
||||
if title and title.startswith("photo-") and f'id="{title}"' not in content:
|
||||
content = content.replace("---\n\n", f'---\n\n<div id="{title}"></div>\n\n', 1)
|
||||
if content != old:
|
||||
path.write_text(content)
|
||||
changed.append(path)
|
||||
return changed
|
||||
Reference in New Issue
Block a user