eb8dbf66a1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
"""Actualiza una nota existente de Obsidian (.md) en disco.
|
|
|
|
Compone funciones puras del grupo obsidian: parse_obsidian_frontmatter para
|
|
leer el estado actual y format_obsidian_note para reescribir. Funcion impura:
|
|
lee y reescribe un archivo en disco.
|
|
"""
|
|
|
|
import os
|
|
|
|
from obsidian import format_obsidian_note, parse_obsidian_frontmatter
|
|
|
|
|
|
def update_obsidian_note(
|
|
path: str,
|
|
body: str = None,
|
|
set_frontmatter: dict = None,
|
|
append: str = None,
|
|
) -> str:
|
|
"""Actualiza una nota Markdown de Obsidian existente.
|
|
|
|
Lee la nota actual, aplica las modificaciones pedidas y la reescribe.
|
|
|
|
Args:
|
|
path: ruta al archivo .md a actualizar.
|
|
body: si se da (no None), reemplaza por completo el cuerpo de la nota.
|
|
set_frontmatter: si se da, hace merge (update de claves) sobre el
|
|
frontmatter actual. Las claves nuevas se anaden, las existentes se
|
|
sobreescriben. Las no mencionadas se conservan.
|
|
append: si se da, concatena este texto al final del cuerpo (separado
|
|
por un salto de linea). Se aplica DESPUES de un eventual reemplazo
|
|
de body.
|
|
|
|
Returns:
|
|
La ruta del archivo actualizado.
|
|
|
|
Raises:
|
|
FileNotFoundError: si la nota no existe.
|
|
IsADirectoryError: si la ruta apunta a un directorio.
|
|
OSError: si la lectura/escritura falla por otro motivo de I/O.
|
|
"""
|
|
if not os.path.exists(path):
|
|
raise FileNotFoundError(f"obsidian note not found: {path}")
|
|
if os.path.isdir(path):
|
|
raise IsADirectoryError(f"expected a file, got a directory: {path}")
|
|
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
|
|
parsed = parse_obsidian_frontmatter(content)
|
|
frontmatter = dict(parsed.get("frontmatter", {}) or {})
|
|
current_body = parsed.get("body", "") or ""
|
|
|
|
if set_frontmatter:
|
|
frontmatter.update(set_frontmatter)
|
|
|
|
new_body = current_body if body is None else body
|
|
|
|
if append is not None:
|
|
if new_body and not new_body.endswith("\n"):
|
|
new_body = new_body + "\n" + append
|
|
else:
|
|
new_body = new_body + append
|
|
|
|
new_content = format_obsidian_note(frontmatter, new_body)
|
|
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
f.write(new_content)
|
|
|
|
return path
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import tempfile
|
|
|
|
fd, tmp = tempfile.mkstemp(suffix=".md")
|
|
os.close(fd)
|
|
with open(tmp, "w", encoding="utf-8") as f:
|
|
f.write("---\ntitle: A\n---\n\nLinea original.")
|
|
update_obsidian_note(tmp, set_frontmatter={"status": "wip"}, append="Linea nueva.")
|
|
with open(tmp, "r", encoding="utf-8") as f:
|
|
out = f.read()
|
|
assert "status" in out, out
|
|
assert "Linea nueva." in out, out
|
|
assert "Linea original." in out, out
|
|
os.remove(tmp)
|
|
print("update_obsidian_note smoke OK")
|