""" Import ONLY songs and setlists into existing demo database Uses correct API field mappings based on actual El Goose API response """ import requests from datetime import datetime from sqlmodel import Session, select from database import engine from models import Vertical, Song, Performance, Show BASE_URL = "https://elgoose.net/api/v2" ARTIST_ID = 1 # Goose def fetch_json(endpoint, params=None): """Fetch JSON from El Goose API with error handling""" url = f"{BASE_URL}/{endpoint}.json" try: response = requests.get(url, params=params) response.raise_for_status() data = response.json() if data.get('error') == 1 or data.get('error') == True: print(f"āŒ API Error: {data.get('error_message')}") return None return data.get('data', []) except Exception as e: print(f"āŒ Failed to fetch {endpoint}: {e}") return None def import_songs(session, vertical_id): """Import all songs using correct API field names""" print("\nšŸŽµ Importing songs...") songs_data = fetch_json("songs") if not songs_data: print("āŒ No song data received") return {} song_map = {} for s in songs_data: # Check if song exists existing = session.exec( select(Song).where( Song.title == s['name'], Song.vertical_id == vertical_id ) ).first() if existing: song_map[s['id']] = existing.id else: song = Song( title=s['name'], original_artist=s.get('original_artist'), vertical_id=vertical_id ) session.add(song) session.commit() session.refresh(song) song_map[s['id']] = song.id if len(song_map) % 100 == 0: print(f" Progress: {len(song_map)} songs...") print(f"āœ“ Imported {len(song_map)} songs") return song_map def import_setlists(session, vertical_id, song_map): """Import setlists for Goose shows only""" print("\nšŸ“‹ Importing setlists...") # Get all our shows from the database shows = session.exec( select(Show).where(Show.vertical_id == vertical_id) ).all() print(f" Found {len(shows)} shows in database") # Fetch ALL setlists and filter for Goose print(" Fetching setlists from API...") setlists_data = fetch_json("setlists") if not setlists_data: print("āŒ No setlist data found") return print(f" Received {len(setlists_data)} total performances") # Create a map of El Goose show_id to our show id show_map = {} for show in shows: # We need to find the matching El Goose show by date # Since we imported shows with their original show_id stored... wait, we didn't # We need to match by date instead pass # Actually, let's fetch shows again to get the mapping shows_data = fetch_json("shows") if shows_data: goose_shows = [s for s in shows_data if s.get('artist_id') == ARTIST_ID] print(f" Found {len(goose_shows)} Goose shows in API") # Build mapping: El Goose show_id -> our database show id for eg_show in goose_shows: eg_date = datetime.strptime(eg_show['showdate'], '%Y-%m-%d').date() # Find matching show in our DB by date db_show = session.exec( select(Show).where( Show.vertical_id == vertical_id, Show.date >= datetime.combine(eg_date, datetime.min.time()), Show.date < datetime.combine(eg_date, datetime.max.time()) ) ).first() if db_show: show_map[eg_show['show_id']] = db_show.id print(f" Mapped {len(show_map)} shows") # Now import performances performance_count = 0 skipped = 0 for perf_data in setlists_data: # Only import if this is a Goose show our_show_id = show_map.get(perf_data.get('show_id')) if not our_show_id: skipped += 1 continue our_song_id = song_map.get(perf_data.get('song_id')) if not our_song_id: # Song not found - might be from another artist skipped += 1 continue # Check if performance already exists existing = session.exec( select(Performance).where( Performance.show_id == our_show_id, Performance.song_id == our_song_id, Performance.position == perf_data.get('position', 0) ) ).first() if existing: continue perf = Performance( show_id=our_show_id, song_id=our_song_id, position=perf_data.get('position', 0), set_name=perf_data.get('set'), segue=bool(perf_data.get('segue', 0)), notes=perf_data.get('notes') ) session.add(perf) performance_count += 1 if performance_count % 100 == 0: session.commit() print(f" Progress: {performance_count} performances...") session.commit() print(f"āœ“ Imported {performance_count} performances (skipped {skipped} non-Goose)") def main(): print("="*60) print("EL GOOSE SONGS & SETLISTS IMPORTER") print("="*60) with Session(engine) as session: # Get existing Goose vertical vertical = session.exec( select(Vertical).where(Vertical.slug == "goose") ).first() if not vertical: print("āŒ Goose vertical not found! Run main import first.") return print(f"āœ“ Found Goose vertical (ID: {vertical.id})") # Import songs and setlists song_map = import_songs(session, vertical.id) import_setlists(session, vertical.id, song_map) print("\n" + "="*60) print("āœ“ IMPORT COMPLETE!") print("="*60) print(f"\nImported:") print(f" • {len(song_map)} songs") print(f"\nDemo environment is now fully populated!") print(f"\nStart demo servers:") print(f" Backend: DATABASE_URL='sqlite:///./elmeg-demo.db' uvicorn main:app --reload --port 8001") print(f" Frontend: NEXT_PUBLIC_API_URL=http://localhost:8001 npm run dev -- -p 3001") if __name__ == "__main__": main()