Files

127 lines
4.1 KiB
Python
Raw Permalink Normal View History

"""
scripts/fix_real_artist_images.py
Replaces placeholder star images and broken/stub avatars using:
1. MediaWiki Search & PageImages API (auto-resolves redirects and searches)
2. Deezer Public Artist API (official high-res portraits, picture_xl)
"""
from pathlib import Path
import sys
import pandas as pd
import requests
ROOT_DIR = Path(__file__).resolve().parent.parent
if str(ROOT_DIR) not in sys.path:
sys.path.insert(0, str(ROOT_DIR))
from core.database import get_connection
LASTFM_STAR_HASH = "2a96cbd8b46e442fc41c2b86b821562f"
HEADERS = {"User-Agent": "HIFFIArtistIntelligence/1.0 (contact@hiffi.com)"}
def get_wikimedia_image(name: str):
"""Searches Wikipedia and retrieves the top matched artist page's thumbnail."""
url = "https://en.wikipedia.org/w/api.php"
params = {
"action": "query",
"format": "json",
"generator": "search",
"gsrsearch": f"{name} rapper musician",
"gsrlimit": 1,
"prop": "pageimages",
"piprop": "thumbnail",
"pithumbsize": 600
}
try:
r = requests.get(url, params=params, headers=HEADERS, timeout=8)
if r.status_code == 200:
pages = r.json().get("query", {}).get("pages", {})
for _, page in pages.items():
thumb = page.get("thumbnail", {}).get("source")
if thumb:
return thumb
except Exception:
pass
return None
def get_deezer_image(name: str):
"""Queries Deezer API for verified editorial artist portraits."""
url = "https://api.deezer.com/search/artist"
params = {"q": name, "limit": 1}
try:
r = requests.get(url, params=params, timeout=8)
if r.status_code == 200:
data = r.json().get("data", [])
if data:
artist = data[0]
img = artist.get("picture_xl") or artist.get("picture_big") or artist.get("picture_medium")
if img and "artist-default" not in img:
return img
except Exception:
pass
return None
def main():
print("=" * 65)
print("HIFFI INTELLIGENCE: HIGH-RES PORTRAIT ENRICHMENT ENGINE")
print("=" * 65)
csv_path = ROOT_DIR / "data" / "hiffi_multiplatform_500.csv"
if not csv_path.exists():
csv_path = ROOT_DIR / "cleaned_artists_inventory.csv"
df_csv = pd.read_csv(csv_path)
name_col = "name" if "name" in df_csv.columns else "artist_name"
cohort = [str(n).strip() for n in df_csv[name_col].dropna()]
conn = get_connection()
cur = conn.cursor()
placeholders = ",".join(["?"] * len(cohort))
query = f"""
SELECT artist_id, artist_name, image_url
FROM artists
WHERE artist_name IN ({placeholders})
"""
cur.execute(query, cohort)
rows = cur.fetchall()
flagged = []
for artist_id, name, img in rows:
# Flag any artist using the Last.fm star placeholder or an empty image
if not img or LASTFM_STAR_HASH in img:
flagged.append((artist_id, name))
print(f"Targeting {len(flagged)} artists needing verified portraits...\n")
resolved = 0
for idx, (artist_id, name) in enumerate(flagged, start=1):
# 1. Try Wikimedia action search
img_url = get_wikimedia_image(name)
source = "Wikimedia"
# 2. Fall back to Deezer if Wikimedia has no thumbnail
if not img_url:
img_url = get_deezer_image(name)
source = "Deezer"
if img_url:
cur.execute("""
UPDATE artists
SET image_url = ?,
image_verified_flag = 1
WHERE artist_id = ?
""", (img_url, artist_id))
resolved += 1
print(f"[{idx:>3}/{len(flagged)}] [OK] ({source}) Saved portrait for {name}")
else:
print(f"[{idx:>3}/{len(flagged)}] [FAIL] Could not locate image for {name}")
conn.commit()
conn.close()
print("\n" + "=" * 65)
print(f"Successfully resolved high-resolution portraits for {resolved} / {len(flagged)} artists.")
print("=" * 65)
if __name__ == "__main__":
main()