From 0d29fd0486c00bd316bd92c0fba778ad111789a0 Mon Sep 17 00:00:00 2001 From: Stefan Koelle Date: Wed, 5 Aug 2026 01:16:52 +0200 Subject: [PATCH] fix 3 --- src/db.py | 19 +++++++++++++++++++ src/vcard_parser.py | 10 +++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/db.py b/src/db.py index 1d00ce1..9871cab 100644 --- a/src/db.py +++ b/src/db.py @@ -95,6 +95,7 @@ def upsert_contacts(conn, contacts: list[dict], run_id: str): with conn.cursor() as cur: for c in contacts: c["sync_run_id"] = run_id + c = _sanitize_contact(c) cols = list(c.keys()) placeholders = ", ".join(["%s"] * len(cols)) update_clause = ", ".join(f"{col}=VALUES({col})" for col in cols if col not in ("account", "uid")) @@ -118,12 +119,30 @@ def delete_contacts_by_href_uids(conn, account: str, uids: list[str]): conn.commit() +def _sanitize_contact(c: dict) -> dict: + """Stellt sicher, dass alle Werte Skalare sind (kein tuple/list/dict).""" + sanitized = {} + for k, v in c.items(): + if isinstance(v, (list, tuple)): + # JSON-Felder sind bereits serialisiert, andere zu Strings machen + if k in ("emails", "phones", "addresses", "urls", "social_profiles", "related_names", "categories"): + sanitized[k] = v # bereits JSON-String + else: + sanitized[k] = ",".join(str(x) for x in v) if v else None + elif isinstance(v, dict): + sanitized[k] = str(v) if v else None + else: + sanitized[k] = v + return sanitized + + def replace_all_contacts_for_account(conn, account: str, contacts: list[dict], run_id: str): """Voller Re-Sync für einen Account (initialer Lauf oder Recovery nach ungültigem sync-token).""" with conn.cursor() as cur: cur.execute("DELETE FROM contacts WHERE account = %s", (account,)) for c in contacts: c["sync_run_id"] = run_id + c = _sanitize_contact(c) cols = ", ".join(c.keys()) placeholders = ", ".join(["%s"] * len(c)) cur.execute(f"INSERT INTO contacts ({cols}) VALUES ({placeholders})", list(c.values())) diff --git a/src/vcard_parser.py b/src/vcard_parser.py index d03c14c..61338ee 100644 --- a/src/vcard_parser.py +++ b/src/vcard_parser.py @@ -44,11 +44,11 @@ def parse_vcard(raw_text: str, account: str) -> dict | None: return None n = getattr(vcard, "n", None) - given_name = n.value.given if n else None - family_name = n.value.family if n else None - middle_name = n.value.additional if n else None - prefix = n.value.prefix if n else None - suffix = n.value.suffix if n else None + given_name = _scalar(n.value.given) if n else None + family_name = _scalar(n.value.family) if n else None + middle_name = _scalar(n.value.additional) if n else None + prefix = _scalar(n.value.prefix) if n else None + suffix = _scalar(n.value.suffix) if n else None emails = [{"type": _type_str(e), "value": e.value} for e in getattr(vcard, "email_list", [])]