"""Backtest book URL metadata fetch across all supported platforms.""" from __future__ import annotations import asyncio import json import sys from dataclasses import asdict # Core fields expected for a "complete" import preview CORE_FIELDS = ("title", "author", "description", "genre", "cover_url") EXTRA_FIELDS = ("about_author", "isbn", "publisher", "publish_year", "page_count", "language") TEST_URLS: dict[str, str] = { "amazon": "https://www.amazon.com/dp/0593128257", "barnes_noble": "https://www.barnesandnoble.com/w/james-percival-everett/1143678734?ean=9780385550369", "goodreads": "https://www.goodreads.com/book/show/4671.The_Great_Gatsby", "google_books": "https://books.google.com/books/about/Project_Hail_Mary.html?id=GrYsEAAAQBAJ", "apple_books": "https://books.apple.com/us/book/fang-fiction/id6475274221", "kobo": "https://www.kobo.com/ca/en/ebook/project-hail-mary-9780593135204", "thriftbooks": "https://www.thriftbooks.com/w/1q84_haruki-murakami/252010/", "abebooks": "https://www.abebooks.com/products/isbn/9780593135204", "worldcat": "https://search.worldcat.org/search?q=bn:9780593135204", "open_library": "https://openlibrary.org/works/OL268236W/The_Cat_Who_Went_to_Heaven", "bookshop": "https://bookshop.org/p/books/1q84-haruki-murakami/525d944c7585381e?ean=9780307476463", "lulu": "https://www.lulu.com/shop/brett-arquette/operation-hail-storm/paperback/product-22895695.html", "walmart": "https://www.walmart.com/ip/Winternight-Trilogy-The-Bear-and-the-Nightingale-Book-1-Hardcover-9781101885932/53596259", "waterstones": "https://www.waterstones.com/book/9780575077331", "booksamillion": "https://www.booksamillion.com/p/Three-Body-Problem/Cixin-Liu/9780765382030", "powells": "https://www.powells.com/book/project-hail-mary-9780593135204", "indigo": "https://www.indigo.ca/en-ca/project-hail-mary-a-novel/9780593135204.html", } def _field_ok(name: str, value) -> bool: if name == "description": return bool(value) and len(str(value)) >= 40 if name == "about_author": return bool(value) and len(str(value)) >= 50 if name == "page_count": return int(value or 0) > 0 return bool(value) async def main() -> int: from app.services.book_url_scraper import fetch_book_metadata, detect_platform results = [] for platform, url in TEST_URLS.items(): detected = detect_platform(url) meta = await fetch_book_metadata(url, force_refresh=True) row = { "platform": platform, "detected": detected, "url": url, "confidence": meta.confidence, "error": meta.error, "warnings": meta.warnings, "fields": {}, "missing_core": [], "missing_extra": [], } d = asdict(meta) for f in CORE_FIELDS + EXTRA_FIELDS: val = d.get(f, "") if f == "page_count": display = val if val else "" else: display = (str(val)[:60] + "...") if len(str(val)) > 60 else val row["fields"][f] = {"ok": _field_ok(f, val), "value": display} row["missing_core"] = [f for f in CORE_FIELDS if not row["fields"][f]["ok"]] row["missing_extra"] = [f for f in EXTRA_FIELDS if not row["fields"][f]["ok"]] row["perfect"] = not row["missing_core"] and not row["error"] results.append(row) # Print summary table print("\n" + "=" * 100) print("BOOK URL METADATA BACKTEST") print("=" * 100) perfect = sum(1 for r in results if r["perfect"]) print(f"\nPerfect (all core fields): {perfect}/{len(results)}\n") for r in results: status = "PASS" if r["perfect"] else "FAIL" print(f"[{status}] {r['platform']:15} conf={r['confidence']:.2f} detected={r['detected']}") print(f" title: {ascii(r['fields']['title']['value'])}") print(f" author: {ascii(r['fields']['author']['value'])}") if r["missing_core"]: print(f" MISSING CORE: {', '.join(r['missing_core'])}") if r["missing_extra"]: print(f" missing extra: {', '.join(r['missing_extra'])}") if r["error"]: print(f" ERROR: {r['error']}") print() out_path = "scripts/backtest_book_urls_results.json" with open(out_path, "w", encoding="utf-8") as f: json.dump(results, f, indent=2) print(f"Full results written to {out_path}") return 0 if perfect == len(results) else 1 if __name__ == "__main__": sys.path.insert(0, ".") raise SystemExit(asyncio.run(main()))