Initial Commit
slip slop
This commit is contained in:
commit
064e672ab7
61 changed files with 3504 additions and 0 deletions
155
app/routes_tunes.py
Normal file
155
app/routes_tunes.py
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
"""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
|
||||
callable=true|false
|
||||
review=true|false
|
||||
to_learn=true|false
|
||||
difficulty=easy|hard
|
||||
modal=true|false
|
||||
source_id=1
|
||||
search=<substring match on name>
|
||||
"""
|
||||
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")
|
||||
callable_ = request.args.get("callable")
|
||||
review = request.args.get("review")
|
||||
to_learn = request.args.get("to_learn")
|
||||
difficulty = request.args.get("difficulty")
|
||||
|
||||
def _bool(val):
|
||||
return val.lower() in ("true", "1", "yes")
|
||||
|
||||
if any([instrument_id, tuning, callable_, review, to_learn, 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 callable_ is not None:
|
||||
q = q.filter(TuneByInstrument.callable == _bool(callable_))
|
||||
if review is not None:
|
||||
q = q.filter(TuneByInstrument.review == _bool(review))
|
||||
if to_learn is not None:
|
||||
q = q.filter(TuneByInstrument.to_learn == _bool(to_learn))
|
||||
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("/<int:tune_id>")
|
||||
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"),
|
||||
callable=inst_data.get("callable"),
|
||||
review=inst_data.get("review"),
|
||||
to_learn=inst_data.get("to_learn", False),
|
||||
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("/<int:tune_id>")
|
||||
@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("/<int:tune_id>")
|
||||
@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})
|
||||
Loading…
Add table
Add a link
Reference in a new issue