--- 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.