#!/usr/bin/env python3 """ Comprehensive Elgoose Data Importer Imports all shows, setlists, songs, venues, and tours from elgoose.net API """ import requests from datetime import datetime, date from sqlmodel import Session, select from database import engine from models import Show, Song, Performance, Venue, Tour, Vertical BASE_URL = "https://elgoose.net/api/v2" GOOSE_ARTIST_ID = 1 # Main Goose artist def get_api_data(endpoint): """Fetch data from elgoose API""" url = f"{BASE_URL}/{endpoint}" print(f"Fetching: {url}") response = requests.get(url, timeout=30) response.raise_for_status() return response.json() def import_shows_and_setlists(): """Import all shows and their setlists""" print("="*60) print("COMPREHENSIVE ELGOOSE IMPORT") print("="*60) with Session(engine) as session: # Ensure Goose vertical exists (id=1) goose_vertical = session.get(Vertical, 1) if not goose_vertical: print("Creating Goose vertical...") goose_vertical = Vertical( name="Goose", slug="goose", description="The band Goose." ) session.add(goose_vertical) session.commit() session.refresh(goose_vertical) print(f"Created vertical with id: {goose_vertical.id}") else: print(f"Using existing Goose vertical (id={goose_vertical.id})") # Get all shows from API shows_data = get_api_data("shows.json") if shows_data.get("error"): print(f"API Error: {shows_data.get('error_message')}") return api_shows = shows_data.get("data", []) print(f"Found {len(api_shows)} shows in elgoose API") # Filter to Goose shows only (artist_id=1) goose_shows = [s for s in api_shows if s.get("artist_id") == GOOSE_ARTIST_ID] print(f"Found {len(goose_shows)} Goose shows") # Get today's date for filtering today = date.today() past_shows = [] future_shows = [] for show in goose_shows: show_date_str = show.get("showdate", "") if show_date_str: show_date = datetime.strptime(show_date_str, "%Y-%m-%d").date() if show_date <= today: past_shows.append(show) else: future_shows.append(show) print(f"Past shows: {len(past_shows)}") print(f"Future/upcoming shows: {len(future_shows)}") with Session(engine) as session: # Build lookup maps existing_shows = {s.date: s for s in session.exec(select(Show)).all()} existing_songs = {s.title.lower(): s for s in session.exec(select(Song)).all()} existing_venues = {v.name.lower(): v for v in session.exec(select(Venue)).all()} existing_tours = {t.name.lower(): t for t in session.exec(select(Tour)).all()} print(f"Existing shows in DB: {len(existing_shows)}") print(f"Existing songs in DB: {len(existing_songs)}") print(f"Existing venues in DB: {len(existing_venues)}") print(f"Existing tours in DB: {len(existing_tours)}") shows_added = 0 shows_updated = 0 performances_added = 0 venues_added = 0 tours_added = 0 songs_added = 0 # Process past shows with setlists for api_show in past_shows: show_date_str = api_show.get("showdate") show_date = datetime.strptime(show_date_str, "%Y-%m-%d") api_show_id = api_show.get("show_id") venue_name = api_show.get("venuename", "").replace("&", "&") tour_name = api_show.get("tourname", "") location = api_show.get("location", "") city = api_show.get("city", "") state = api_show.get("state", "") # Find or create venue venue = None if venue_name: venue = existing_venues.get(venue_name.lower()) if not venue: venue = Venue( name=venue_name, city=city, state=state, country=api_show.get("country", "USA"), # Get country from API vertical_id=1 # Goose vertical ) session.add(venue) session.flush() existing_venues[venue_name.lower()] = venue venues_added += 1 # Find or create tour tour = None if tour_name and tour_name != "Not Part of a Tour": tour = existing_tours.get(tour_name.lower()) if not tour: tour = Tour( name=tour_name, vertical_id=1 ) session.add(tour) session.flush() existing_tours[tour_name.lower()] = tour tours_added += 1 # Check if show exists existing_show = existing_shows.get(show_date) if existing_show: # Update venue/tour if missing if venue and not existing_show.venue_id: existing_show.venue_id = venue.id shows_updated += 1 if tour and not existing_show.tour_id: existing_show.tour_id = tour.id shows_updated += 1 show = existing_show else: # Create new show show = Show( date=show_date, venue_id=venue.id if venue else None, tour_id=tour.id if tour else None, vertical_id=1 ) session.add(show) session.flush() existing_shows[show_date] = show shows_added += 1 # Fetch setlist for this show by date try: setlist_data = get_api_data(f"setlists/showdate/{show_date_str}.json") if not setlist_data.get("error"): setlist = setlist_data.get("data", []) # Check existing performances existing_perfs = session.exec( select(Performance).where(Performance.show_id == show.id) ).all() if not existing_perfs and setlist: for idx, perf_data in enumerate(setlist): song_title = perf_data.get("songname", "").strip() set_name = perf_data.get("set", "") position = perf_data.get("position", idx + 1) segue = perf_data.get("segue", "") == ">" notes = perf_data.get("footnote", "") if not song_title: continue # Find or create song song = existing_songs.get(song_title.lower()) if not song: song = Song( title=song_title, vertical_id=1 ) session.add(song) session.flush() existing_songs[song_title.lower()] = song songs_added += 1 # Create performance perf = Performance( show_id=show.id, song_id=song.id, position=position, set_name=set_name, segue=segue, notes=notes ) session.add(perf) performances_added += 1 except Exception as e: print(f" Error fetching setlist for show {api_show_id}: {e}") # Commit periodically if (shows_added + shows_updated) % 50 == 0: session.commit() print(f" Progress: {shows_added} added, {shows_updated} updated, {performances_added} performances") session.commit() print("\n" + "="*60) print("IMPORT COMPLETE") print("="*60) print(f"Shows added: {shows_added}") print(f"Shows updated: {shows_updated}") print(f"Venues added: {venues_added}") print(f"Tours added: {tours_added}") print(f"Songs added: {songs_added}") print(f"Performances added: {performances_added}") if __name__ == "__main__": import_shows_and_setlists()