""" Per-Show Setlist Importer Fetches setlist for each show individually """ import requests from sqlmodel import Session, select from database import engine from models import Show, Song, Performance BASE_URL = "https://elgoose.net/api/v2" def fetch_show_setlist(api_show_id): """Fetch setlist for a specific show""" url = f"{BASE_URL}/setlists/showid/{api_show_id}.json" try: response = requests.get(url, timeout=30) response.raise_for_status() data = response.json() if data.get('error') == 1: return None return data.get('data', []) except Exception as e: return None def main(): print("PER-SHOW SETLIST IMPORTER") print("=" * 40) with Session(engine) as session: # Get all shows shows = session.exec(select(Show)).all() print(f"Found {len(shows)} shows in database") # Build song map by title songs = session.exec(select(Song)).all() song_map = {s.title.lower(): s.id for s in songs} print(f"Mapped {len(song_map)} songs") # Get existing performances print("Loading existing performances...") existing_map = {} # (show_id, song_id, position) -> Performance Object perfs = session.exec(select(Performance)).all() for p in perfs: existing_map[(p.show_id, p.song_id, p.position)] = p print(f"Found {len(existing_map)} existing performances") # We need API show IDs. The ElGoose API shows endpoint returns show_id. # Let's fetch and correlate by date print("Fetching API shows to get API IDs...") api_shows = {} # date_str -> api_show_id page = 1 seen_ids = set() while True: url = f"{BASE_URL}/shows.json" try: resp = requests.get(url, params={"page": page}, timeout=30) data = resp.json().get('data', []) if not data: break # Loop detection first_id = data[0].get('show_id') if data else None if first_id in seen_ids: print(f" Loop detected at page {page}") break if first_id: seen_ids.add(first_id) for s in data: # CRITICAL: Only include Goose shows if s.get('artist') != 'Goose': continue date_str = s['showdate'] api_shows[date_str] = s['show_id'] page += 1 except Exception as e: print(f" Error on page {page}: {e}") break print(f"Got {len(api_shows)} API show IDs") # Now import setlists for each show total_added = 0 total_updated = 0 processed = 0 for show in shows: date_str = show.date.strftime('%Y-%m-%d') api_show_id = api_shows.get(date_str) if not api_show_id: continue # REMOVED: Skipping logic. We verify everything. # existing_for_show = ... # Fetch setlist setlist = fetch_show_setlist(api_show_id) if not setlist: continue added = 0 updated = 0 for item in setlist: song_title = item.get('songname', '').lower() song_id = song_map.get(song_title) if not song_id: continue position = item.get('position', 0) key = (show.id, song_id, position) # Resolve set name set_val = str(item.get('setnumber', '1')) if set_val.isdigit(): set_name = f"Set {set_val}" elif set_val.lower() == 'e': set_name = "Encore" elif set_val.lower() == 'e2': set_name = "Encore 2" elif set_val.lower() == 's': set_name = "Soundcheck" else: set_name = f"Set {set_val}" if key in existing_map: # Update Check perf = existing_map[key] if not perf.set_name or perf.set_name != set_name: perf.set_name = set_name session.add(perf) updated += 1 total_updated += 1 continue # Create New perf = Performance( show_id=show.id, song_id=song_id, position=position, set_name=set_name, segue=bool(item.get('segue', 0)), notes=item.get('footnote') ) session.add(perf) existing_map[key] = perf # Add to map to prevent dupes in same run added += 1 total_added += 1 if added > 0 or updated > 0: session.commit() processed += 1 print(f"Show {date_str}: +{added} new, ~{updated} updated") print(f"\nImport Complete! Added: {total_added}, Updated: {total_updated}") if __name__ == "__main__": main()