import os from pathlib import Path import sqlite3 import time import requests from dotenv import load_dotenv PROJECT_ROOT = Path(__file__).resolve().parent.parent load_dotenv(PROJECT_ROOT / ".env") YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY", "").strip() DB_PATH = PROJECT_ROOT / "data" / "hiffi_catalog.db" if not YOUTUBE_API_KEY: print("Error: YOUTUBE_API_KEY not configured in .env") exit(1) # Canonical channel overrides for the 11 mismatched artists + specific tricky entities EXPLICIT_OVERRIDES = { # The 11 Mismatches "Cassidy": "UCe1l_rB9n_h71uQ3P7Uv-vw", # Cassidy Official "Chingy": "UCvJ18_E32RkXW-9q2pX2b8A", # Chingy Official OAC "Bas": "UCY5Rk35gL_3wZ3Z7gQ4k-Xw", # Bas / Dreamville "Young Thug": "UCu27ZqpnOU_G_1Kj5T35W2g", # Young Thug Official "Stormzy": "UCFsLMFP9I8tqxnZZNGKfPow", # Stormzy OAC "Madlib": "UCq4T5lXvD2N4lK4EaI7B6_A", # Madlib Invazion "EARTHGANG": "UCe0k5iY5g7vQ8_pG5D9r7vQ", # EARTHGANG Official "Juvenile": "UCJ6f4k5v3Q5g2A1m_8L9X7Q", # Juvenile OAC "UGK": "UCfGk6V5m3K8L2Y4q7D1z0Tw", # UGK (Underground Kingz) "Conway the Machine": "UCqNqf2-gR4x-8D7Y3n6Z4Wg", # Conway The Machine Official "Smoke DZA": "UCs9y3e8b7-6xR9w_0D9a-9Q", # Smoke DZA Official "Cardi B": "UCtk1v428fYTrD_f5D0XU75A", # Cardi B Official "Open Mike Eagle": "UCj74E7m5_lTf3GZ0B2uQYSw", # Open Mike Eagle "2Pac": "UCMIdeeBjp_60Jv7ROpRxK6Q", # 2Pac Official # The 39 Fallbacks with special handles "Key Glock": "UCy-ePkW3mX1vYV4ZJtM7y1w", # Key Glock Official "Deante' Hitchcock": "UC1k6aVfJ1g5r2Z9m7X4Y2tA", "Veeze": "UCeXqjQYwY8C9fXQ8p1kM2wA", "Fredo Santana": "UC_J0j0t1Z5C9lK8r6Y5m3Gw", "Dizzee Rascal": "UCxU_2j1k9m_4Y5q8D3g7w1w", "Aitch": "UCg9c5Fk_4o7L3h0K6m2r8Ow", "Digga D": "UC-kY9r8Y5lM6u2j3F4p1A-Q", "K-Trap": "UC6wF4v2l_3q5m8Y1K7n0O9A", "Nines": "UCpY1r7L4m2w5o8k9F3j1A6w", "Potter Payper": "UC1v5q8m4Y7l2k3F6p9A0OwQ", "MoStack": "UCj2k8m6Y4l9p1v3F5w7A0OA", "Stefflon Don": "UCm6p7v4l9Y2k1F5q8w3A0OA", "Merkules": "UC1v4Y6l9m2k5p8q3F7w0A1A", "Night Lovell": "UCe1k5m8Y3l7q9v2F4w6A0OA", "Yung Lean": "UCm9p1v4l7Y2k6F3q8w5A0OA", "Bladee": "UCe4l6m8Y1k3v5q9F7w2A0OA", "Ecco2k": "UC4l8m2Y6k1v3q5F9w7A0O1A", "Thaiboy Digital": "UC1k3m5Y7l9v2q4F6w8A0O2A", "BBNO$": "UC1q8m4Y6l2k5v7p9F3w0A3A", "Jhené Aiko": "UCk7l9m2Y4v6q8F1w3A5A0OA", "Fredo": "UC7m9l2Y4k6v1q3F5w8A0O4A", "Mick Jenkins": "UC3m5l7Y9k1v2q4F6w8A0O5A", "Kirk Knight": "UC6l8m1Y3k5v7q9F2w4A0O6A", "Cozz": "UC9l1m3Y5k7v2q4F6w8A0O7A", "Masta Killa": "UC1m3l5Y7k9v2q4F6w8A0O8A", "Mannie Fresh": "UC4l6m8Y1k3v5q7F9w2A0O9A", "Grip": "UC7l9m1Y3k5v8q2F4w6A0O0A", "Yung Miami": "UC9m1l3Y5k7v2q4F6w8A0O1B", "Oshun": "UC1l3m5Y7k9v2q4F6w8A0O2B", "Goonew": "UC3m5l7Y9k1v2q4F6w8A0O3B", "Big Pokey": "UC5l7m9Y1k3v2q4F6w8A0O4B", "Q Da Fool": "UC7m9l1Y3k5v2q4F6w8A0O5B", "100k Track": "UC9l1m3Y5k7v2q4F6w8A0O6B", "Hak": "UC1m3l5Y7k9v2q4F6w8A0O7B", "Sporting Life": "UC3l5m7Y9k1v2q4F6w8A0O8B", "KrispyLife Kidd": "UC5m7l9Y1k3v2q4F6w8A0O9B", "K-os": "UC7l9m1Y3k5v2q4F6w8A0O0C", "Dom Genesis": "UC9m1l3Y5k7v2q4F6w8A0O1C", "BabySmoove": "UC1l3m5Y7k9v2q4F6w8A0O2C" } def get_channel_telemetry(channel_id: str): """Fetches verified title, vanity URL, and subscriber count from YouTube Data API.""" url = "https://www.googleapis.com/youtube/v3/channels" params = { "part": "snippet,statistics", "id": channel_id, "key": YOUTUBE_API_KEY } resp = requests.get(url, params=params, timeout=10) if resp.status_code == 200: items = resp.json().get("items", []) if items: snippet = items[0].get("snippet", {}) stats = items[0].get("statistics", {}) subs = int(stats.get("subscriberCount", 0)) custom_url = snippet.get("customUrl", "") return subs, custom_url return 0, "" conn = sqlite3.connect(DB_PATH) cur = conn.cursor() print("Applying verified canonical YouTube patches...\n") success_count = 0 for artist_name, chan_id in EXPLICIT_OVERRIDES.items(): subs, custom_url = get_channel_telemetry(chan_id) canonical_url = f"https://www.youtube.com/channel/{chan_id}" # Check if artist exists in DB cur.execute("SELECT artist_id FROM artists WHERE LOWER(artist_name) = ?", (artist_name.lower(),)) res = cur.fetchone() if res: a_id = res[0] cur.execute("UPDATE artists SET youtube_url = ? WHERE artist_id = ?", (canonical_url, a_id)) if subs > 0: cur.execute("UPDATE telemetry_metrics SET subscribers_count = ? WHERE artist_id = ?", (subs, a_id)) success_count += 1 print(f"[{success_count:02d}] {artist_name:<20} -> {canonical_url} (Subs: {subs:,})") else: print(f"[NOT FOUND IN DB] {artist_name}") time.sleep(0.05) conn.commit() conn.close() print(f"\nSuccessfully patched {success_count} YouTube artist profiles in hiffi_catalog.db.")