feat(infra): auto-commit con 88 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: resolve_obsidian_embed
|
||||
kind: function
|
||||
lang: py
|
||||
domain: obsidian
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def resolve_obsidian_embed(vault_dir: str, embed_name: str) -> str"
|
||||
description: "Resuelve el path absoluto real de un attachment embebido buscandolo por nombre dentro de un vault de Obsidian. Obsidian resuelve los embeds ![[...]] por nombre de archivo unico (no por path), asi que esta funcion recorre el vault recursivamente (una pasada con os.walk) y devuelve el primer archivo cuyo basename coincida (case-insensitive), excluyendo .obsidian/ y .trash/. Si el embed no trae extension, acepta cualquier match de ese basename. Devuelve cadena vacia si no existe (NO lanza). Lanza si vault_dir no existe. No depende de la app GUI."
|
||||
tags: [obsidian, embed, attachment, resolve, filesystem, migrate]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: ["os"]
|
||||
params:
|
||||
- name: vault_dir
|
||||
desc: "ruta a la raiz del vault Obsidian donde buscar el attachment"
|
||||
- name: embed_name
|
||||
desc: "nombre del attachment embebido (el target de un ![[...]], lo que devuelve extract_obsidian_embeds), con o sin extension"
|
||||
output: "string con el path absoluto del primer archivo del vault cuyo basename coincide (case-insensitive) con embed_name, o cadena vacia '' si ningun archivo coincide. Excluye .obsidian/ y .trash/."
|
||||
tested: true
|
||||
tests:
|
||||
- "match exacto en subcarpeta"
|
||||
- "match case insensitive"
|
||||
- "sin extension acepta cualquier match"
|
||||
- "no existe devuelve vacio"
|
||||
- "excluye obsidian y trash"
|
||||
- "vault inexistente lanza"
|
||||
test_file_path: "python/functions/obsidian/resolve_obsidian_embed_test.py"
|
||||
file_path: "python/functions/obsidian/resolve_obsidian_embed.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join("python", "functions"))
|
||||
from obsidian import extract_obsidian_embeds, resolve_obsidian_embed
|
||||
|
||||
body = "Mi DNI: ![[dni enmanuel (2).jpg]]"
|
||||
for embed in extract_obsidian_embeds(body):
|
||||
path = resolve_obsidian_embed("/home/me/MiVault", embed)
|
||||
print(embed, "->", path or "(no encontrado)")
|
||||
# dni enmanuel (2).jpg -> /home/me/MiVault/attachments/dni enmanuel (2).jpg
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Usala junto a `extract_obsidian_embeds` cuando migres o extraigas un subgrafo de
|
||||
notas y necesites el path fisico real de cada attachment para copiarlo al nuevo
|
||||
destino. Replica la resolucion por-nombre de Obsidian sin abrir la app GUI:
|
||||
basta con el directorio del vault en disco.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Resuelve por NOMBRE de archivo, no por path.** Igual que Obsidian: busca el
|
||||
basename en TODO el vault. Si hay dos archivos con el mismo nombre en carpetas
|
||||
distintas (`fotos/logo.png` y `assets/logo.png`), devuelve el PRIMERO que
|
||||
encuentra `os.walk` — el orden de `os.walk` no esta garantizado entre sistemas,
|
||||
asi que con nombres duplicados el resultado puede no ser el embed que Obsidian
|
||||
mostraria. Para vaults con nombres ambiguos, deduplica los nombres antes de
|
||||
migrar.
|
||||
- Si el embed no existe en el vault devuelve `""` (cadena vacia), NO lanza
|
||||
excepcion. Comprueba el valor antes de usarlo como ruta.
|
||||
- SI lanza `FileNotFoundError` / `NotADirectoryError` si `vault_dir` no existe o
|
||||
no es un directorio.
|
||||
- Es impura: recorre el filesystem en cada llamada. Si vas a resolver muchos
|
||||
embeds del mismo vault, considera construir tu propio indice `basename -> path`
|
||||
con un unico `os.walk` en lugar de llamar a esta funcion en bucle.
|
||||
Reference in New Issue
Block a user