"""Routes for the core tunes table.""" from flask import Blueprint, jsonify, request from app.extensions import db from app.models import Tune, TuneByInstrument, TuneNote, Reference, Musician from app.auth import require_api_key tunes_bp = Blueprint("tunes", __name__, url_prefix="/tunes") # --------------------------------------------------------------------------- # List / filter # --------------------------------------------------------------------------- @tunes_bp.get("/") def list_tunes(): """ Query params (all optional, combinable): instrument_id=1 key=D tuning_id=1 status=callable|review|to_learn difficulty=easy|hard modal=true|false source_id=1 search= """ q = db.session.query(Tune) search = request.args.get("search") if search: q = q.filter(Tune.name.ilike(f"%{search}%")) key = request.args.get("key") if key: q = q.filter(Tune.key.ilike(key)) modal = request.args.get("modal") if modal is not None: q = q.filter(Tune.modal == (modal.lower() in ("true", "1", "yes"))) source_id = request.args.get("source_id") if source_id: q = q.filter(Tune.source_id == int(source_id)) instrument_id = request.args.get("instrument_id") tuning = request.args.get("tuning") status = request.args.get("status") difficulty = request.args.get("difficulty") if any([instrument_id, tuning, status, difficulty]): q = q.join(Tune.instruments) if instrument_id: q = q.filter(TuneByInstrument.instrument_id == int(instrument_id)) if tuning: q = q.filter(TuneByInstrument.tuning_id == int(tuning)) if status: q = q.filter(TuneByInstrument.status == status) if difficulty: q = q.filter(TuneByInstrument.difficulty.ilike(difficulty)) tunes = q.order_by(Tune.name).all() return jsonify([t.to_dict() for t in tunes]) # --------------------------------------------------------------------------- # Get single tune # --------------------------------------------------------------------------- @tunes_bp.get("/") def get_tune(tune_id): tune = db.get_or_404(Tune, tune_id) return jsonify(tune.to_dict()) # --------------------------------------------------------------------------- # Create tune (with optional nested instruments / notes / references) # --------------------------------------------------------------------------- @tunes_bp.post("/") @require_api_key def create_tune(): data = request.get_json(force=True) tune = Tune( name=data.get("name"), key=data.get("key"), modal=data.get("modal"), source_id=data.get("source_id"), ) db.session.add(tune) db.session.flush() for inst_data in data.get("instruments", []): entry = TuneByInstrument( tune_id=tune.id, instrument_id=inst_data["instrument_id"], learned_from_id=inst_data.get("learned_from_id"), tuning_id=inst_data.get("tuning_id"), date_learned=inst_data.get("date_learned"), status=inst_data.get("status"), difficulty=inst_data.get("difficulty"), ) db.session.add(entry) for note_data in data.get("notes", []): db.session.add(TuneNote(tune_id=tune.id, note=note_data.get("note"))) for ref_data in data.get("references", []): ref = Reference(tune_id=tune.id, link=ref_data.get("link"), site=ref_data.get("site")) db.session.add(ref) db.session.flush() for m in ref_data.get("musicians", []): musician = db.session.get(Musician, m["id"]) if musician: ref.musicians.append(musician) db.session.commit() return jsonify(tune.to_dict()), 201 # --------------------------------------------------------------------------- # Update tune core fields # --------------------------------------------------------------------------- @tunes_bp.patch("/") @require_api_key def update_tune(tune_id): tune = db.get_or_404(Tune, tune_id) data = request.get_json(force=True) for field in ("name", "key", "modal", "source_id"): if field in data: setattr(tune, field, data[field]) db.session.commit() return jsonify(tune.to_dict()) # --------------------------------------------------------------------------- # Delete tune # --------------------------------------------------------------------------- @tunes_bp.delete("/") @require_api_key def delete_tune(tune_id): tune = db.get_or_404(Tune, tune_id) db.session.delete(tune) db.session.commit() return jsonify({"deleted": tune_id})