fediversion/backend/fast_import_setlists.py
fullsizemalt b4cddf41ea feat: Initialize Fediversion multi-band platform
- Fork elmeg-demo codebase for multi-band support
- Add data importer infrastructure with base class
- Create band-specific importers:
  - phish.py: Phish.net API v5
  - grateful_dead.py: Grateful Stats API
  - setlistfm.py: Dead & Company, Billy Strings (Setlist.fm)
- Add spec-kit configuration for Gemini
- Update README with supported bands and architecture
2025-12-28 12:39:28 -08:00

128 lines
4.4 KiB
Python

"""
Fast Setlist Importer - Skips validation checks for speed
Run after main import if it times out
"""
import requests
from datetime import datetime
from sqlmodel import Session, select
from database import engine
from models import Show, Song, Performance
BASE_URL = "https://elgoose.net/api/v2"
def fetch_json(endpoint, params=None):
url = f"{BASE_URL}/{endpoint}.json"
try:
response = requests.get(url, params=params, timeout=30)
response.raise_for_status()
data = response.json()
if data.get('error') == 1:
return None
return data.get('data', [])
except Exception as e:
print(f"Error: {e}")
return None
def main():
print("FAST SETLIST IMPORTER")
print("=" * 40)
with Session(engine) as session:
# Build lookup maps
print("Building show map...")
shows = session.exec(select(Show)).all()
# Map API show_id to our show_id
# We need the API show_id. The 'notes' field might have showtitle but not API id.
# Problem: We don't store API show_id in our DB!
# We need to re-fetch shows and match by date+venue_id
show_map = {} # api_show_id -> our_show_id
song_map = {} # api_song_id -> our_song_id
# Fetch shows from API to build map
print("Fetching API shows to build map...")
page = 1
while True:
data = fetch_json("shows", {"artist": 1, "page": page})
if not data:
break
for s in data:
api_show_id = s['show_id']
show_date = datetime.strptime(s['showdate'], '%Y-%m-%d')
# Find matching show in our DB
our_show = session.exec(
select(Show).where(Show.date == show_date)
).first()
if our_show:
show_map[api_show_id] = our_show.id
page += 1
if page > 50:
break
print(f"Mapped {len(show_map)} shows")
# Build song map
print("Building song map...")
songs_data = fetch_json("songs")
if songs_data:
for s in songs_data:
api_song_id = s['id']
our_song = session.exec(
select(Song).where(Song.title == s['name'])
).first()
if our_song:
song_map[api_song_id] = our_song.id
print(f"Mapped {len(song_map)} songs")
# Get existing performances to skip
print("Loading existing performances...")
existing = set()
perfs = session.exec(select(Performance.show_id, Performance.song_id, Performance.position)).all()
for p in perfs:
existing.add((p[0], p[1], p[2]))
print(f"Found {len(existing)} existing performances")
# Import setlists page by page
print("\\nImporting setlists...")
page = 1
total_added = 0
while True:
data = fetch_json("setlists", {"page": page})
if not data:
print(f"No data on page {page}, done.")
break
added_this_page = 0
for perf_data in data:
our_show_id = show_map.get(perf_data.get('show_id'))
our_song_id = song_map.get(perf_data.get('song_id'))
position = perf_data.get('position', 0)
if not our_show_id or not our_song_id:
continue
key = (our_show_id, our_song_id, position)
if key in existing:
continue
perf = Performance(
show_id=our_show_id,
song_id=our_song_id,
position=position,
set_name=perf_data.get('set'),
segue=bool(perf_data.get('segue', 0)),
notes=perf_data.get('notes')
)
session.add(perf)
existing.add(key)
added_this_page += 1
total_added += 1
session.commit()
print(f"Page {page}: +{added_this_page} ({total_added} total)")
page += 1
print(f"\\n✓ Added {total_added} performances")
if __name__ == "__main__":
main()