-
Notifications
You must be signed in to change notification settings - Fork 7
/
server.py
93 lines (76 loc) · 3.26 KB
/
server.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
from build_weighted_model import build_weighted_model
from genre_recognizer import GenreRecognizer
from common import GENRES
import numpy as np
import os
import json
import uuid
from random import random
import time
import tornado
import tornado.ioloop
import tornado.web
from optparse import OptionParser
STATIC_PATH = os.path.join(os.path.dirname(__file__), 'static')
UPLOADS_PATH = os.path.join(os.path.dirname(__file__), 'uploads')
genre_recognizer = None
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render(os.path.join(STATIC_PATH, 'index.html'))
class PlayHandler(tornado.web.RequestHandler):
def get(self):
self.render(os.path.join(STATIC_PATH, 'play.html'))
class UploadHandler(tornado.web.RequestHandler):
def post(self):
file_info = self.request.files['filearg'][0]
file_name = file_info['filename']
file_extension = os.path.splitext(file_name)[1]
file_uuid = str(uuid.uuid4())
uploaded_name = file_uuid + file_extension
if not os.path.exists(UPLOADS_PATH):
os.makedirs(UPLOADS_PATH)
uploaded_path = os.path.join(UPLOADS_PATH, uploaded_name)
with open(uploaded_path, 'wb') as f:
f.write(file_info['body'])
(predictions, duration) = genre_recognizer.recognize(uploaded_path)
genre_distributions = self.get_genre_distribution_over_time(predictions, duration)
json_path = os.path.join(UPLOADS_PATH, file_uuid + '.json')
with open(json_path, 'w') as f:
f.write(json.dumps(genre_distributions))
self.finish('"{}"'.format(file_uuid))
def get_genre_distribution_over_time(self, predictions, duration):
"""
Turns the matrix of predictions given by a model into a dict mapping
time in the song to a music genre distribution.
"""
predictions = np.reshape(predictions, np.array(predictions).shape[2:])
n_steps = predictions.shape[0]
delta_t = duration / n_steps
def get_genre_distribution(step):
return {genre_name: float(predictions[step, genre_index])
for (genre_index, genre_name) in enumerate(GENRES)}
return [((step + 1) * delta_t, get_genre_distribution(step)) for step in range(n_steps)]
application = tornado.web.Application([
(r'/', MainHandler),
(r'/play.html', PlayHandler),
(r'/static/(.*)', tornado.web.StaticFileHandler, {
'path': STATIC_PATH
}),
(r'/uploads/(.*)', tornado.web.StaticFileHandler, {
'path': UPLOADS_PATH
}),
(r'/upload', UploadHandler),
], debug=True)
if __name__ == '__main__':
parser = OptionParser()
parser.add_option('-w', '--weights', dest='weights_path',
default=os.path.join(os.path.dirname(__file__),
'models/weights.best.hdf5'),
help='load keras model WEIGHTS hdf5 file', metavar='WEIGHTS')
parser.add_option('-p', '--port', dest='port',
default=8000,
help='run server at PORT', metavar='PORT')
options, args = parser.parse_args()
genre_recognizer = GenreRecognizer(build_weighted_model(options.weights_path))
application.listen(options.port)
tornado.ioloop.IOLoop.instance().start()