- core/vocab.py: extract B1-B2 level vocabulary from English content via Gemini Flash - core/anki.py: register vocab cards to AnkiConnect (English::Vocabulary deck) - core/enricher.py: add language detection field + summary_ko (Korean summary) - core/obsidian.py: render Korean + English summary in note - daemon/worker.py: call vocab extraction and Anki registration for English content
90 lines
2.3 KiB
Python
90 lines
2.3 KiB
Python
"""Save processed knowledge items as Obsidian markdown notes."""
|
|
|
|
import os
|
|
import re
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
|
|
def _slugify(text: str, max_len: int = 50) -> str:
|
|
"""Convert text to a filesystem-safe slug."""
|
|
text = re.sub(r"[^\w\s-]", "", text, flags=re.UNICODE)
|
|
text = re.sub(r"[\s_]+", "-", text).strip("-")
|
|
return text[:max_len].lower()
|
|
|
|
|
|
def save_note(
|
|
content_type: str,
|
|
title: str,
|
|
summary: str,
|
|
body: str,
|
|
tags: list[str],
|
|
source_url: str = "",
|
|
author: str = "",
|
|
date: str = "",
|
|
summary_ko: str = "",
|
|
) -> Path:
|
|
"""Save a processed knowledge item as an Obsidian markdown file.
|
|
|
|
Args:
|
|
content_type: One of 'youtube', 'url', 'text'.
|
|
title: The note title.
|
|
summary: LLM-generated summary in English.
|
|
body: Full content text.
|
|
tags: List of topic tags.
|
|
source_url: Original URL (empty for plain text).
|
|
author: Author name (may be empty).
|
|
date: Publication date in ISO 8601 format (may be empty).
|
|
summary_ko: Korean translation of the summary (may be empty).
|
|
|
|
Returns:
|
|
Path of the created markdown file.
|
|
"""
|
|
vault = os.environ.get("OBSIDIAN_VAULT", "/Users/joungmin/Documents/Obsidian Vault")
|
|
today = datetime.now().strftime("%Y-%m-%d")
|
|
now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
slug = _slugify(title) or "untitled"
|
|
|
|
# Determine subfolder by content type
|
|
subfolder_map = {
|
|
"youtube": "20 Sources/YouTube",
|
|
"url": "20 Sources/Web",
|
|
"text": "20 Sources/Notes",
|
|
}
|
|
subfolder = subfolder_map.get(content_type, "20 Sources/Notes")
|
|
note_dir = Path(vault) / subfolder
|
|
note_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
filename = f"{today}-{slug}.md"
|
|
note_path = note_dir / filename
|
|
|
|
# Build YAML frontmatter tags
|
|
tags_yaml = ", ".join(tags) if tags else ""
|
|
|
|
summary_section = f"## 요약\n{summary_ko}\n\n*(English)*\n{summary}" if summary_ko else f"## 요약\n{summary}"
|
|
|
|
content = f"""---
|
|
title: {title}
|
|
source_type: {content_type}
|
|
url: {source_url}
|
|
author: {author}
|
|
date: {date}
|
|
tags: [{tags_yaml}]
|
|
created: {today}
|
|
---
|
|
|
|
# {title}
|
|
|
|
{summary_section}
|
|
|
|
## 원문
|
|
{body}
|
|
|
|
---
|
|
*Source: {source_url}*
|
|
*Saved: {now_str}*
|
|
"""
|
|
|
|
note_path.write_text(content, encoding="utf-8")
|
|
return note_path
|