dump carddav

This commit is contained in:
2026-08-05 06:10:36 +02:00
parent cf3563124f
commit 447528b5ff
3 changed files with 21 additions and 4 deletions
+18 -2
View File
@@ -15,8 +15,9 @@ antwortet der Server mit 403 valid-sync-token, dann fällt der Client automatisc
auf einen vollständigen Re-Sync zurück.
"""
import logging
import os
from urllib.parse import urljoin, urlparse
from xml.etree import ElementTree as ET
from urllib.parse import urljoin
import requests
@@ -35,10 +36,11 @@ class SyncTokenInvalid(Exception):
class CardDAVClient:
def __init__(self, base_url: str, username: str, password: str, timeout: int = 30):
def __init__(self, base_url: str, username: str, password: str, timeout: int = 30, account_name: str = ""):
self.base_url = base_url
self.auth = (username, password)
self.timeout = timeout
self.account_name = account_name
self.session = requests.Session()
def _request(self, method: str, url: str, body: str, depth: str = "0"):
@@ -49,6 +51,7 @@ class CardDAVClient:
if resp.status_code == 403 and "valid-sync-token" in resp.text:
raise SyncTokenInvalid("sync-token vom Server abgelehnt")
resp.raise_for_status()
self._dump_debug(method, url, resp)
return ET.fromstring(resp.content)
def discover_principal(self) -> str:
@@ -148,3 +151,16 @@ class CardDAVClient:
if href.startswith("http"):
return href
return urljoin(self.base_url, href)
def _dump_debug(self, method: str, url: str, resp: requests.Response):
dump_dir = f"/app/debug/carddav/{self.account_name}" if self.account_name else "/app/debug/carddav"
try:
os.makedirs(dump_dir, exist_ok=True)
path = urlparse(url).path.rstrip("/").replace("/", "_") or "root"
filename = f"{method}_{path}.xml"
filepath = os.path.join(dump_dir, filename)
with open(filepath, "w", encoding="utf-8") as f:
f.write(resp.text)
logger.debug("CardDAV-Debug-Dump: %s", filepath)
except Exception:
logger.warning("Debug-Dump fehlgeschlagen", exc_info=True)
+2 -1
View File
@@ -1,7 +1,8 @@
# Copyright (c) 2026 Stefan Koelle (https://stefankoelle.de)
# Licensed under the MIT License. See LICENSE file in project root for details.
import os
import json
import os
from dotenv import load_dotenv
load_dotenv()
+1 -1
View File
@@ -19,7 +19,7 @@ logger = logging.getLogger("sync")
def sync_account(conn, account, href_to_uid_cache: dict):
client = CardDAVClient(ICLOUD_BASE_URL, account.apple_email, account.apple_app_password)
client = CardDAVClient(ICLOUD_BASE_URL, account.apple_email, account.apple_app_password, account_name=account.name)
collection_url = client.discover_collection()
stored_token = db.get_sync_token(conn, account.name)