Files
old-books/_pipeline/license.py
T
2026-10-17 15:27:14 -05:00

41 lines
1.8 KiB
Python

"""License status by code. Published 1930 or earlier = US public domain as of 2026. Anything else is unknown."""
import datetime
import os
import re
import pdftext
PATTERNS = [r"first\s+published\s+in\s+(\d{4})", r"(?:©|copyright|\(c\))\s*(\d{4})"]
def find_year(units):
"""Earliest year the book's own front pages give as first publication or copyright: (year, where, text) or None."""
for pat in PATTERNS:
for u in units[:8]:
m = re.search(pat, u["text"], re.I)
if m:
return int(m.group(1)), "pdf p.%d" % u["pdf_page"], m.group(0)
return None
def run(cfg, book_dir, book, pdf):
found = find_year(pdftext.units(pdf))
limit = cfg["license"]["public_domain_max_year"]
if found is None:
status, reason, year = "unknown", "no publication year found in the book's own text", None
else:
year, where, quote = found
if year <= limit:
status = "public domain"
reason = "published %d (book text, %s: \"%s\"), %d or earlier, so US public domain as of 2026" % (year, where, quote, limit)
else:
status = "unknown"
reason = "published %d (book text, %s: \"%s\"), later than %d, so the date rule does not clear it; confirm before sharing" % (year, where, quote, limit)
today = datetime.date.today().isoformat()
book["published_year"] = year
book["license"] = {"status": status, "reason": reason, "checked": today}
with open(os.path.join(book_dir, "LICENSE_STATUS.md"), "w", encoding="utf-8") as f:
f.write("# License status\n\nStatus: %s\n\nReason: %s\n\nDate checked: %s\n\n"
"Rule: published %d or earlier is public domain in the US as of 2026; anything else is unknown until confirmed. "
"Status never blocks audio production. Nothing is published.\n" % (status, reason, today, limit))