content-explorer/content_explorer/attribution.py
tegwick f8c94d3272
All checks were successful
synthetic / suite (push) Successful in 56s
Finish the computing-basics pilot and the local OnCo reference slice.
The single-operator pilot keeps static projection. Local OnCo use requires a CC BY-NC origin notice, and the slice stays out of public CI.

Assistant: grok
Assistant-Session: 01a15378-f601-7fe2-a143-8e1500a1d59c
2026-10-19 13:04:55 +02:00

59 lines
2.4 KiB
Python

"""CC origin notices for a published source.
The duties follow the license named on the source. CC BY and CC BY-NC need
creator attribution, a license link, a link to the material, a retrieval date,
the pinned origin, and an explicit modification notice. CC0 does not require
attribution. A missing duty is a gap, not a silent default.
"""
from __future__ import annotations
from typing import Any
LICENSE_URLS = {
"CC0-1.0": "https://creativecommons.org/publicdomain/zero/1.0/",
"CC-BY-4.0": "https://creativecommons.org/licenses/by/4.0/",
"CC-BY-NC-4.0": "https://creativecommons.org/licenses/by-nc/4.0/",
"MIT": "https://opensource.org/license/mit",
}
_BY = frozenset({"CC-BY-4.0", "CC-BY-NC-4.0"})
def attribution_gaps(source: dict[str, Any]) -> list[str]:
"""Names of CC duties this source does not yet satisfy."""
license_name = str(source.get("license") or "")
gaps: list[str] = []
if not license_name:
gaps.append("license")
if not str(source.get("title") or "").strip():
gaps.append("title")
if not str(source.get("uri") or "").strip():
gaps.append("uri")
if license_name in _BY or license_name == "MIT":
if not str(source.get("attribution") or "").strip():
gaps.append("attribution")
if license_name in _BY:
expected = LICENSE_URLS[license_name]
if str(source.get("licenseUrl") or "") != expected:
gaps.append("licenseUrl")
if not str(source.get("retrievedAt") or "").strip():
gaps.append("retrievedAt")
if not str(source.get("originSha") or "").strip():
gaps.append("originSha")
if not str(source.get("modificationNotice") or "").strip():
gaps.append("modificationNotice")
if license_name == "CC-BY-NC-4.0":
attribution = str(source.get("attribution") or "")
if "onco.cc" not in attribution.lower() and "data from onco" not in attribution.lower():
# The OnCo corpus duty is the OnCo line. Other BY-NC sources may
# name a different creator; only the OnCo wording is checked when
# the attribution itself claims OnCo.
pass
if "Data from OnCo" in attribution and "onco.cc" not in attribution:
gaps.append("onco-link")
return gaps
def notice_complete(source: dict[str, Any]) -> bool:
return not attribution_gaps(source)