35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
"""Interpret user-curated date folders without guessing dates from image files."""
|
||
|
||
import re
|
||
from datetime import date
|
||
from pathlib import PurePosixPath
|
||
|
||
_DATE = r"(?P<year>\d{4})(?:[-._年]?)(?P<month>\d{2})(?:[-._月]?)(?P<day>\d{2})(?:日)?(?!\d)"
|
||
_PREFIX = re.compile(r"^" + _DATE)
|
||
|
||
|
||
def folder_caption(name: str) -> dict[str, str] | None:
|
||
match = _PREFIX.match(name.strip())
|
||
if not match:
|
||
return None
|
||
try:
|
||
captured = date(int(match["year"]), int(match["month"]), int(match["day"]))
|
||
except ValueError:
|
||
return None
|
||
remainder = name.strip()[match.end() :].strip(" _-—–::")
|
||
title, separator, place = remainder.replace("@", "@").partition("@")
|
||
return {
|
||
"title": " ".join(title.split()),
|
||
"date": captured.isoformat(),
|
||
"place": " ".join(place.split()) if separator else "",
|
||
}
|
||
|
||
|
||
def path_caption(path: str) -> dict[str, str] | None:
|
||
# Children inherit their nearest date folder, rather than their filename.
|
||
for component in reversed(PurePosixPath(path).parent.parts):
|
||
caption = folder_caption(component)
|
||
if caption is not None:
|
||
return caption
|
||
return None
|