#!/usr/bin/env python3
"""Auto-Index: neue Seiten aus deiner Sitemap sofort an IndexNow melden (Bing, Yandex, Seznam und weitere).
Merkt sich bekannte URLs in einer Datei und meldet nur neue. Still, wenn nichts neu ist.
Vorlage von madebybrain.com/hermes-jobs (MIT). Läuft als Hermes-Job ohne KI (--no-agent), täglich.
Voraussetzung IndexNow: Schlüsseldatei <KEY>.txt im Wurzelverzeichnis deiner Website (siehe indexnow.org).
Google nimmt IndexNow nicht an; dort reicht die Sitemap in der Search Console.
Aufruf zum Testen ohne Meldung: auto_index.py --probe
"""
import json
import os
import re
import sys
import urllib.request

SITEMAP = os.environ.get("SITEMAP_URL", "https://example.com/sitemap.xml")
KEY = os.environ.get("INDEXNOW_KEY", "")
STATE = os.path.expanduser(os.environ.get("AUTO_INDEX_STATE", "~/.hermes/auto_index_bekannt.json"))
PROBE = "--probe" in sys.argv or not KEY  # ohne Schlüssel nur zählen, nichts melden


def lade(url):
    req = urllib.request.Request(url, headers={"User-Agent": "hermes-auto-index"})
    return urllib.request.urlopen(req, timeout=30).read().decode("utf-8", "ignore")


def urls(sitemap):
    xml = lade(sitemap)
    locs = re.findall(r"<loc>\s*([^<]+?)\s*</loc>", xml)
    if "<sitemapindex" in xml:  # Sitemap-Index: Unter-Sitemaps einsammeln
        return sorted({u for s in locs for u in urls(s)})
    return sorted(set(locs))


aktuell = urls(SITEMAP)
bekannt = set(json.load(open(STATE))) if os.path.exists(STATE) else None
if bekannt is None:  # erster Lauf: nur merken, nichts melden
    neu = []
else:
    neu = [u for u in aktuell if u not in bekannt]

if PROBE:
    grund = "Probelauf" if KEY else "kein INDEXNOW_KEY gesetzt"
    print(f"{len(aktuell)} URLs in der Sitemap, davon neu: {len(neu)} ({grund}, nichts gemeldet)")
    for u in neu:
        print("  " + u)
    raise SystemExit
if neu:
    host = re.sub(r"^https?://([^/]+).*", r"\1", SITEMAP)
    body = json.dumps({"host": host, "key": KEY, "keyLocation": f"https://{host}/{KEY}.txt", "urlList": neu}).encode()
    req = urllib.request.Request("https://api.indexnow.org/indexnow", data=body,
                                 headers={"Content-Type": "application/json; charset=utf-8"})
    code = urllib.request.urlopen(req, timeout=30).status
    print(f"Auto-Index: {len(neu)} neue URL(s) gemeldet (IndexNow HTTP {code})")
    for u in neu:
        print("  " + u)
os.makedirs(os.path.dirname(STATE), exist_ok=True)
json.dump(aktuell, open(STATE, "w"))
