mirror of
https://github.com/skoelle/icloud-contacts-sync.git
synced 2026-09-17 15:30:24 +00:00
sync healthcheck feature
This commit is contained in:
@@ -10,14 +10,16 @@
|
|||||||
{"label": "LinkedIn", "url": "https://www.linkedin.com/search/results/all/?keywords=[fullname]"},
|
{"label": "LinkedIn", "url": "https://www.linkedin.com/search/results/all/?keywords=[fullname]"},
|
||||||
{"label": "Google Maps Home", "url": "https://www.google.com/maps?q=[homecity]"},
|
{"label": "Google Maps Home", "url": "https://www.google.com/maps?q=[homecity]"},
|
||||||
{"label": "Google Maps Work", "url": "https://www.google.com/maps?q=[workcity]"}
|
{"label": "Google Maps Work", "url": "https://www.google.com/maps?q=[workcity]"}
|
||||||
]
|
],
|
||||||
|
"healthcheck_url": "https://healthchecks.example.de/ping/abc123"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "partner",
|
"name": "partner",
|
||||||
"apple_email": "partner@icloud.com",
|
"apple_email": "partner@icloud.com",
|
||||||
"apple_app_password": "yyyy-yyyy-yyyy-yyyy",
|
"apple_app_password": "yyyy-yyyy-yyyy-yyyy",
|
||||||
"authelia_user": "partner.user",
|
"authelia_user": "partner.user",
|
||||||
"custom_links": []
|
"custom_links": [],
|
||||||
|
"healthcheck_url": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"admins": [
|
"admins": [
|
||||||
|
|||||||
+4
-2
@@ -13,12 +13,13 @@ ICLOUD_BASE_URL = "https://contacts.icloud.com/"
|
|||||||
|
|
||||||
class Account:
|
class Account:
|
||||||
def __init__(self, name: str, apple_email: str, apple_app_password: str, authelia_user: str | None,
|
def __init__(self, name: str, apple_email: str, apple_app_password: str, authelia_user: str | None,
|
||||||
custom_links: list[dict] | None = None):
|
custom_links: list[dict] | None = None, healthcheck_url: str = ""):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.apple_email = apple_email
|
self.apple_email = apple_email
|
||||||
self.apple_app_password = apple_app_password
|
self.apple_app_password = apple_app_password
|
||||||
self.authelia_user = authelia_user
|
self.authelia_user = authelia_user
|
||||||
self.custom_links = custom_links or []
|
self.custom_links = custom_links or []
|
||||||
|
self.healthcheck_url = healthcheck_url
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@@ -101,7 +102,8 @@ class Config:
|
|||||||
raise RuntimeError(f"Account-Name '{name}' ist nicht eindeutig")
|
raise RuntimeError(f"Account-Name '{name}' ist nicht eindeutig")
|
||||||
seen_names.add(name)
|
seen_names.add(name)
|
||||||
custom_links = entry.get("custom_links", [])
|
custom_links = entry.get("custom_links", [])
|
||||||
accounts.append(Account(name, email, pwd, authelia_user, custom_links))
|
healthcheck_url = entry.get("healthcheck_url", "")
|
||||||
|
accounts.append(Account(name, email, pwd, authelia_user, custom_links, healthcheck_url))
|
||||||
return accounts
|
return accounts
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
+15
@@ -9,6 +9,8 @@ vollständiger Re-Sync."""
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
import db
|
import db
|
||||||
from carddav_client import ICLOUD_BASE_URL, CardDAVClient, SyncTokenInvalid
|
from carddav_client import ICLOUD_BASE_URL, CardDAVClient, SyncTokenInvalid
|
||||||
from config import Config
|
from config import Config
|
||||||
@@ -18,6 +20,16 @@ logging.basicConfig(level=Config.LOG_LEVEL, format="%(asctime)s [%(levelname)s]
|
|||||||
logger = logging.getLogger("sync")
|
logger = logging.getLogger("sync")
|
||||||
|
|
||||||
|
|
||||||
|
def _call_healthcheck(account):
|
||||||
|
if not account.healthcheck_url:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
resp = requests.get(account.healthcheck_url, timeout=10)
|
||||||
|
logger.info("[%s] Healthcheck OK (%d)", account.name, resp.status_code)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("[%s] Healthcheck fehlgeschlagen: %s", account.name, exc)
|
||||||
|
|
||||||
|
|
||||||
def _classify_vcards(raw_vcards, raw_etags, account_name):
|
def _classify_vcards(raw_vcards, raw_etags, account_name):
|
||||||
contacts, groups = [], []
|
contacts, groups = [], []
|
||||||
for v, etag in zip(raw_vcards, raw_etags):
|
for v, etag in zip(raw_vcards, raw_etags):
|
||||||
@@ -56,6 +68,7 @@ def sync_account(conn, account, href_to_uid_cache: dict):
|
|||||||
db.save_sync_token(conn, account.name, new_token)
|
db.save_sync_token(conn, account.name, new_token)
|
||||||
db.finish_sync_run(conn, run_id, "success", upserted=len(contacts), deleted=0)
|
db.finish_sync_run(conn, run_id, "success", upserted=len(contacts), deleted=0)
|
||||||
logger.info("[%s] Initialer Sync abgeschlossen: %d Kontakte, %d Gruppen", account.name, len(contacts), len(groups))
|
logger.info("[%s] Initialer Sync abgeschlossen: %d Kontakte, %d Gruppen", account.name, len(contacts), len(groups))
|
||||||
|
_call_healthcheck(account)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -72,6 +85,7 @@ def sync_account(conn, account, href_to_uid_cache: dict):
|
|||||||
db.save_sync_token(conn, account.name, new_token)
|
db.save_sync_token(conn, account.name, new_token)
|
||||||
db.finish_sync_run(conn, run_id, "success", upserted=len(contacts), deleted=0)
|
db.finish_sync_run(conn, run_id, "success", upserted=len(contacts), deleted=0)
|
||||||
logger.info("[%s] Re-Sync abgeschlossen: %d Kontakte, %d Gruppen", account.name, len(contacts), len(groups))
|
logger.info("[%s] Re-Sync abgeschlossen: %d Kontakte, %d Gruppen", account.name, len(contacts), len(groups))
|
||||||
|
_call_healthcheck(account)
|
||||||
return
|
return
|
||||||
|
|
||||||
contacts, groups = _classify_vcards(changed_vcards, etags, account.name)
|
contacts, groups = _classify_vcards(changed_vcards, etags, account.name)
|
||||||
@@ -97,6 +111,7 @@ def sync_account(conn, account, href_to_uid_cache: dict):
|
|||||||
"[%s] Delta-Sync abgeschlossen: %d geändert/neu, %d gelöscht (%d Gruppen geändert)",
|
"[%s] Delta-Sync abgeschlossen: %d geändert/neu, %d gelöscht (%d Gruppen geändert)",
|
||||||
account.name, len(contacts), len(deleted_uids), len(groups),
|
account.name, len(contacts), len(deleted_uids), len(groups),
|
||||||
)
|
)
|
||||||
|
_call_healthcheck(account)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception("[%s] Sync-Lauf %s fehlgeschlagen", account.name, run_id)
|
logger.exception("[%s] Sync-Lauf %s fehlgeschlagen", account.name, run_id)
|
||||||
print(f"SYNC-FEHLER [{account.name}]: {exc}", file=sys.stderr, flush=True)
|
print(f"SYNC-FEHLER [{account.name}]: {exc}", file=sys.stderr, flush=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user