from flask import Flask, render_template, request, redirect, url_for from werkzeug.utils import secure_filename import yaml from yaml.loader import SafeLoader import os import json from pathlib import Path 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()] app = Flask(__name__) # register the middleware to prefix all the requests with our base_url app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/soupboat/workbook') def create_instrument(name, description, params, sockets, panel): slug = secure_filename(name) os.mkdir(f'static/instruments/{slug}') os.mkdir(f'static/instruments/{slug}/patches') os.mkdir(f'static/instruments/{slug}/samples') instrument = { "name": name, "slug": slug, "description": description, "params": params, "sockets": sockets } with open(f'static/instruments/{slug}/model.yml', 'w') as f: yaml.dump(instrument, f, sort_keys=False) panel.save(f'static/instruments/{slug}/panel.svg') @app.route("/") def workbook(): return render_template('workbook.html') @app.route("/") def page(slug): return render_template(f'{slug}.html') @app.route("/instruments") def instruments(): instruments = [] for filename in os.listdir('static/instruments'): with open(f'static/instruments/{filename}/model.yml') as f: instrument = yaml.load(f, Loader=SafeLoader) instruments.append(instrument) return render_template('instruments.html', instruments=instruments) @app.route("/instruments/") def patches(instrument): with open(f'static/instruments/{instrument}/panel.svg') as f: panel = f.read() patches = [] for filename in os.listdir(f'static/instruments/{instrument}/patches'): with open(f'static/instruments/{instrument}/patches/{filename}/{filename}.yml') as f: patch = yaml.load(f, Loader=SafeLoader) patches.append(patch) 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//add", methods=['GET', 'POST']) def add_patch(instrument): 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"]) patch['slug'] = slug Path(f'static/instruments/{instrument}/patches/{slug}').mkdir() with open(f'static/instruments/{instrument}/patches/{slug}/{slug}.yml', 'w') as f: yaml.dump(patch, f) return redirect(url_for('patches', instrument=instrument)) with open(f'static/instruments/{instrument}/panel.svg') as f: panel = f.read() with open(f'static/instruments/{instrument}/model.yml') as f: instrument = yaml.load(f, Loader=SafeLoader) return render_template('add_patch.html', instrument=instrument, panel=panel) @app.route("/instruments//", methods=['GET', 'POST']) def patch(instrument, name): if request.method == 'POST': file = request.files['snippet'] if file: Path(f'static/instruments/{instrument}/patches/{name}/snippets').mkdir(exist_ok=True) filename = secure_filename(file.filename) file.save(os.path.join(f'static/instruments/{instrument}/patches/{name}/snippets', filename)) # description = request.form['description'] redirect(url_for('patch', instrument=instrument, name=name)) snippets = [] if os.path.exists(f'static/instruments/{instrument}/patches/{name}/snippets'): for filename in os.listdir(f'static/instruments/{instrument}/patches/{name}/snippets'): snippets.append(filename) with open(f'static/instruments/{instrument}/panel.svg') as f: panel = f.read() with open(f'static/instruments/{instrument}/patches/{name}/{name}.yml') as f: patch = yaml.load(f, Loader=SafeLoader) with open(f'static/instruments/{instrument}/model.yml') as f: instrument = yaml.load(f, Loader=SafeLoader) return render_template('patch.html', instrument=instrument, patch=patch, panel=panel, snippets=snippets) app.run(port=3146, debug=True)