repertory-api/app/routes_sub.py
Ian Keane 507531fbff Changes for refactor of references view, add unique keys for some tables
References sites table updated so we can filter by site later, added
timestamp to tunes so they can be sorted in certain contexts, enforced
uniqueness on some tables that were causing issues
2026-06-11 10:05:23 -04:00

124 lines
4 KiB
Python

"""Routes for notes and references sub-resources."""
from flask import Blueprint, jsonify, request
from app.extensions import db
from app.models import Tune, TuneNote, Reference, Musician
from app.auth import require_api_key
sub_bp = Blueprint("sub", __name__)
# ===========================================================================
# Notes
# ===========================================================================
@sub_bp.get("/tunes/<int:tune_id>/notes")
def list_notes(tune_id):
db.get_or_404(Tune, tune_id)
notes = db.session.query(TuneNote).filter_by(tune_id=tune_id).all()
return jsonify([n.to_dict() for n in notes])
@sub_bp.post("/tunes/<int:tune_id>/notes")
@require_api_key
def add_note(tune_id):
db.get_or_404(Tune, tune_id)
data = request.get_json(force=True)
note = TuneNote(tune_id=tune_id, note=data.get("note"))
db.session.add(note)
db.session.commit()
return jsonify(note.to_dict()), 201
@sub_bp.patch("/tunes/<int:tune_id>/notes/<int:note_id>")
@require_api_key
def update_note(tune_id, note_id):
note = db.get_or_404(TuneNote, note_id)
data = request.get_json(force=True)
if "note" in data:
note.note = data["note"]
db.session.commit()
return jsonify(note.to_dict())
@sub_bp.delete("/tunes/<int:tune_id>/notes/<int:note_id>")
@require_api_key
def delete_note(tune_id, note_id):
note = db.get_or_404(TuneNote, note_id)
db.session.delete(note)
db.session.commit()
return jsonify({"deleted": note_id})
# ===========================================================================
# References
# ===========================================================================
@sub_bp.get("/tunes/<int:tune_id>/references")
def list_references(tune_id):
db.get_or_404(Tune, tune_id)
refs = db.session.query(Reference).filter_by(tune_id=tune_id).all()
return jsonify([r.to_dict() for r in refs])
@sub_bp.post("/tunes/<int:tune_id>/references")
@require_api_key
def add_reference(tune_id):
db.get_or_404(Tune, tune_id)
data = request.get_json(force=True)
ref = Reference(tune_id=tune_id, link=data.get("link"), site_id=data.get("site_id"))
db.session.add(ref)
db.session.flush()
for m in data.get("musicians", []):
musician = db.session.get(Musician, m["id"])
if musician:
ref.musicians.append(musician)
db.session.commit()
return jsonify(ref.to_dict()), 201
@sub_bp.patch("/tunes/<int:tune_id>/references/<int:ref_id>")
@require_api_key
def update_reference(tune_id, ref_id):
ref = db.get_or_404(Reference, ref_id)
data = request.get_json(force=True)
for field in ("link", "site_id"):
if field in data:
setattr(ref, field, data[field])
db.session.commit()
return jsonify(ref.to_dict())
@sub_bp.delete("/tunes/<int:tune_id>/references/<int:ref_id>")
@require_api_key
def delete_reference(tune_id, ref_id):
ref = db.get_or_404(Reference, ref_id)
db.session.delete(ref)
db.session.commit()
return jsonify({"deleted": ref_id})
# ===========================================================================
# Musicians on a reference (add/remove via join table)
# ===========================================================================
@sub_bp.post("/tunes/<int:tune_id>/references/<int:ref_id>/musicians")
@require_api_key
def add_musician_to_reference(tune_id, ref_id):
ref = db.get_or_404(Reference, ref_id)
data = request.get_json(force=True)
musician = db.get_or_404(Musician, data["musician_id"])
if musician not in ref.musicians:
ref.musicians.append(musician)
db.session.commit()
return jsonify(ref.to_dict())
@sub_bp.delete("/tunes/<int:tune_id>/references/<int:ref_id>/musicians/<int:musician_id>")
@require_api_key
def remove_musician_from_reference(tune_id, ref_id, musician_id):
ref = db.get_or_404(Reference, ref_id)
musician = db.get_or_404(Musician, musician_id)
if musician in ref.musicians:
ref.musicians.remove(musician)
db.session.commit()
return jsonify(ref.to_dict())