refactor, fix uri encoding

This commit is contained in:
iou1name 2019-01-11 11:27:25 -05:00
parent 0ec22ee2a2
commit 3382579b47
5 changed files with 53 additions and 19 deletions

View File

@ -4,7 +4,7 @@ Stream some music.
## Requirements ## Requirements
Python 3.6+ Python 3.6+
FFmpeg compiled with `--enable-libopus` FFmpeg compiled with `--enable-libopus`
Python packages: `flask gunicorn` Python packages: `flask gunicorn mutagen`
## Install ## Install
1. Get on the floor 1. Get on the floor

View File

@ -3,10 +3,12 @@
Music streaming. Music streaming.
""" """
import os import os
import re
import json import json
import random import random
import subprocess import subprocess
from urllib import parse from urllib import parse
from collections import defaultdict
from flask import Flask, Response, render_template, send_file from flask import Flask, Response, render_template, send_file
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
@ -23,6 +25,23 @@ FFMPEG_CMD = [
'-' '-'
] ]
def build_tree(root_dir):
"""Walks the music directory and builds a tree."""
print("Building tree.")
tree = defaultdict(dict)
for dirName, subDirs, files in os.walk(root_dir):
if dirName == root_dir:
continue
reg = re.search(".*/(.+?) - (.+) \(\d{4}\)", dirName)
if not reg:
print(dirName)
continue
artist, album = reg.groups()
tracks = [f for f in files if f.rpartition('.')[2] in MUSIC_EXT]
tree[artist][album] = tracks
return tree
app = Flask(__name__) app = Flask(__name__)
@app.route('/') @app.route('/')
@ -40,6 +59,7 @@ def index():
@app.route('/stream/<path:track>') @app.route('/stream/<path:track>')
def stream(track): def stream(track):
"""View for the raw audio file.""" """View for the raw audio file."""
track = parse.unquote(track)
path = os.path.join(MUSIC_DIR, track) path = os.path.join(MUSIC_DIR, track)
path = os.path.abspath(path) path = os.path.abspath(path)
if not path.startswith(MUSIC_DIR): if not path.startswith(MUSIC_DIR):
@ -58,7 +78,8 @@ def stream(track):
@app.route('/get_dir/<path:directory>/') @app.route('/get_dir/<path:directory>/')
def get_dir(directory): @app.route('/get_dir/')
def get_dir(directory=""):
"""Returns the contents of the requested directory.""" """Returns the contents of the requested directory."""
directory = directory.replace("DOTDOT", "..") directory = directory.replace("DOTDOT", "..")
directory = os.path.join(MUSIC_DIR, directory) directory = os.path.join(MUSIC_DIR, directory)

View File

@ -1,5 +1,6 @@
body { body {
margin: 0; margin: 0;
font-family: Helvetica, sans-serif;
} }
img { img {
@ -33,6 +34,7 @@ img {
} }
#playerContainer { #playerContainer {
height: 30vh;
flex: 0 0 auto; flex: 0 0 auto;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -42,6 +44,8 @@ img {
#albumCover { #albumCover {
padding-right: 1em; padding-right: 1em;
padding-left: 1em; padding-left: 1em;
padding-bottom: 3px;
box-sizing: border-box;
} }
#playerControls { #playerControls {

View File

@ -1,23 +1,26 @@
var httpRequest
function load() { function load() {
// track has ended // track has ended
document.getElementById('player').addEventListener('ended', function() { document.getElementById('player').addEventListener('ended', function() {
// shuffle // shuffle
if (document.getElementById('shuffle').checked) { if (document.getElementById('shuffle').checked) {
httpRequest = new XMLHttpRequest(); ajax('/musik/get_shuffle', function() {
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState !== XMLHttpRequest.DONE) { return; } if (httpRequest.readyState !== XMLHttpRequest.DONE) { return; }
if (httpRequest.status !== 200) { return; } if (httpRequest.status !== 200) { return; }
let track = httpRequest.responseText; let track = httpRequest.responseText;
change_track(track); change_track(track);
} });
httpRequest.open('GET', '/musik/get_shuffle', true);
httpRequest.send();
} }
}); });
} }
var httpRequest;
function ajax(url, func) {
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = func;
httpRequest.open('GET', url, true);
httpRequest.send();
}
function navigate(item) { function navigate(item) {
if (/\..{3,5}$/.test(item)) { if (/\..{3,5}$/.test(item)) {
select_track(item); select_track(item);
@ -35,7 +38,7 @@ function select_track(item) {
function change_track(track) { function change_track(track) {
let source = document.getElementById('stream'); let source = document.getElementById('stream');
source.src = '/musik/stream' + track; source.src = '/musik/stream' + encodeURIComponent(track);
let player = document.getElementById('player'); let player = document.getElementById('player');
player.load(); player.load();
player.play(); player.play();
@ -48,12 +51,18 @@ function change_track(track) {
function get_dir(item) { function get_dir(item) {
let cd = document.getElementById('currentDirectory').innerText; let cd = document.getElementById('currentDirectory').innerText;
item = cd + item; if (item === "../") {
item = item.replace(/\.\./g, 'DOTDOT'); if (cd !== "/") {
httpRequest = new XMLHttpRequest(); item = cd.slice(0, cd.slice(0, -1).lastIndexOf("/")+1);
httpRequest.onreadystatechange = update_nav_items; }
httpRequest.open('GET', '/musik/get_dir' + item, true); else {
httpRequest.send(); return;
}
}
else {
item = cd + item;
}
ajax('/musik/get_dir/' + item, update_nav_items);
} }
function update_nav_items() { function update_nav_items() {

View File

@ -18,8 +18,8 @@
</ul> </ul>
</div> </div>
<div id="playerContainer"> <div id="playerContainer">
<div id="albumCover"><img src="/musik/album_cover{{ initial_cover }}"/></div> <span id="albumCover"><img src="/musik/album_cover{{ initial_cover }}"/></span>
<div id="playerControls"> <span id="playerControls">
<h3 id="nowPlaying">{{ initial_track }}</h3> <h3 id="nowPlaying">{{ initial_track }}</h3>
<audio id="player" controls> <audio id="player" controls>
<source id="stream" src="{{ url_for('stream', track=initial_track) }}" type="audio/ogg"> <source id="stream" src="{{ url_for('stream', track=initial_track) }}" type="audio/ogg">
@ -28,7 +28,7 @@
<input type="checkbox" name="shuffle" id="shuffle" checked="true"> <input type="checkbox" name="shuffle" id="shuffle" checked="true">
<label for="shuffle">Shuffle</label> <label for="shuffle">Shuffle</label>
</div> </div>
</div> </span>
</div> </div>
</div> </div>
</body> </body>