Clean up unused API endpoints and server code
This commit is contained in:
parent
b4d6ea81a1
commit
ab7e949f07
212
webapp/server.py
212
webapp/server.py
|
|
@ -19,29 +19,25 @@ from fractions import Fraction
|
|||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Path to data files
|
||||
# Path to output directory
|
||||
DATA_DIR = Path(__file__).parent.parent / "output"
|
||||
DATA_FILE = "output_chords.json" # default file
|
||||
DEFAULT_FILE = "output_chords.json" # default file
|
||||
|
||||
# State
|
||||
current_index = 0
|
||||
chords = []
|
||||
dims = (2, 3, 5, 7)
|
||||
|
||||
# OSC settings
|
||||
fundamental = 110.0
|
||||
osc_sender = OSCSender(ip="127.0.0.1", port=57120, fundamental=fundamental)
|
||||
|
||||
|
||||
def get_chords_file():
|
||||
return DATA_DIR / DATA_FILE
|
||||
|
||||
|
||||
def load_chords():
|
||||
def load_chords(filepath=None):
|
||||
global chords, current_index
|
||||
chords_file = get_chords_file()
|
||||
if chords_file.exists():
|
||||
with open(chords_file) as f:
|
||||
if filepath is None:
|
||||
filepath = DATA_DIR / DEFAULT_FILE
|
||||
if filepath.exists():
|
||||
with open(filepath) as f:
|
||||
data = json.load(f)
|
||||
chords = data.get("chords", [])
|
||||
current_index = 0
|
||||
|
|
@ -72,82 +68,6 @@ def calculate_cents(fraction_str):
|
|||
return 1200 * math.log2(fr)
|
||||
|
||||
|
||||
def calculate_graph(chord):
|
||||
"""Calculate nodes and edges for a chord using pitch logic."""
|
||||
if not chord:
|
||||
return {"nodes": [], "edges": []}
|
||||
|
||||
# Calculate cents for each pitch
|
||||
import math
|
||||
|
||||
nodes = []
|
||||
cents_list = []
|
||||
|
||||
for i, pitch in enumerate(chord):
|
||||
fr = parse_fraction(pitch.get("fraction", "1"))
|
||||
cents = 1200 * math.log2(fr) if fr > 0 else 0
|
||||
cents_list.append(cents)
|
||||
|
||||
nodes.append(
|
||||
{
|
||||
"id": i,
|
||||
"cents": round(cents),
|
||||
"fraction": pitch.get("fraction", "1"),
|
||||
"hs_array": pitch.get("hs_array", []),
|
||||
}
|
||||
)
|
||||
|
||||
# Find edges: differ by ±1 in exactly one dimension (ignoring dim 0)
|
||||
edges = []
|
||||
for i in range(len(chord)):
|
||||
for j in range(i + 1, len(chord)):
|
||||
hs1 = chord[i].get("hs_array", [])
|
||||
hs2 = chord[j].get("hs_array", [])
|
||||
|
||||
if not hs1 or not hs2:
|
||||
continue
|
||||
|
||||
# Count differences in dims 1, 2, 3
|
||||
diff_count = 0
|
||||
diff_dim = -1
|
||||
|
||||
for d in range(1, len(hs1)):
|
||||
diff = hs2[d] - hs1[d]
|
||||
if abs(diff) == 1:
|
||||
diff_count += 1
|
||||
diff_dim = d
|
||||
elif diff != 0:
|
||||
break # diff > 1 in this dimension
|
||||
else:
|
||||
# Check if exactly one dimension differs
|
||||
if diff_count == 1 and diff_dim > 0:
|
||||
# Calculate frequency ratio from pitch difference
|
||||
# diff = hs1 - hs2 gives direction
|
||||
# Convert to fraction
|
||||
diff_hs = [hs1[d] - hs2[d] for d in range(len(hs1))]
|
||||
|
||||
numerator = 1
|
||||
denominator = 1
|
||||
for d_idx, d in enumerate(dims):
|
||||
exp = diff_hs[d_idx]
|
||||
if exp > 0:
|
||||
numerator *= d**exp
|
||||
elif exp < 0:
|
||||
denominator *= d ** (-exp)
|
||||
|
||||
ratio = (
|
||||
f"{numerator}/{denominator}"
|
||||
if denominator > 1
|
||||
else str(numerator)
|
||||
)
|
||||
|
||||
edges.append(
|
||||
{"source": i, "target": j, "ratio": ratio, "dim": diff_dim}
|
||||
)
|
||||
|
||||
return {"nodes": nodes, "edges": edges}
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return send_from_directory(".", "path_navigator.html")
|
||||
|
|
@ -158,126 +78,11 @@ def serve_static(filename):
|
|||
return send_from_directory(".", filename)
|
||||
|
||||
|
||||
@app.route("/api/files")
|
||||
def list_files():
|
||||
"""List available output files."""
|
||||
files = []
|
||||
if DATA_DIR.exists():
|
||||
for f in DATA_DIR.iterdir():
|
||||
if f.is_file() and f.suffix == ".json" and "chords" in f.name:
|
||||
files.append(f.name)
|
||||
return jsonify({"files": sorted(files)})
|
||||
|
||||
|
||||
@app.route("/api/set-file/<filename>", methods=["POST"])
|
||||
def set_data_file(filename):
|
||||
global DATA_FILE, current_index
|
||||
DATA_FILE = filename
|
||||
current_index = 0
|
||||
load_chords()
|
||||
return jsonify({"file": DATA_FILE, "loaded": len(chords), "index": current_index})
|
||||
|
||||
|
||||
@app.route("/api/chords")
|
||||
def get_chords():
|
||||
return jsonify({"chords": chords, "total": len(chords)})
|
||||
|
||||
|
||||
@app.route("/api/current")
|
||||
def get_current():
|
||||
if not chords:
|
||||
return jsonify({"error": "No chords loaded"}), 404
|
||||
|
||||
prev_idx = current_index - 1 if current_index > 0 else None
|
||||
next_idx = current_index + 1 if current_index < len(chords) - 1 else None
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"index": current_index,
|
||||
"total": len(chords),
|
||||
"prev": chords[prev_idx] if prev_idx is not None else None,
|
||||
"current": chords[current_index],
|
||||
"next": chords[next_idx] if next_idx is not None else None,
|
||||
"has_prev": prev_idx is not None,
|
||||
"has_next": next_idx is not None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.route("/api/graph/<int:index>")
|
||||
def get_graph(index):
|
||||
"""Get computed graph for prev/current/next at given index."""
|
||||
if not chords:
|
||||
return jsonify({"error": "No chords loaded"}), 404
|
||||
|
||||
if not (0 <= index < len(chords)):
|
||||
return jsonify({"error": "Invalid index"}), 400
|
||||
|
||||
prev_idx = index - 1 if index > 0 else None
|
||||
next_idx = index + 1 if index < len(chords) - 1 else None
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"index": index,
|
||||
"total": len(chords),
|
||||
"prev": calculate_graph(chords[prev_idx]) if prev_idx is not None else None,
|
||||
"current": calculate_graph(chords[index]),
|
||||
"next": calculate_graph(chords[next_idx]) if next_idx is not None else None,
|
||||
"has_prev": prev_idx is not None,
|
||||
"has_next": next_idx is not None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.route("/api/all-graphs")
|
||||
def get_all_graphs():
|
||||
"""Get computed graph for ALL chords at once for single-canvas rendering."""
|
||||
if not chords:
|
||||
return jsonify({"error": "No chords loaded"}), 404
|
||||
|
||||
all_graphs = []
|
||||
for i, chord in enumerate(chords):
|
||||
graph = calculate_graph(chord)
|
||||
graph["index"] = i
|
||||
all_graphs.append(graph)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"total": len(chords),
|
||||
"graphs": all_graphs,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.route("/api/navigate", methods=["POST"])
|
||||
def navigate():
|
||||
global current_index
|
||||
data = request.json
|
||||
direction = data.get("direction", "next")
|
||||
|
||||
if direction == "prev" and current_index > 0:
|
||||
current_index -= 1
|
||||
elif direction == "next" and current_index < len(chords) - 1:
|
||||
current_index += 1
|
||||
|
||||
return jsonify({"index": current_index})
|
||||
|
||||
|
||||
@app.route("/api/goto/<int:index>")
|
||||
def goto(index):
|
||||
global current_index
|
||||
if 0 <= index < len(chords):
|
||||
current_index = index
|
||||
return jsonify({"index": current_index})
|
||||
return jsonify({"error": "Invalid index"}), 400
|
||||
|
||||
|
||||
@app.route("/api/reload", methods=["POST"])
|
||||
def reload():
|
||||
load_chords()
|
||||
return jsonify({"loaded": len(chords), "index": current_index})
|
||||
|
||||
|
||||
@app.route("/api/set-fundamental", methods=["POST"])
|
||||
def set_fundamental():
|
||||
"""Set the fundamental frequency for OSC playback."""
|
||||
|
|
@ -439,7 +244,8 @@ def batch_calculate_cents_api():
|
|||
|
||||
if __name__ == "__main__":
|
||||
print("Starting Path Navigator server...")
|
||||
print(f"Loading chords from: {get_chords_file()}")
|
||||
filepath = DATA_DIR / DEFAULT_FILE
|
||||
print(f"Loading chords from: {filepath}")
|
||||
load_chords()
|
||||
print(f"Loaded {len(chords)} chords")
|
||||
app.run(host="0.0.0.0", port=8080, debug=True)
|
||||
|
|
|
|||
Loading…
Reference in a new issue