diff --git a/src/api/main.py b/src/api/main.py index ece6f0a..fbee19d 100644 --- a/src/api/main.py +++ b/src/api/main.py @@ -31,7 +31,7 @@ templates = Jinja2Templates(directory="api/templates") def _row_to_contact_out(row: dict) -> dict: row = dict(row) - for field in ["emails", "phones", "addresses", "urls", "categories"]: + for field in ["emails", "phones", "addresses", "urls", "social_profiles", "categories"]: raw = row.get(field) row[field] = json.loads(raw) if raw else [] if not row.get("full_name"): @@ -76,7 +76,7 @@ def list_contacts( cur.execute( f"""SELECT id, account, uid, full_name, given_name, family_name, organization, - job_title, birthday, notes, emails, phones, addresses, urls, categories, updated_at + job_title, birthday, notes, emails, phones, addresses, urls, social_profiles, categories, updated_at FROM contacts {where_clause}{search_clause} ORDER BY full_name LIMIT %s OFFSET %s""", @@ -98,7 +98,7 @@ def get_contact(contact_id: int, current_user: str = Depends(get_current_user)): with conn.cursor() as cur: cur.execute( f"""SELECT id, account, uid, full_name, given_name, family_name, organization, - job_title, birthday, notes, emails, phones, addresses, urls, categories, updated_at + job_title, birthday, notes, emails, phones, addresses, urls, social_profiles, categories, updated_at FROM contacts {where_clause} {id_clause}""", params + [contact_id], ) @@ -121,7 +121,7 @@ def birthdays_today(current_user: str = Depends(get_current_user)): with conn.cursor() as cur: cur.execute( f"""SELECT id, account, uid, full_name, given_name, family_name, organization, - job_title, birthday, notes, emails, phones, addresses, urls, categories, updated_at + job_title, birthday, notes, emails, phones, addresses, urls, social_profiles, categories, updated_at FROM contacts {where_clause} {month_day_clause} ORDER BY full_name""", params + [today.month, today.day], @@ -293,7 +293,7 @@ def web_contact( with conn.cursor() as cur: cur.execute( f"""SELECT id, account, uid, full_name, given_name, family_name, organization, - job_title, birthday, notes, emails, phones, addresses, urls, categories, updated_at + job_title, birthday, notes, emails, phones, addresses, urls, social_profiles, categories, updated_at FROM contacts {where_clause} {id_clause}""", params + [contact_id], ) diff --git a/src/api/schemas.py b/src/api/schemas.py index c8e3f1e..600ed68 100644 --- a/src/api/schemas.py +++ b/src/api/schemas.py @@ -19,6 +19,7 @@ class ContactOut(BaseModel): phones: list addresses: list urls: list + social_profiles: list categories: list updated_at: str diff --git a/src/api/templates/contact.html b/src/api/templates/contact.html index f4bb794..93c0d75 100644 --- a/src/api/templates/contact.html +++ b/src/api/templates/contact.html @@ -277,6 +277,20 @@ {% endif %} + {% if contact.social_profiles %} +
+
Soziale Profile
+
+ {% for sp in contact.social_profiles %} +
+ {{ sp.type }}{% if sp.username %} ({{ sp.username }}){% endif %} + {{ sp.url }} +
+ {% endfor %} +
+
+ {% endif %} + {% if contact.categories %}
Kategorien
diff --git a/src/vcard_parser.py b/src/vcard_parser.py index ddc6e86..af4af2d 100644 --- a/src/vcard_parser.py +++ b/src/vcard_parser.py @@ -69,6 +69,21 @@ def parse_vcard(raw_text: str, account: str, etag: str | None = None) -> dict | urls = [{"type": _type_str(u), "value": u.value} for u in getattr(vcard, "url_list", [])] + social_profiles = [] + for sp in vcard.contents.get("x-socialprofile", []): + params = getattr(sp, "params", {}) + type_val = params.get("TYPE") or params.get("type") or "other" + if isinstance(type_val, list): + type_val = type_val[0] if type_val else "other" + username = params.get("X-USER") or params.get("x-user") or "" + if isinstance(username, list): + username = username[0] if username else "" + social_profiles.append({ + "type": type_val, + "username": username, + "url": sp.value if sp.value else "", + }) + categories = [c.strip() for c in vcard.categories.value] if hasattr(vcard, "categories") else [] birthday = str(vcard.bday.value)[:10] if hasattr(vcard, "bday") else None @@ -100,7 +115,7 @@ def parse_vcard(raw_text: str, account: str, etag: str | None = None) -> dict | "phones": json.dumps(phones, ensure_ascii=False), "addresses": json.dumps(addresses, ensure_ascii=False), "urls": json.dumps(urls, ensure_ascii=False), - "social_profiles": json.dumps([], ensure_ascii=False), + "social_profiles": json.dumps(social_profiles, ensure_ascii=False), "related_names": json.dumps([], ensure_ascii=False), "categories": json.dumps(categories, ensure_ascii=False), "raw_vcard": raw_text,