feat(dav,obsidian): grupo dav completo (CardDAV/CalDAV client + split vcf/ics + import pipelines) + build_obsidian_graph + dav_list_calendars
Funciones reutilizables creadas esta sesion para el sistema self-hosted de contactos/calendario (Xandikos) y la app osint_web: - grupo dav (infra): split_vcards, split_vevents_to_vcalendars, extract_or_make_uid, carddav_put_vcard, caldav_put_event, dav_list_resources, dav_get_resource, dav_list_calendars - pipelines: import_vcf_to_carddav, import_ics_to_caldav - obsidian: build_obsidian_graph (grafo agregado del vault)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: split_vcards
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def split_vcards(vcf_text: str) -> list"
|
||||
description: "Divide el texto completo de un archivo .vcf en sus VCARDs individuales. Devuelve una lista de strings, cada uno un VCARD completo (BEGIN:VCARD..END:VCARD) stripeado. Pura, solo stdlib (re). Util para importar a CardDAV un .vcf exportado de Google Contacts que concatena N tarjetas en un solo archivo: cada string resultante se sube como recurso .vcf independiente."
|
||||
tags: [dav, carddav, vcard, vcf, contacts, infra, split]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [re]
|
||||
params:
|
||||
- name: vcf_text
|
||||
desc: "contenido completo del archivo .vcf, con una o varias tarjetas VCARD concatenadas. Tolera saltos de linea LF o CRLF."
|
||||
output: "list[str]. Cada elemento es un VCARD completo ('BEGIN:VCARD'..'END:VCARD') stripeado de espacios al inicio/fin. Lista vacia si el input es vacio o no contiene ninguna tarjeta."
|
||||
tested: true
|
||||
tests:
|
||||
- "test_dos_vcards_devuelve_dos"
|
||||
- "test_vcard_unico"
|
||||
- "test_input_vacio_devuelve_lista_vacia"
|
||||
- "test_crlf_se_tolera"
|
||||
- "test_cada_card_es_begin_end"
|
||||
test_file_path: "python/functions/infra/split_vcards_test.py"
|
||||
file_path: "python/functions/infra/split_vcards.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.insert(0, "python/functions")
|
||||
from infra.split_vcards import split_vcards
|
||||
|
||||
vcf = (
|
||||
"BEGIN:VCARD\r\nVERSION:3.0\r\nFN:Ada Lovelace\r\nEND:VCARD\r\n"
|
||||
"BEGIN:VCARD\r\nVERSION:3.0\r\nFN:Alan Turing\r\nEND:VCARD\r\n"
|
||||
)
|
||||
cards = split_vcards(vcf)
|
||||
print(len(cards)) # 2
|
||||
print(cards[0][:13]) # BEGIN:VCARD
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando exportas contactos de Google (o cualquier fuente) a un unico `.vcf` con
|
||||
muchas tarjetas concatenadas y necesitas subir cada una como recurso CardDAV
|
||||
separado. Es el primer paso del pipeline `import_vcf_to_carddav`: split → extraer
|
||||
UID por tarjeta → `carddav_put_vcard`. Tambien para contar/validar un `.vcf`
|
||||
sin parsear cada campo.
|
||||
|
||||
## Gotchas
|
||||
|
||||
Funcion pura sin gotchas relevantes. No valida el contenido interno del VCARD
|
||||
(no comprueba VERSION ni campos obligatorios); solo segmenta por
|
||||
BEGIN:VCARD..END:VCARD. Si una tarjeta esta truncada (sin END:VCARD) no aparece
|
||||
en la salida.
|
||||
Reference in New Issue
Block a user