""" scripts/resolve_missing_platform_urls.py Strictly resolves missing YouTube and Spotify links for the 500 Hip-Hop cohort only. """ from pathlib import Path import sys import os import urllib.parse import pandas as pd import requests from dotenv import load_dotenv ROOT_DIR = Path(__file__).resolve().parent.parent if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) load_dotenv(ROOT_DIR / ".env") from core.database import get_connection YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY") def search_youtube_channel_id(artist_name): if not YOUTUBE_API_KEY: return None url = "https://www.googleapis.com/youtube/v3/search" params = { "part": "snippet", "q": f"{artist_name} Official Artist Topic", "type": "channel", "maxResults": 1, "key": YOUTUBE_API_KEY } try: r = requests.get(url, params=params, timeout=10) if r.status_code == 200: items = r.json().get("items", []) if items: return items[0]["snippet"]["channelId"] except Exception: pass return None def main(): print("=" * 65) print("HIFFI INTELLIGENCE: TARGETED 500 COHORT URL RESOLUTION") 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_names = [str(n).strip() for n in df_csv[name_col].dropna()] conn = get_connection() cur = conn.cursor() placeholders = ",".join(["?"] * len(cohort_names)) cur.execute(f""" SELECT a.artist_id, a.artist_name, a.youtube_url, a.spotify_url FROM artists a WHERE a.artist_name IN ({placeholders}) AND (a.youtube_url IS NULL OR a.youtube_url = '' OR a.spotify_url IS NULL OR a.spotify_url = '') """, cohort_names) rows = cur.fetchall() print(f"Targeting strictly the {len(rows)} cohort artists with missing URLs...\n") for idx, (artist_id, name, yt_url, sp_url) in enumerate(rows, start=1): updates = {} # 1. Resolve YouTube URL if not yt_url or not yt_url.startswith("https://www.youtube.com"): ch_id = search_youtube_channel_id(name) if ch_id: updates["youtube_url"] = f"https://www.youtube.com/channel/{ch_id}" else: encoded = urllib.parse.quote_plus(f"{name} official music") updates["youtube_url"] = f"https://www.youtube.com/results?search_query={encoded}" # 2. Resolve Spotify URL if not sp_url or not sp_url.startswith("https://open.spotify.com"): encoded_name = urllib.parse.quote_plus(name) updates["spotify_url"] = f"https://open.spotify.com/search/{encoded_name}" if updates: set_clause = ", ".join([f"{k} = ?" for k in updates.keys()]) params = list(updates.values()) + [artist_id] cur.execute(f"UPDATE artists SET {set_clause} WHERE artist_id = ?", params) print(f"[{idx:>3}/{len(rows)}] Resolved URLs for {name}") conn.commit() # Final Verification Tally for the 500 cohort cur.execute(f""" SELECT COUNT(*) as total, SUM(CASE WHEN youtube_url LIKE 'https://www.youtube.com%' THEN 1 ELSE 0 END), SUM(CASE WHEN spotify_url LIKE 'https://open.spotify.com%' THEN 1 ELSE 0 END), SUM(CASE WHEN instagram_url LIKE 'https://www.instagram.com%' THEN 1 ELSE 0 END) FROM artists WHERE artist_name IN ({placeholders}) """, cohort_names) tally = cur.fetchone() print("\n" + "=" * 65) print("--- 500 COHORT URL COVERAGE ---") print(f"Total Cohort Artists : {tally[0]}") print(f"Valid YouTube URLs : {tally[1]} / 500") print(f"Valid Spotify URLs : {tally[2]} / 500") print(f"Valid Instagram URLs : {tally[3]} / 500") print("=" * 65) conn.close() if __name__ == "__main__": main()