72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
"""Wiki-link generation from detected entities.
|
|
|
|
Converts entity references to SilverBullet-compatible wiki-links:
|
|
- Person → [[people/firstname-lastname]]
|
|
- Project → [[projects/project-slug]]
|
|
|
|
Only the first occurrence of each entity is linked; subsequent mentions remain plain text.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from slugify import slugify
|
|
|
|
from ingestion.enrichment.models import Entity
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _entity_to_wikilink(entity: Entity) -> str:
|
|
"""Convert an entity to its wiki-link representation."""
|
|
slug = slugify(entity.value)
|
|
if entity.type == "person":
|
|
return f"[[people/{slug}]]"
|
|
elif entity.type == "project":
|
|
return f"[[projects/{slug}]]"
|
|
return ""
|
|
|
|
|
|
def generate_wiki_links(text: str, entities: list[Entity]) -> str:
|
|
"""Insert wiki-links into text for person and project entities.
|
|
|
|
Only the first occurrence of each entity's value is converted to a wiki-link.
|
|
Dates and action_items are skipped (handled by frontmatter/renderer).
|
|
|
|
Args:
|
|
text: The document body text.
|
|
entities: List of detected entities from enrichment.
|
|
|
|
Returns:
|
|
Text with wiki-links inserted at first occurrence of each entity.
|
|
"""
|
|
# Filter to linkable entity types
|
|
linkable = [e for e in entities if e.type in ("person", "project")]
|
|
|
|
# Track which entity values we've already linked (case-insensitive)
|
|
linked_values: set[str] = set()
|
|
|
|
for entity in linkable:
|
|
lower_val = entity.value.lower()
|
|
if lower_val in linked_values:
|
|
continue
|
|
|
|
# Find first occurrence and replace it
|
|
idx = text.find(entity.value)
|
|
if idx == -1:
|
|
# Try case-insensitive search
|
|
idx = text.lower().find(lower_val)
|
|
if idx == -1:
|
|
continue
|
|
# Use the actual text at that position for replacement
|
|
original_text = text[idx : idx + len(entity.value)]
|
|
else:
|
|
original_text = entity.value
|
|
|
|
wikilink = _entity_to_wikilink(entity)
|
|
if wikilink:
|
|
# Replace only the first occurrence
|
|
text = text[:idx] + wikilink + text[idx + len(original_text) :]
|
|
linked_values.add(lower_val)
|
|
|
|
return text
|