create output files as temporary files and remove them before sending

stable
neingeist 6 years ago
parent 887d99f587
commit 6348b0f6d9

1
.gitignore vendored

@ -1,4 +1,3 @@
__pycache__/ __pycache__/
*.pyc *.pyc
config.py config.py
tmp/

@ -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__':

Loading…
Cancel
Save