#!/usr/bin/env python3
import json, re, time, urllib.request, urllib.error

API_KEY = open("/home/clawd/secrets/notion/api_key").read().strip()
DB_ID = "2ff330c2-8646-81f0-bbd9-ec474393d7a5"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Notion-Version": "2022-06-28",
    "Content-Type": "application/json",
}

def notion_req(url, data=None, method=None, retries=3):
    for attempt in range(retries):
        try:
            req = urllib.request.Request(url, headers=HEADERS, data=json.dumps(data).encode() if data else None, method=method)
            with urllib.request.urlopen(req, timeout=30) as r:
                return json.loads(r.read())
        except Exception as e:
            if attempt < retries - 1:
                time.sleep(2 * (attempt + 1))
                continue
            raise

# 1. Query all pages
pages = []
cursor = None
while True:
    body = {"page_size": 100}
    if cursor:
        body["start_cursor"] = cursor
    resp = notion_req(f"https://api.notion.com/v1/databases/{DB_ID}/query", body)
    pages.extend(resp["results"])
    if not resp.get("has_more"):
        break
    cursor = resp["next_cursor"]
    time.sleep(0.3)

# 2. Filter: has Link URL, no cover
targets = []
for p in pages:
    if p.get("cover"):
        continue
    props = p.get("properties", {})
    link = props.get("Link", {})
    url = None
    if link.get("type") == "url":
        url = link.get("url")
    if url:
        title_prop = props.get("Name") or props.get("Title") or props.get("title") or {}
        title_arr = title_prop.get("title", [])
        title = title_arr[0]["plain_text"] if title_arr else "(untitled)"
        targets.append({"id": p["id"], "url": url, "title": title})

print(f"Found {len(pages)} pages, {len(targets)} need covers\n")

# 3-6. Fetch og:image and set covers
ok = 0
fail = 0
for i, t in enumerate(targets, 1):
    try:
        req = urllib.request.Request(t["url"], headers={"User-Agent": "Mozilla/5.0"})
        with urllib.request.urlopen(req, timeout=10) as r:
            html = r.read(200_000).decode("utf-8", errors="ignore")
        head = html.split("</head>")[0] if "</head>" in html else html[:50000]
        m = re.search(r'<meta[^>]+property=["\']og:image["\'][^>]+content=["\']([^"\']+)["\']', head, re.I)
        if not m:
            m = re.search(r'<meta[^>]+content=["\']([^"\']+)["\'][^>]+property=["\']og:image["\']', head, re.I)
        if not m or not m.group(1).startswith("https://"):
            print(f"[{i}/{len(targets)}] No og:image for \"{t['title']}\" — skipped")
            fail += 1
            time.sleep(1)
            continue
        og = m.group(1)
        time.sleep(1)
        notion_req(f"https://api.notion.com/v1/pages/{t['id']}", {"cover": {"type": "external", "external": {"url": og}}}, method="PATCH")
        print(f"[{i}/{len(targets)}] Setting cover for \"{t['title']}\" → {og}")
        ok += 1
        time.sleep(0.3)
    except Exception as e:
        print(f"[{i}/{len(targets)}] Failed for \"{t['title']}\": {type(e).__name__}")
        fail += 1
        time.sleep(1)

print(f"\nDone: {ok} covers set, {fail} failed")
