|
|
|
from flask import Flask, render_template, request, redirect, url_for
|
|
|
|
from werkzeug.utils import secure_filename
|
|
|
|
import json
|
|
|
|
import sqlite3
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
from pathlib import Path
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
class PrefixMiddleware(object):
|
|
|
|
def __init__(self, app, prefix=""):
|
|
|
|
self.app = app
|
|
|
|
self.prefix = prefix
|
|
|
|
|
|
|
|
def __call__(self, environ, start_response):
|
|
|
|
|
|
|
|
if environ["PATH_INFO"].startswith(self.prefix):
|
|
|
|
environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix) :]
|
|
|
|
environ["SCRIPT_NAME"] = self.prefix
|
|
|
|
return self.app(environ, start_response)
|
|
|
|
else:
|
|
|
|
start_response("404", [("Content-Type", "text/plain")])
|
|
|
|
return ["This url does not belong to the app.".encode()]
|
|
|
|
|
|
|
|
|
|
|
|
load_dotenv()
|
|
|
|
|
|
|
|
Path(f'static/panels/').mkdir(exist_ok=True)
|
|
|
|
Path(f'static/cables/').mkdir(exist_ok=True)
|
|
|
|
Path(f'static/snippets/').mkdir(exist_ok=True)
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
# register the middleware to prefix all the requests with our base_url
|
|
|
|
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix=os.environ.get('BASE_URL', ''))
|
|
|
|
|
|
|
|
|
|
|
|
def get_db_connection():
|
|
|
|
conn = sqlite3.connect('database.db')
|
|
|
|
conn.row_factory = sqlite3.Row
|
|
|
|
return conn
|
|
|
|
|
|
|
|
def dict_from_row(row):
|
|
|
|
return dict(zip(row.keys(), row))
|
|
|
|
|
|
|
|
def create_instrument(name, description, params, sockets, panel):
|
|
|
|
slug = secure_filename(name)
|
|
|
|
panel.save(f'static/panels/{slug}.svg')
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
cur = connection.cursor()
|
|
|
|
cur.execute(
|
|
|
|
"INSERT INTO instruments (name, slug, description, panel) VALUES (?, ?, ?, ?)",
|
|
|
|
(name, slug, description, f'{slug}.svg')
|
|
|
|
)
|
|
|
|
|
|
|
|
instrument_id = cur.lastrowid
|
|
|
|
|
|
|
|
for param in params:
|
|
|
|
cur.execute(
|
|
|
|
"INSERT OR IGNORE INTO params (param_name) VALUES (?)",(param,)
|
|
|
|
)
|
|
|
|
cur.execute(
|
|
|
|
"INSERT INTO instrument_param (instrument_id, param_name) VALUES (?, ?)", (instrument_id, param )
|
|
|
|
)
|
|
|
|
|
|
|
|
for socket in sockets:
|
|
|
|
cur.execute(
|
|
|
|
"INSERT OR IGNORE INTO sockets (socket_name) VALUES (?)", (socket,)
|
|
|
|
)
|
|
|
|
|
|
|
|
cur.execute(
|
|
|
|
"INSERT INTO instrument_socket (instrument_id, socket_name) VALUES (?, ?)", (instrument_id, socket )
|
|
|
|
)
|
|
|
|
|
|
|
|
connection.commit()
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
def workbook():
|
|
|
|
return render_template('workbook.html')
|
|
|
|
|
|
|
|
@app.route("/<slug>")
|
|
|
|
def page(slug):
|
|
|
|
return render_template(f'{slug}.html')
|
|
|
|
|
|
|
|
@app.route("/instruments")
|
|
|
|
def instruments():
|
|
|
|
connection = get_db_connection()
|
|
|
|
instruments = connection.execute('SELECT * FROM instruments').fetchall()
|
|
|
|
connection.close()
|
|
|
|
return render_template('instruments.html', instruments=instruments)
|
|
|
|
|
|
|
|
@app.route("/instruments/<instrument>")
|
|
|
|
def patches(instrument):
|
|
|
|
|
|
|
|
with open(f'static/panels/{instrument}.svg', 'r') as f:
|
|
|
|
panel = f.read()
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
instrument = cursor.execute("SELECT * FROM instruments WHERE slug = ?", (instrument, )).fetchone()
|
|
|
|
instrument = dict_from_row(instrument)
|
|
|
|
patches = cursor.execute("SELECT * FROM patches WHERE instrument = ?", (instrument['slug'],)).fetchall()
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
return render_template('patches.html', instrument=instrument, patches=patches, panel=panel)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/instruments/add", methods=['GET', 'POST'])
|
|
|
|
def add_instrument():
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
|
|
|
name = request.form.get('name')
|
|
|
|
description = request.form.get('description')
|
|
|
|
params = json.loads(request.form.get('params'))
|
|
|
|
sockets = json.loads(request.form.get('sockets'))
|
|
|
|
panel = request.files['panel']
|
|
|
|
create_instrument(name, description, params, sockets, panel)
|
|
|
|
|
|
|
|
return redirect(url_for('instruments'))
|
|
|
|
|
|
|
|
return render_template('add_instrument.html')
|
|
|
|
|
|
|
|
@app.route("/instruments/<instrument>/add", methods=['GET', 'POST'])
|
|
|
|
def add_patch(instrument):
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
patch = request.form.to_dict()
|
|
|
|
patch = {k: v for k, v in patch.items() if v}
|
|
|
|
|
|
|
|
slug = secure_filename(patch["name"])
|
|
|
|
|
|
|
|
with open(f'static/cables/{slug}.svg', 'w') as f:
|
|
|
|
f.write(patch['cables'])
|
|
|
|
|
|
|
|
cursor.execute(
|
|
|
|
'INSERT INTO patches (name, slug, description, cables, instrument) VALUES (?,?,?,?,?)',
|
|
|
|
(patch['name'], slug, patch['description'], f"{slug}.svg", instrument)
|
|
|
|
)
|
|
|
|
|
|
|
|
patch_id = cursor.lastrowid
|
|
|
|
|
|
|
|
patch.pop('name','')
|
|
|
|
patch.pop('slug','')
|
|
|
|
patch.pop('description','')
|
|
|
|
patch.pop('cables','')
|
|
|
|
|
|
|
|
for param, value in patch.items():
|
|
|
|
cursor.execute('INSERT INTO patch_param (patch_id, param_name, value) VALUES (?,?,?)',
|
|
|
|
(patch_id, param, value))
|
|
|
|
|
|
|
|
connection.commit()
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
return redirect(url_for('patches', instrument=instrument))
|
|
|
|
|
|
|
|
with open(f'static/panels/{instrument}.svg', 'r') as f:
|
|
|
|
panel = f.read()
|
|
|
|
|
|
|
|
instrument = cursor.execute('SELECT * FROM instruments WHERE slug = ?', (instrument,)).fetchone()
|
|
|
|
|
|
|
|
connection.close()
|
|
|
|
return render_template('add_patch.html', instrument=instrument, panel = panel)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/instruments/<instrument>/<name>", methods=['GET', 'POST'])
|
|
|
|
def patch(instrument, name):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
file = request.files['snippet']
|
|
|
|
|
|
|
|
if file:
|
|
|
|
filename = secure_filename(file.filename)
|
|
|
|
file.save(f'static/snippets/{instrument}_{name}_{filename}')
|
|
|
|
|
|
|
|
|
|
|
|
cursor.execute('INSERT INTO snippets (filename, instrument, patch_name, description) VALUES (?,?,?,?)',
|
|
|
|
(filename, instrument, name, request.form.get('description'))
|
|
|
|
)
|
|
|
|
|
|
|
|
connection.commit()
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
redirect(url_for('patch', instrument=instrument, name=name))
|
|
|
|
|
|
|
|
|
|
|
|
connection = get_db_connection()
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
snippets = cursor.execute('SELECT * FROM snippets WHERE instrument = ? AND patch_name = ?',
|
|
|
|
(instrument, name)).fetchall()
|
|
|
|
|
|
|
|
patch = cursor.execute('SELECT * FROM patches WHERE instrument = ? AND slug = ?',
|
|
|
|
(instrument, name)).fetchone()
|
|
|
|
|
|
|
|
params = cursor.execute('SELECT * FROM patch_param WHERE patch_id = ?',
|
|
|
|
(patch['id'],)).fetchall()
|
|
|
|
|
|
|
|
instrument = cursor.execute('SELECT * FROM instruments WHERE slug = ?',
|
|
|
|
(instrument,)).fetchone()
|
|
|
|
|
|
|
|
with open(f'static/panels/{instrument["slug"]}.svg') as f:
|
|
|
|
panel = f.read()
|
|
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
return render_template('patch.html', instrument=instrument, patch=patch, params=params, panel=panel, snippets=snippets)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.run(port=os.environ.get('FLASK_RUN_PORT'), debug=True)
|