#!/usr/bin/env python """Probe a wiki host and report how (or whether) it can be mirrored. Phase 0 of the build, as a command: python scripts/detect_wiki.py https://some.wiki.example.com Reports the source kind, the endpoint, the article URL pattern, and — for MediaWiki — the engine version and page count. Exits non-zero if the host cannot be mirrored at all, so it can gate a scaffold. """ from __future__ import annotations import sys import httpx from wikikb import config from wikikb.sources import MEDIAWIKI, SitemapHtmlSource, detect_source_kind def main(argv: list[str] | None = None) -> int: args = sys.argv[1:] if argv is None else argv if not args: print("usage: detect_wiki.py ", file=sys.stderr) return 2 host = args[0].rstrip("/") with httpx.Client( headers={"User-Agent": config.USER_AGENT}, timeout=30, follow_redirects=True ) as client: try: kind, endpoint = detect_source_kind(client.get, host) except RuntimeError as exc: print(f"[FAIL] {exc}") return 1 print(f"[ OK ] source kind : {kind}") print(f" endpoint : {endpoint}") if kind == MEDIAWIKI: info = client.get( f"{endpoint}?action=query&meta=siteinfo&siprop=general|statistics&format=json" ).json()["query"] general, stats = info["general"], info["statistics"] base = general.get("base", "") pattern = "{host}/wiki/{title}" if "/wiki/" in base else "{host}/{title}" print(f" engine : {general.get('generator')}") print(f" content : {stats.get('articles')} articles") print(f" article URL : {pattern}") print(f" licence : {info.get('rightsinfo', {}).get('text', 'unknown')}") print("\nScaffold with:") print(f" WIKI_KB_HOST={host} WIKI_KB_API_URL={endpoint}") if pattern.endswith("/wiki/{title}"): print(f" WIKI_KB_PAGE_URL='{host}/wiki/{{title}}'") else: urls = list(SitemapHtmlSource(client.get, sitemap_url=endpoint).iter_titles()) print(f" content : {len(urls)} sitemap URLs") print(f" sample : {urls[:5]}") print("\n[WARN] No API. Revision ids and maxlag are unavailable, so fidelity") print(" checks fall back to content diffing and rate limiting is purely") print(" self-imposed. Check the site's robots.txt and terms before use.") print("\nScaffold with:") print(f" WIKI_KB_HOST={host} WIKI_KB_SOURCE=html WIKI_KB_SITEMAP={endpoint}") robots = client.get(f"{host}/robots.txt") if robots.status_code == 200 and "gptbot" in robots.text.lower(): print("\n[NOTE] robots.txt names an AI crawler (e.g. GPTBot). It does not name") print(" this tool, but it is the operators' clearest statement about AI") print(" ingestion of their content. Your call — read it before scraping.") return 0 if __name__ == "__main__": sys.exit(main())