73f41a3474
dav_get_collection trae TODOS los recursos de una coleccion CardDAV/CalDAV en UNA peticion REPORT (addressbook-query / calendar-query) con el contenido vCard / VCALENDAR inline, evitando el patron N+1 (PROPFIND + un GET por recurso). Para 1064 contactos baja de ~9s a ~1s. dav_collection_ctag lee el ctag de la coleccion (PROPFIND Depth:0 barato) para validar caches sin descargar cuando nada cambio. Ambas: solo stdlib, basic auth, verify_tls, error-safe, tests que mockean el multistatus. Grupo dav, verificadas contra Xandikos real. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.6 KiB
5.6 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dav_get_collection | function | py | infra | 1.0.0 | impure | def dav_get_collection(base_url: str, username: str, password: str, collection_path: str, content_type: str = 'vcard', *, timeout_s: float = 30.0, verify_tls: bool = True) -> dict | Descarga TODOS los recursos de una coleccion DAV en UNA peticion HTTP REPORT con el contenido inline, evitando el patron N+1 (PROPFIND + un GET por recurso). Usa addressbook-query (CardDAV, content_type='vcard') o calendar-query (CalDAV, content_type='ical'); el servidor responde un multistatus con el vCard/VCALENDAR de cada recurso embebido. Construye el header Authorization: Basic base64(user:pass) a mano con stdlib, parsea el XML con regex simple y des-escapa las entidades XML del contenido. Para 1064 contactos baja de ~9s (N GETs) a ~1s (1 REPORT). verify_tls=True por defecto. Maneja errores sin lanzar. Solo stdlib (urllib, base64, re, ssl, html). Probado contra Xandikos. |
|
false | error_go_core |
|
|
dict. En exito: {status:'ok', http_status:int, resources:[{href:str, etag:str|None, data:str}, ...]} con un elemento por recurso de la coleccion; data es el vCard / VCALENDAR completo ya des-escapado. En error (sin lanzar): {status:'error', error:str, http_status:int|None}. | true |
|
python/functions/infra/dav_get_collection_test.py | python/functions/infra/dav_get_collection.py |
Ejemplo
import sys
sys.path.insert(0, "python/functions")
from infra.pass_get_secret import pass_get_secret
from infra.dav_get_collection import dav_get_collection
pw = pass_get_secret("dav/xandikos-enmanuel")["value"] # NO logear
# Todos los contactos en UNA peticion (~1s para 1064 vCards):
res = dav_get_collection(
base_url="https://dav-eedeb681c4ab89ab8e444ac9.organic-machine.com",
username="enmanuel",
password=pw,
collection_path="/enmanuel/contacts/addressbook/",
content_type="vcard",
)
print(res["status"], len(res["resources"])) # ok 1064
print(res["resources"][0]["data"][:40]) # BEGIN:VCARD\nVERSION:3.0\nFN:...
# Todos los eventos del calendario en UNA peticion:
cal = dav_get_collection(
base_url="https://dav-eedeb681c4ab89ab8e444ac9.organic-machine.com",
username="enmanuel",
password=pw,
collection_path="/enmanuel/calendars/calendar/",
content_type="ical",
)
print(cal["status"], len(cal["resources"])) # ok 98
Cuando usarla
Cuando necesitas el contenido de TODOS los recursos de una coleccion CardDAV o
CalDAV (renderizar la agenda completa, listar todos los eventos, sincronizar en
bloque) y no solo sus hrefs. Sustituye a dav_list_resources + un
dav_get_resource por recurso: una sola ida y vuelta en lugar de N+1, lo que
para colecciones de cientos/miles de recursos es la diferencia entre ~9s y ~1s.
Si solo necesitas los hrefs/etags (sin contenido), usa dav_list_resources; si
necesitas un unico recurso, usa dav_get_resource.
Gotchas
- Usa los REPORT
addressbook-query/calendar-query(RFC 6352 / 4791) con Depth:1, NOaddressbook-multiget(que en Xandikos exige Depth:0 + una lista explicita de hrefs en el cuerpo). El query no necesita conocer los hrefs de antemano: una sola peticion trae todo. - El namespace CardDAV/CalDAV es el "legacy"
urn:ietf:params:xml:ns:carddav(con:ns:), que es el que Xandikos anuncia en susupported-report-set. El namespace sin:ns:(urn:ietf:params:xml:carddav) provoca un 403 "Unknown report" en Xandikos. - El contenido inline viene XML-escapado en el multistatus (
<,>,&); la funcion lo des-escapa conhtml.unescapeantes de devolverlo. Eldataresultante es el vCard / VCALENDAR tal cual lo guardo el servidor. - El parseo es regex simple sobre el multistatus (KISS, sin parser XML): robusto para la salida estandar de Xandikos, podria fallar con XML muy exotico.
- La respuesta puede ser grande (~600KB para 1000 contactos): el timeout default
es 30s, mayor que el de
dav_list_resourcespor eso. - Lectura remota real sobre TLS; password de
pass, no se logea.