199 lines
6.5 KiB
Python
199 lines
6.5 KiB
Python
"""
|
|
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()
|