/
application.py
executable file
·173 lines (125 loc) · 4.95 KB
/
application.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import json
import base64
import datetime
import os
import uuid
from flask import (Flask, flash, jsonify, redirect, render_template, request,
send_from_directory, session, url_for)
from forms import LoginForm, SignupForm
from model import Recording, User, connect_to_db, db
from pitchgraph import analyze_pitch
application = Flask(__name__)
application.config.from_object(os.environ.get('APP_SETTINGS') or 'config.DevelopmentConfig')
connect_to_db(application)
@application.route('/')
def index():
return render_template("home.html")
@application.route('/signup', methods=["GET", "POST"])
def signup():
form = SignupForm()
if form.validate_on_submit():
user = User(email=form.email.data.lower(), created_at=datetime.datetime.now())
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
session['user_id'] = user.id
session['email'] = user.email
return redirect(url_for('index'))
elif form.errors:
flash("Error creating account")
return render_template("signup.html", form=form)
@application.route('/login', methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user:
if user.check_password(form.password.data):
session['user_id'] = user.id
session['email'] = user.email
return redirect(url_for('index'))
flash('Invalid email or password')
return render_template("login.html", form=form)
@application.route('/logout')
def logout():
if 'user_id' in session:
session.pop('user_id')
if 'email' in session:
session.pop('email')
return redirect(url_for('login'))
@application.route('/about')
def about():
return render_template("about.html")
@application.route('/guidelines')
def guidelines():
return render_template("guidelines.html")
@application.route('/french')
def french_content():
return render_template("french.html")
@application.route('/english-us')
def english_content():
return render_template('english-us.html')
@application.route('/russian')
def russian_content():
return render_template('russian.html')
@application.route('/<path:path>')
def send_audio_file(path):
return send_from_directory('static', path)
@application.route('/targetdata', methods=["POST"])
def send_target_pitch_data():
"""Send pitch data from target recording to be displayed in graph when tab loads.
Also send the user's past attempts at this sentence, if any."""
ex_id = request.form.get("sentence")
with open("./static/json/" + ex_id + "-pd.json") as target_file:
target_pitch_data = json.loads(target_file.read())
attempts = []
if 'user_id' in session:
attempts = Recording.query.filter_by(user_id=session['user_id'], ex_id=ex_id).all()
return jsonify(target_pitch_data=target_pitch_data,
attempts=[attempt.serialize() for attempt in attempts])
@application.route('/analyze', methods=["POST"])
def analyze_user_rec():
"""Analyze the user's recording, save audio data and pitch data to
the database if they're logged in, and send pitch data back to page."""
ex_id = request.form.get("ex_id")
# cut off first 22 chars ("data:audio/wav;base64,")
user_b64 = request.form.get("user_rec")[22:]
user_wav = base64.b64decode(user_b64)
user_recording_path = os.path.abspath('./static/sounds/user-rec-' + str(uuid.uuid4()) + '.wav')
with open(user_recording_path, 'wb') as f:
f.write(user_wav)
user_pitch_data = analyze_pitch(user_recording_path)
os.remove(user_recording_path)
attempt = {}
if 'user_id' in session:
attempts = Recording.query.filter_by(user_id=session['user_id'], ex_id=ex_id).all()
attempt_num = 1
if attempts:
attempt_num += max(attempt.attempt_num for attempt in attempts)
new_rec = Recording(user_id=session['user_id'],
ex_id=ex_id,
attempt_num=attempt_num,
audio_data=user_b64,
pitch_data=user_pitch_data,
created_at=datetime.datetime.now())
db.session.add(new_rec)
db.session.commit()
attempt = new_rec.serialize()
else:
attempt = {
"ex_id": ex_id,
"audio_data": user_b64,
"pitch_data": json.loads(user_pitch_data)
}
return jsonify(attempt=attempt)
@application.route('/delete-attempt', methods=["POST"])
def delete_attempt():
rec = Recording.query.filter_by(id=request.form.get("id")).first()
if rec:
db.session.delete(rec)
db.session.commit()
return redirect(redirect_url())
def redirect_url(default='index'):
return request.args.get('next') or request.referrer or url_for(default)
if __name__ == "__main__":
application.run()