Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -92,6 +92,15 @@ DEFAULT_IA_QUERY = os.environ.get(
|
|
| 92 |
ALLOW_DEV_BOOTSTRAP = os.environ.get("ALLOW_DEV_BOOTSTRAP", "0") == "1"
|
| 93 |
ALLOW_DEV_DIAGNOSTICS = os.environ.get("ALLOW_DEV_DIAGNOSTICS", "0") == "1"
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
# -----------------------------------------------------------------------------
|
| 96 |
# 2) UTILS
|
| 97 |
# -----------------------------------------------------------------------------
|
|
@@ -420,16 +429,26 @@ def ensure_minimum_ia_pool(min_items: int = MIN_IA_POOL, rows: int = 100, max_pa
|
|
| 420 |
cached = 0
|
| 421 |
log.info(f"ensure_minimum_ia_pool: have={have}, target={min_items}")
|
| 422 |
|
| 423 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 424 |
page = 1
|
| 425 |
while have + added < min_items and page <= max_pages:
|
| 426 |
try:
|
| 427 |
-
docs = ia_advanced_search(
|
| 428 |
except Exception:
|
| 429 |
-
log.warning(f"IA search failed on page {page},
|
| 430 |
break
|
|
|
|
| 431 |
if not docs:
|
| 432 |
-
log.warning("IA search returned 0 docs; stopping")
|
| 433 |
break
|
| 434 |
for d in docs:
|
| 435 |
ident = d.get("identifier")
|
|
@@ -442,13 +461,13 @@ def ensure_minimum_ia_pool(min_items: int = MIN_IA_POOL, rows: int = 100, max_pa
|
|
| 442 |
if rec:
|
| 443 |
added += 1
|
| 444 |
except Exception:
|
| 445 |
-
log.exception(f"
|
| 446 |
continue
|
| 447 |
if have + added >= min_items:
|
| 448 |
break
|
| 449 |
page += 1
|
| 450 |
|
| 451 |
-
# Cache up to min_items
|
| 452 |
pool = ia_pool_ref().get() or {}
|
| 453 |
have_now = len(pool)
|
| 454 |
need_cache = max(0, min_items - have_now)
|
|
@@ -462,6 +481,7 @@ def ensure_minimum_ia_pool(min_items: int = MIN_IA_POOL, rows: int = 100, max_pa
|
|
| 462 |
log.info(f"ensure_minimum_ia_pool: stats={stats}")
|
| 463 |
return stats
|
| 464 |
|
|
|
|
| 465 |
# -----------------------------------------------------------------------------
|
| 466 |
# 4) CASE GENERATION (uses IA for authentic image, Gemini for forgeries/meta)
|
| 467 |
# -----------------------------------------------------------------------------
|
|
@@ -816,16 +836,28 @@ def admin_generate_today():
|
|
| 816 |
def admin_bootstrap_now():
|
| 817 |
if not ALLOW_DEV_BOOTSTRAP:
|
| 818 |
return jsonify({"error": "Disabled. Set ALLOW_DEV_BOOTSTRAP=1 to enable."}), 403
|
|
|
|
| 819 |
cfg = request.get_json() or {}
|
| 820 |
min_items = int(cfg.get("min_items", MIN_IA_POOL))
|
| 821 |
rows = int(cfg.get("rows", 100))
|
| 822 |
max_pages = int(cfg.get("max_pages", 5))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 823 |
try:
|
| 824 |
stats = ensure_minimum_ia_pool(min_items=min_items, rows=rows, max_pages=max_pages)
|
| 825 |
-
return jsonify({"ok": True, "stats": stats})
|
| 826 |
except Exception as e:
|
| 827 |
log.exception("bootstrap-now failed")
|
| 828 |
return jsonify({"ok": False, "error": str(e)}), 500
|
|
|
|
|
|
|
|
|
|
| 829 |
|
| 830 |
# --- DEV-ONLY: diagnostics (network + firebase sanity) ---
|
| 831 |
@app.route("/admin/diagnostics", methods=["GET"])
|
|
|
|
| 92 |
ALLOW_DEV_BOOTSTRAP = os.environ.get("ALLOW_DEV_BOOTSTRAP", "0") == "1"
|
| 93 |
ALLOW_DEV_DIAGNOSTICS = os.environ.get("ALLOW_DEV_DIAGNOSTICS", "0") == "1"
|
| 94 |
|
| 95 |
+
FALLBACK_IA_QUERIES = [
|
| 96 |
+
# 1) broad (fastest win)
|
| 97 |
+
'(mediatype:image AND (format:JPEG OR format:PNG))',
|
| 98 |
+
# 2) portraits bias (nice for the game)
|
| 99 |
+
'(mediatype:image AND (format:JPEG OR format:PNG) AND (subject:portrait OR title:portrait))',
|
| 100 |
+
# 3) slightly narrower but still broad
|
| 101 |
+
'(mediatype:image AND format:JPEG)',
|
| 102 |
+
]
|
| 103 |
+
|
| 104 |
# -----------------------------------------------------------------------------
|
| 105 |
# 2) UTILS
|
| 106 |
# -----------------------------------------------------------------------------
|
|
|
|
| 429 |
cached = 0
|
| 430 |
log.info(f"ensure_minimum_ia_pool: have={have}, target={min_items}")
|
| 431 |
|
| 432 |
+
# Decide which queries to try: env IA_QUERY first, then fallbacks
|
| 433 |
+
candidate_queries = []
|
| 434 |
+
if DEFAULT_IA_QUERY:
|
| 435 |
+
candidate_queries.append(DEFAULT_IA_QUERY)
|
| 436 |
+
candidate_queries.extend([q for q in FALLBACK_IA_QUERIES if q not in candidate_queries])
|
| 437 |
+
|
| 438 |
+
# Ingest until we reach the target or run out of queries/pages
|
| 439 |
+
for q in candidate_queries:
|
| 440 |
+
if have + added >= min_items:
|
| 441 |
+
break
|
| 442 |
+
log.info(f"IA ingest: trying query: {q}")
|
| 443 |
page = 1
|
| 444 |
while have + added < min_items and page <= max_pages:
|
| 445 |
try:
|
| 446 |
+
docs = ia_advanced_search(q, rows=rows, page=page)
|
| 447 |
except Exception:
|
| 448 |
+
log.warning(f"IA search failed on page {page} for query {q!r}, moving on")
|
| 449 |
break
|
| 450 |
+
log.info(f"IA search page={page} -> {len(docs)} docs for query {q!r}")
|
| 451 |
if not docs:
|
|
|
|
| 452 |
break
|
| 453 |
for d in docs:
|
| 454 |
ident = d.get("identifier")
|
|
|
|
| 461 |
if rec:
|
| 462 |
added += 1
|
| 463 |
except Exception:
|
| 464 |
+
log.exception(f"Ingest failed for {ident}")
|
| 465 |
continue
|
| 466 |
if have + added >= min_items:
|
| 467 |
break
|
| 468 |
page += 1
|
| 469 |
|
| 470 |
+
# Cache up to min_items (unchanged)
|
| 471 |
pool = ia_pool_ref().get() or {}
|
| 472 |
have_now = len(pool)
|
| 473 |
need_cache = max(0, min_items - have_now)
|
|
|
|
| 481 |
log.info(f"ensure_minimum_ia_pool: stats={stats}")
|
| 482 |
return stats
|
| 483 |
|
| 484 |
+
|
| 485 |
# -----------------------------------------------------------------------------
|
| 486 |
# 4) CASE GENERATION (uses IA for authentic image, Gemini for forgeries/meta)
|
| 487 |
# -----------------------------------------------------------------------------
|
|
|
|
| 836 |
def admin_bootstrap_now():
|
| 837 |
if not ALLOW_DEV_BOOTSTRAP:
|
| 838 |
return jsonify({"error": "Disabled. Set ALLOW_DEV_BOOTSTRAP=1 to enable."}), 403
|
| 839 |
+
|
| 840 |
cfg = request.get_json() or {}
|
| 841 |
min_items = int(cfg.get("min_items", MIN_IA_POOL))
|
| 842 |
rows = int(cfg.get("rows", 100))
|
| 843 |
max_pages = int(cfg.get("max_pages", 5))
|
| 844 |
+
custom_q = cfg.get("query")
|
| 845 |
+
|
| 846 |
+
global DEFAULT_IA_QUERY
|
| 847 |
+
original_q = DEFAULT_IA_QUERY
|
| 848 |
+
if custom_q:
|
| 849 |
+
log.warning(f"DEV bootstrap using custom query: {custom_q!r}")
|
| 850 |
+
DEFAULT_IA_QUERY = custom_q # temporary override
|
| 851 |
+
|
| 852 |
try:
|
| 853 |
stats = ensure_minimum_ia_pool(min_items=min_items, rows=rows, max_pages=max_pages)
|
| 854 |
+
return jsonify({"ok": True, "stats": stats, "effective_query": DEFAULT_IA_QUERY})
|
| 855 |
except Exception as e:
|
| 856 |
log.exception("bootstrap-now failed")
|
| 857 |
return jsonify({"ok": False, "error": str(e)}), 500
|
| 858 |
+
finally:
|
| 859 |
+
DEFAULT_IA_QUERY = original_q # restore
|
| 860 |
+
|
| 861 |
|
| 862 |
# --- DEV-ONLY: diagnostics (network + firebase sanity) ---
|
| 863 |
@app.route("/admin/diagnostics", methods=["GET"])
|