8641b49bee
- tools/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.6 KiB
Python
69 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Organiza AurgiObsidian in-situ por reglas (los titulos tienen prefijos consistentes).
|
|
|
|
Mover notas dentro del mismo vault es seguro: Obsidian resuelve wikilinks/embeds por nombre,
|
|
no por ruta. Idempotente. Con --apply mueve; sin flag solo muestra el plan.
|
|
"""
|
|
import sys, os, re, shutil, glob
|
|
from collections import Counter
|
|
|
|
V = "/home/enmanuel/Obsidian/AurgiObsidian"
|
|
FECHA = re.compile(r'^\d{4}-\d{2}-\d{2}')
|
|
|
|
|
|
def cat(t):
|
|
tl = t.lower()
|
|
if FECHA.match(t):
|
|
return "bitacora"
|
|
if "excalidraw" in tl or t.startswith("Drawing") or t.startswith("2334Drawing"):
|
|
return "diagramas"
|
|
if t.startswith(("Carga DDS", "Carga Stg", "STG.", "ETL", "INITIAL_", "Carga Movimientos")) \
|
|
or t.startswith(("Llenar", "llenar_", "insert_", "update ")):
|
|
return "etl"
|
|
if t.startswith("Navision."):
|
|
return "navision"
|
|
if "reunion" in tl:
|
|
return "reuniones"
|
|
if t.startswith("GENAI") or "mioti" in tl or "prompt engineering" in tl or "curso palantir" in tl:
|
|
return "cursos"
|
|
if any(k in tl for k in ["bigquery", "big query", "looker", "metabase", "kpi", "dashboard",
|
|
"cuadro de mando", "cubo", "informe", "reporte", "visualiz", "tabla de hecho",
|
|
"modelos de datos", "segmentacion", "clustering"]):
|
|
return "bi"
|
|
if any(k in tl for k in ["sql", "query", "querys", "tabla", "tablas", "conexion", "conexiones",
|
|
"transformacion", "transformaciones", "origen", "origenes", "tpv", "vista",
|
|
"datos", "bbdd", "base de datos"]):
|
|
return "datos"
|
|
return "otros"
|
|
|
|
|
|
def main():
|
|
apply = "--apply" in sys.argv
|
|
notes = [p for p in glob.glob(f"{V}/**/*.md", recursive=True)
|
|
if "/.obsidian/" not in p and "/.git/" not in p]
|
|
plan = []
|
|
for p in notes:
|
|
rel = os.path.relpath(p, V)
|
|
if "/" in rel: # ya en subcarpeta — no remover (excepto Compartir en Drive lo dejamos)
|
|
continue
|
|
plan.append((p, cat(os.path.basename(p)[:-3])))
|
|
dist = Counter(c for _, c in plan)
|
|
print(f"AurgiObsidian: {len(plan)} notas sueltas en raiz")
|
|
for c, n in dist.most_common():
|
|
print(f" {c}: {n}")
|
|
if not apply:
|
|
print("\n(dry-run; usa --apply para mover)")
|
|
return
|
|
moved = 0
|
|
for p, c in plan:
|
|
dd = f"{V}/{c}"; os.makedirs(dd, exist_ok=True)
|
|
dst = f"{dd}/{os.path.basename(p)}"
|
|
if os.path.exists(dst):
|
|
continue
|
|
shutil.move(p, dst); moved += 1
|
|
print(f"\nmovidas: {moved}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|