from sqlmodel import Session, select from database import engine from models import Venue, Song, Show, Tour, Performance from slugify import generate_slug, generate_show_slug import requests import time BASE_URL = "https://elgoose.net/api/v2" def fetch_all_json(endpoint, params=None): all_data = [] page = 1 params = params.copy() if params else {} print(f"Fetching {endpoint}...") while True: params['page'] = page url = f"{BASE_URL}/{endpoint}.json" try: resp = requests.get(url, params=params) if resp.status_code != 200: break data = resp.json() items = data.get('data', []) if not items: break all_data.extend(items) print(f" Page {page} done ({len(items)} items)") page += 1 time.sleep(0.5) except Exception as e: print(f"Error fetching {endpoint}: {e}") break return all_data def fix_data(): with Session(engine) as session: # 1. Fix Venues Slugs print("Fixing Venue Slugs...") venues = session.exec(select(Venue)).all() for v in venues: if not v.slug: v.slug = generate_slug(v.name) session.add(v) session.commit() # 2. Fix Songs Slugs print("Fixing Song Slugs...") songs = session.exec(select(Song)).all() for s in songs: if not s.slug: s.slug = generate_slug(s.title) session.add(s) session.commit() # 3. Fix Tours Slugs print("Fixing Tour Slugs...") tours = session.exec(select(Tour)).all() for t in tours: if not t.slug: t.slug = generate_slug(t.name) session.add(t) session.commit() # 4. Fix Shows Slugs print("Fixing Show Slugs...") shows = session.exec(select(Show)).all() venue_map = {v.id: v for v in venues} # Cache venues for naming for show in shows: if not show.slug: date_str = show.date.strftime("%Y-%m-%d") if show.date else "unknown" venue_name = "unknown" if show.venue_id and show.venue_id in venue_map: venue_name = venue_map[show.venue_id].name show.slug = generate_show_slug(date_str, venue_name) session.add(show) session.commit() # 5. Fix Set Names (Fetch API) print("Fixing Set Names (fetching setlists)...") # We need to map El Goose show_id/song_id to our IDs to find the record. # But we don't store El Goose IDs in our models? # Checked models.py: we don't store ex_id. # We match by show date/venue and song title. # This is hard to do reliably without external IDs. # Alternatively, we can infer set name from 'position'? # No, position 1 could be Set 1 or Encore if short show? No. # Wait, import_elgoose mappings are local var. # If we re-run import logic but UPDATE instead of SKIP, we can fix it. # But matching is tricky. # Let's try to match by Show Date and Song Title. # Build map: (show_id, song_id, position) -> Performance perfs = session.exec(select(Performance)).all() perf_map = {} # (show_id, song_id, position) -> perf object for p in perfs: perf_map[(p.show_id, p.song_id, p.position)] = p # We need show map: el_goose_show_id -> our_show_id # We need song map: el_goose_song_id -> our_song_id # We have to re-fetch shows and songs to rebuild this map. print(" Re-building ID maps...") # Map Shows el_shows = fetch_all_json("shows", {"artist": 1}) if not el_shows: el_shows = fetch_all_json("shows") # fallback el_show_map = {} # el_id -> our_id for s in el_shows: # Find our show dt = s['showdate'] # YYYY-MM-DD # We need to match precise Show. # Simplified: match by date. # Convert string to datetime from datetime import datetime s_date = datetime.strptime(dt, "%Y-%m-%d") # Find show in our DB # We can optimise this but for now linear search or query is fine for one-off script found = session.exec(select(Show).where(Show.date == s_date)).first() if found: el_show_map[s['show_id']] = found.id # Map Songs el_songs = fetch_all_json("songs") el_song_map = {} # el_id -> our_id for s in el_songs: found = session.exec(select(Song).where(Song.title == s['name'])).first() if found: el_song_map[s['id']] = found.id # Now fetch setlists el_setlists = fetch_all_json("setlists") count = 0 for item in el_setlists: our_show_id = el_show_map.get(item['show_id']) our_song_id = el_song_map.get(item['song_id']) position = item.get('position', 0) if our_show_id and our_song_id: # Find existing perf perf = perf_map.get((our_show_id, our_song_id, position)) if perf: # Logic to fix set_name set_val = str(item.get('setnumber', '1')) set_name = f"Set {set_val}" 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" if perf.set_name != set_name: perf.set_name = set_name session.add(perf) count += 1 session.commit() print(f"Fixed {count} performance set names.") if __name__ == "__main__": fix_data()