|
|
@ -1,11 +1,12 @@
|
|
|
|
from flask import (Flask, render_template, flash, redirect,
|
|
|
|
from flask import (Flask, render_template, flash, redirect,
|
|
|
|
url_for, request, send_from_directory)
|
|
|
|
url_for, request, send_file, abort)
|
|
|
|
from flask_bootstrap import Bootstrap
|
|
|
|
from flask_bootstrap import Bootstrap
|
|
|
|
from flask_wtf import FlaskForm
|
|
|
|
from flask_wtf import FlaskForm
|
|
|
|
from wtforms import DateTimeField, IntegerField, SubmitField
|
|
|
|
from wtforms import DateTimeField, IntegerField, SubmitField
|
|
|
|
from wtforms.validators import InputRequired, NumberRange
|
|
|
|
from wtforms.validators import InputRequired, NumberRange
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
|
|
|
|
from tempfile import mkstemp
|
|
|
|
import os
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import random
|
|
|
|
import re
|
|
|
|
import re
|
|
|
@ -18,6 +19,7 @@ app = Flask(__name__)
|
|
|
|
app.config.from_object(Config)
|
|
|
|
app.config.from_object(Config)
|
|
|
|
Bootstrap(app)
|
|
|
|
Bootstrap(app)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
attachment_filenames = {}
|
|
|
|
|
|
|
|
|
|
|
|
class DownloadForm(FlaskForm):
|
|
|
|
class DownloadForm(FlaskForm):
|
|
|
|
start_time = DateTimeField('Start time',
|
|
|
|
start_time = DateTimeField('Start time',
|
|
|
@ -38,7 +40,8 @@ def download():
|
|
|
|
form.length.data = 60
|
|
|
|
form.length.data = 60
|
|
|
|
elif form.validate_on_submit():
|
|
|
|
elif form.validate_on_submit():
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
output_filename = prepare_download(form)
|
|
|
|
output_filename, attachment_filename = prepare_download(form)
|
|
|
|
|
|
|
|
attachment_filenames[output_filename] = attachment_filename
|
|
|
|
flash('The download should start immediately.', 'success')
|
|
|
|
flash('The download should start immediately.', 'success')
|
|
|
|
return render_template('download.html', form=form, filename=output_filename)
|
|
|
|
return render_template('download.html', form=form, filename=output_filename)
|
|
|
|
except ValueError as e:
|
|
|
|
except ValueError as e:
|
|
|
@ -50,8 +53,21 @@ def download():
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/download_file/<filename>')
|
|
|
|
@app.route('/download_file/<filename>')
|
|
|
|
def download_file(filename):
|
|
|
|
def download_file(filename):
|
|
|
|
return send_from_directory(app.config['TMP_DIR'], filename,
|
|
|
|
"""Download an output file"""
|
|
|
|
as_attachment=True)
|
|
|
|
|
|
|
|
|
|
|
|
# Get attachment filename. This also makes sure that the user only downloads
|
|
|
|
|
|
|
|
# (and removes) a file generated by us.
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
attachment_filename = attachment_filenames.pop(filename)
|
|
|
|
|
|
|
|
except KeyError:
|
|
|
|
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fh = open(os.path.join(app.config['TMP_DIR'], filename), 'rb')
|
|
|
|
|
|
|
|
os.remove(os.path.join(app.config['TMP_DIR'], filename))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# XXX How to close fh?
|
|
|
|
|
|
|
|
return send_file(fh, as_attachment=True,
|
|
|
|
|
|
|
|
attachment_filename=attachment_filename)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def prepare_download(form):
|
|
|
|
def prepare_download(form):
|
|
|
@ -92,7 +108,9 @@ def prepare_download(form):
|
|
|
|
ss = (form.start_time.data - sources[0]['start_time']).total_seconds()
|
|
|
|
ss = (form.start_time.data - sources[0]['start_time']).total_seconds()
|
|
|
|
|
|
|
|
|
|
|
|
# Let ffmpeg do the rest of the job
|
|
|
|
# Let ffmpeg do the rest of the job
|
|
|
|
output_filename = '{}_{}.mp3'.format(form.start_time.data, form.length.data)
|
|
|
|
_, output_filename = mkstemp(suffix='.mp3', dir=app.config['TMP_DIR'])
|
|
|
|
|
|
|
|
output_filename = os.path.basename(output_filename)
|
|
|
|
|
|
|
|
attachment_filename = '{}_{}.mp3'.format(form.start_time.data, form.length.data)
|
|
|
|
|
|
|
|
|
|
|
|
c = ['ffmpeg', '-y']
|
|
|
|
c = ['ffmpeg', '-y']
|
|
|
|
c += ['-ss', str(ss)]
|
|
|
|
c += ['-ss', str(ss)]
|
|
|
@ -105,7 +123,7 @@ def prepare_download(form):
|
|
|
|
app.logger.debug(' '.join(c))
|
|
|
|
app.logger.debug(' '.join(c))
|
|
|
|
subprocess.call(c)
|
|
|
|
subprocess.call(c)
|
|
|
|
|
|
|
|
|
|
|
|
return output_filename
|
|
|
|
return output_filename, attachment_filename
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if __name__ == '__main__':
|
|
|
|