55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
"""Privacy tokens [[TOKEN]] in templates. Distinct from context {{key}}."""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from placeholders import PlaceholderError
|
|
|
|
PRIVACY_PATTERN = re.compile(r"\[\[([A-Z][A-Z0-9_]*(?::[A-Z0-9_]+)?)\]\]")
|
|
KNOWN_EXACT = {"SELF"}
|
|
KNOWN_PREFIXES = ("PERSON:", "PLACE:", "ORG:", "PROJECT:")
|
|
|
|
|
|
def catalog() -> list[dict]:
|
|
return [
|
|
{
|
|
"token": "[[SELF]]",
|
|
"kind": "exact",
|
|
"data_class": "B",
|
|
"description": "Die reflektierende Person. Mapping bleibt lokal.",
|
|
},
|
|
{
|
|
"token": "[[PERSON:ROLE]]",
|
|
"kind": "prefix",
|
|
"data_class": "B",
|
|
"description": "Andere Person als nicht sprechende Rolle, nicht als Klarname.",
|
|
},
|
|
{
|
|
"token": "[[PLACE:KIND]]",
|
|
"kind": "prefix",
|
|
"data_class": "B",
|
|
"description": "Ort als Kategorie, nicht als Adresse oder Stadtname.",
|
|
},
|
|
]
|
|
|
|
|
|
def extract_tokens(template: str) -> list[str]:
|
|
return PRIVACY_PATTERN.findall(template or "")
|
|
|
|
|
|
def validate_tokens(template: str) -> list[str]:
|
|
tokens = extract_tokens(template)
|
|
invalid = []
|
|
for token in tokens:
|
|
if token in KNOWN_EXACT:
|
|
continue
|
|
if any(token.startswith(prefix) for prefix in KNOWN_PREFIXES):
|
|
continue
|
|
invalid.append(f"[[{token}]]")
|
|
if invalid:
|
|
raise PlaceholderError(
|
|
"unknown_privacy_placeholder",
|
|
"Unbekannte Privacy-Platzhalter: " + ", ".join(sorted(set(invalid))),
|
|
)
|
|
return [f"[[{token}]]" for token in tokens]
|