170 lines
6.2 KiB
Python
170 lines
6.2 KiB
Python
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()
|