From d21230c6c31c1ad8cb42ea7dc175c41d31c4b446 Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 17 Nov 2025 21:24:22 +0100 Subject: [PATCH] Dateien nach "app/core" hochladen --- app/core/derive_edges.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/app/core/derive_edges.py b/app/core/derive_edges.py index 616f5d9..6a89950 100644 --- a/app/core/derive_edges.py +++ b/app/core/derive_edges.py @@ -5,12 +5,15 @@ Modul: app/core/derive_edges.py Zweck: - Bewahrt bestehende Edgelogik (belongs_to, prev/next, references, backlink) - Ergänzt typenbasierte Default-Kanten (edge_defaults aus config/types.yaml) -- Unterstützt "typed inline relations" ([[rel:KIND | Target]] / [[rel:KIND Target]]) -- Unterstützt Obsidian-Callouts (> [!edge] KIND: [[Target]] [[Target2]] ...) - +- Unterstützt "typed inline relations": + * [[rel:KIND | Target]] + * [[rel:KIND Target]] + * rel: KIND [[Target]] +- Unterstützt Obsidian-Callouts: + * > [!edge] KIND: [[Target]] [[Target2]] ... Kompatibilität: - build_edges_for_note(...) Signatur unverändert -- rule_id Werte exakt wie zuvor erwartet (ohne Versionssuffix): +- rule_id Werte: * structure:belongs_to * structure:order * explicit:wikilink @@ -37,7 +40,7 @@ except Exception: # pragma: no cover def _get(d: dict, *keys, default=None): for k in keys: - if k in d and d[k] is not None: + if isinstance(d, dict) and k in d and d[k] is not None: return d[k] return default @@ -135,15 +138,21 @@ def _edge_defaults_for(note_type: Optional[str], reg: dict) -> List[str]: _WIKILINK_RE = re.compile(r"\[\[(?:[^\|\]]+\|)?([a-zA-Z0-9_\-#:. ]+)\]\]") # Getypte Inline-Relationen: -# [[rel:depends_on | Target]] -# [[rel:related_to Target]] +# [[rel:KIND | Target]] +# [[rel:KIND Target]] _REL_PIPE = re.compile(r"\[\[\s*rel:(?P[a-z_]+)\s*\|\s*(?P[^\]]+?)\s*\]\]", re.IGNORECASE) _REL_SPACE = re.compile(r"\[\[\s*rel:(?P[a-z_]+)\s+(?P[^\]]+?)\s*\]\]", re.IGNORECASE) +# rel: KIND [[Target]] (reines Textmuster) +_REL_TEXT = re.compile(r"rel\s*:\s*(?P[a-z_]+)\s*\[\[\s*(?P[^\]]+?)\s*\]\]", re.IGNORECASE) def _extract_typed_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: """ Gibt Liste (kind, target) zurück und den Text mit entfernten getypten Relation-Links, damit die generische Wikilink-Erkennung sie nicht doppelt zählt. + Unterstützt drei Varianten: + - [[rel:KIND | Target]] + - [[rel:KIND Target]] + - rel: KIND [[Target]] """ pairs: List[Tuple[str,str]] = [] def _collect(m): @@ -152,8 +161,10 @@ def _extract_typed_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: if k and t: pairs.append((k, t)) return "" # Link entfernen + text = _REL_PIPE.sub(_collect, text) text = _REL_SPACE.sub(_collect, text) + text = _REL_TEXT.sub(_collect, text) return pairs, text # Obsidian Callout Parser @@ -238,7 +249,7 @@ def build_edges_for_note( - belongs_to: für jeden Chunk (chunk -> note) - next / prev: zwischen aufeinanderfolgenden Chunks - references: pro Chunk aus window/text (via Wikilinks) - - typed inline relations: [[rel:KIND | Target]] oder [[rel:KIND Target]] + - typed inline relations: [[rel:KIND | Target]] / [[rel:KIND Target]] / rel: KIND [[Target]] - Obsidian Callouts: > [!edge] KIND: [[Target]] [[Target2]] - optional note-scope references/backlinks: dedupliziert über alle Chunk-Funde + note_level_references - typenbasierte Default-Kanten (edge_defaults) je gefundener Referenz @@ -369,6 +380,7 @@ def build_edges_for_note( "rule_id": f"edge_defaults:{note_type}:{rel}", "confidence": 0.7, })) + refs_all.extend(refs) # 4) optional note-scope refs/backlinks (+ defaults)