Files
Srilekha 78a46a8dbe
HIFFI Multi-Platform CI / test (3.12) (push) Successful in 50s
HIFFI Multi-Platform CI / test (3.11) (push) Successful in 50s
feat: finalize root api.py with X-Auth-Secret auth security and clean pure sales cohort
2026-11-04 16:49:39 +05:30

117 lines
4.0 KiB
Python

"""
scripts/force_replace_silhouettes.py
Direct local portrait generator for $uicideboy$, 100k Track, and Aminé.
Uses Wikimedia REST endpoints and guaranteed local binary writing.
Zero network dependencies on blocked CDNs.
"""
import sqlite3
import base64
import requests
import re
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
DB_PATH = BASE_DIR / "data" / "hiffi_catalog.db"
AVATAR_DIR = BASE_DIR / "data" / "artist_avatars"
AVATAR_DIR.mkdir(parents=True, exist_ok=True)
# Wikimedia REST API lead image endpoints (official, completely unblocked)
TARGET_CONFIG = {
"$uicideboy$": {
"wiki_title": "Suicideboys",
"fallback_deezer_id": "8482488"
},
"100k Track": {
"wiki_title": "100k_Track",
"fallback_deezer_id": "131441852"
},
"Aminé": {
"wiki_title": "Aminé_(rapper)",
"fallback_deezer_id": "10486256"
}
}
HEADERS = {
"User-Agent": "HIFFIArtistApp/1.0 (contact@hiffi.ai)",
"Accept": "application/json,image/*"
}
def clean_file_slug(name: str) -> str:
cleaned = re.sub(r'[^a-zA-Z0-9_-]', '_', name.strip().lower())
return re.sub(r'_+', '_', cleaned).strip('_')
def get_verified_image_bytes(artist_name: str, cfg: dict):
"""Fetches real image bytes using unblocked Wikipedia REST API or Deezer direct entity."""
# 1. Try Wikipedia REST summary API
title = cfg["wiki_title"]
wiki_url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{title}"
try:
r = requests.get(wiki_url, headers=HEADERS, timeout=10)
if r.status_code == 200:
data = r.json()
if "thumbnail" in data and "source" in data["thumbnail"]:
img_url = data["thumbnail"]["source"]
img_res = requests.get(img_url, headers=HEADERS, timeout=10)
if img_res.status_code == 200 and len(img_res.content) > 3000:
return img_res.content, img_url
except Exception:
pass
# 2. Try Deezer public API entity endpoint
deezer_id = cfg["fallback_deezer_id"]
dz_url = f"https://api.deezer.com/artist/{deezer_id}"
try:
r = requests.get(dz_url, headers=HEADERS, timeout=10)
if r.status_code == 200:
data = r.json()
img_url = data.get("picture_xl") or data.get("picture_big") or data.get("picture_medium")
if img_url and "artist//500x500" not in img_url:
img_res = requests.get(img_url, headers=HEADERS, timeout=10)
if img_res.status_code == 200 and len(img_res.content) > 3000:
return img_res.content, img_url
except Exception:
pass
return None, None
def main():
if not DB_PATH.exists():
print(f"[-] Database not found at {DB_PATH}")
return
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
print("[*] Fetching verified unblocked face portraits...\n")
for artist_name, cfg in TARGET_CONFIG.items():
cursor.execute("SELECT artist_id FROM artists WHERE artist_name = ? COLLATE NOCASE", (artist_name,))
row = cursor.fetchone()
artist_id = str(row[0]) if row else "0"
slug = clean_file_slug(artist_name)
target_file = AVATAR_DIR / f"{slug}_{artist_id}.jpg"
print(f" [>] Processing {artist_name} (ID: {artist_id})...", flush=True)
img_bytes, img_url = get_verified_image_bytes(artist_name, cfg)
if img_bytes:
with open(target_file, "wb") as f:
f.write(img_bytes)
size_kb = len(img_bytes) / 1024
print(f" [+] Successfully written: {target_file.name} ({size_kb:.1f} KB)", flush=True)
cursor.execute(
"UPDATE artists SET image_url = ?, image_verified_flag = 1 WHERE artist_id = ?",
(img_url, artist_id)
)
conn.commit()
else:
print(f" [-] Failed to retrieve image for {artist_name}", flush=True)
conn.close()
print("\n[+] Direct write complete.")
if __name__ == "__main__":
main()