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 found in .env") exit(1) conn = sqlite3.connect(DB_PATH) cur = conn.cursor() # Query all artists with search fallback URLs cur.execute(""" SELECT a.artist_id, a.artist_name, a.youtube_url FROM artists a WHERE a.youtube_url LIKE '%results?search_query%' AND a.image_verified_flag = 1 """) rows = cur.fetchall() print(f"Targeting {len(rows)} artists needing canonical YouTube Channel URLs and subscriber counts...\n") resolved = 0 for artist_id, name, old_url in rows: clean_name = name.strip() try: # 1. Search for verified channel search_resp = requests.get( "https://www.googleapis.com/youtube/v3/search", params={ "part": "snippet", "q": f"{clean_name} Official Artist Channel", "type": "channel", "maxResults": 1, "key": YOUTUBE_API_KEY }, timeout=10 ) channel_id = None if search_resp.status_code == 200: items = search_resp.json().get("items", []) if items: channel_id = items[0]["snippet"]["channelId"] if channel_id: # 2. Get accurate subscriber count chan_resp = requests.get( "https://www.googleapis.com/youtube/v3/channels", params={ "part": "statistics", "id": channel_id, "key": YOUTUBE_API_KEY }, timeout=10 ) subs = 0 if chan_resp.status_code == 200: stats = chan_resp.json().get("items", [{}])[0].get("statistics", {}) subs = int(stats.get("subscriberCount", 0)) canonical_url = f"https://www.youtube.com/channel/{channel_id}" # 3. Update artists and telemetry_metrics cur.execute("UPDATE artists SET youtube_url = ? WHERE artist_id = ?", (canonical_url, artist_id)) if subs > 0: cur.execute("UPDATE telemetry_metrics SET subscribers_count = ? WHERE artist_id = ?", (subs, artist_id)) conn.commit() resolved += 1 print(f"[{resolved}/{len(rows)}] {clean_name} -> {canonical_url} (Subs: {subs:,})") else: print(f"[NO CHANNEL FOUND] {clean_name}") except Exception as e: print(f"[ERR] {clean_name}: {e}") time.sleep(0.1) conn.close() print(f"\nYouTube canonicalization complete: {resolved}/{len(rows)} resolved.")