prolefeeder/prolefeeder.py

129 lines
4.2 KiB
Python
Raw Normal View History

from flask import (Flask, render_template, flash, redirect,
2019-03-06 20:19:10 +01:00
url_for, request, send_from_directory, abort)
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
2018-11-12 00:06:36 +01:00
from wtforms import DateTimeField, IntegerField, SubmitField
2018-11-12 14:36:42 +01:00
from wtforms.validators import InputRequired, NumberRange
from datetime import datetime, timedelta
from tempfile import mkstemp
2018-11-11 19:55:57 +01:00
import os
import random
import re
import subprocess
2019-03-06 20:19:10 +01:00
import time
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
2018-11-14 19:07:23 +01:00
app.config['WTF_I18N_ENABLED'] = False # enables WTForms built-in translations
bootstrap = Bootstrap(app)
download_filenames = {}
2018-11-12 23:21:15 +01:00
class DownloadForm(FlaskForm):
2018-11-14 19:07:23 +01:00
class Meta:
locales = ['de_DE', 'de']
2018-11-13 15:13:11 +01:00
start_time = DateTimeField('Startzeit',
2018-11-12 14:38:48 +01:00
validators=[InputRequired()],
2018-11-13 22:23:18 +01:00
format='%d.%m.%Y %H:%M')
2018-11-13 15:13:11 +01:00
length = IntegerField('Länge',
2018-11-12 14:38:48 +01:00
validators=[
InputRequired(),
NumberRange(
min=1, max=app.config['MAX_LENGTH'],
message="Länge muss zwischen %(min)s and %(max)s Minuten sein")])
submit = SubmitField('Download')
@app.route('/', methods=['GET', 'POST'])
def download():
form = DownloadForm()
if request.method == 'GET':
2018-11-11 16:53:41 +01:00
form.start_time.data = datetime.now().replace(minute=0, second=0) - timedelta(hours=1)
form.length.data = 60
elif form.validate_on_submit():
2018-11-12 14:36:19 +01:00
try:
output_filename, download_filename = prepare_download(form)
download_filenames[output_filename] = download_filename
2018-11-13 15:13:11 +01:00
flash('Der Download sollte sofort starten.', 'success')
return render_template('download.html', form=form, filename=output_filename)
2018-11-12 14:36:19 +01:00
except ValueError as e:
2018-11-13 15:13:11 +01:00
flash('Fehler beim Erstellen des Downloads: {}'.format(e), 'warning')
else:
2018-11-13 15:13:11 +01:00
flash('Fehler im Formular!', 'warning')
return render_template('download.html', form=form)
2019-03-06 20:19:10 +01:00
def clean_out_dir():
"""Clean up OUT_DIR"""
for fn in os.listdir(app.config['OUT_DIR']):
if not fn.startswith('prolefeeder'):
continue
creation_time = os.path.getctime(os.path.join(app.config['OUT_DIR'], fn))
if time.time() - creation_time >= 60:
os.unlink(os.path.join(app.config['OUT_DIR'], fn))
2018-11-12 08:22:27 +01:00
@app.route('/download_file/<filename>')
def download_file(filename):
"""Download an output file"""
if filename not in download_filenames:
abort(404)
download_filename = download_filenames.pop(filename)
2019-03-06 20:19:10 +01:00
clean_out_dir()
2019-03-06 20:19:10 +01:00
return send_from_directory(app.config['OUT_DIR'], filename,
download_name=download_filename, as_attachment=True)
2018-11-11 13:56:51 +01:00
def prepare_download(form):
2018-11-11 19:55:57 +01:00
"""Prepare a download given the user's request form"""
# Get a sorted list of all source files with start time and length
sources = sorted(Config.SOURCES, key=lambda s: s['start_time'])
print(sources)
2018-11-11 19:55:57 +01:00
# Only interested in the source files from the start file
start_index = None
for i, source in enumerate(sources):
if source['start_time'] <= form.start_time.data < source['start_time'] + source['length']:
start_index = i
if start_index is None:
2018-11-13 15:13:11 +01:00
raise ValueError('Konnte Startdatei nicht finden!')
2018-11-11 19:55:57 +01:00
sources = sources[start_index:]
2018-11-12 15:22:09 +01:00
# Super lazy: Limit to 5 source files input
sources = sources[:5]
2018-11-11 19:55:57 +01:00
# Seek into the first file
ss = (form.start_time.data - sources[0]['start_time']).total_seconds()
# Let ffmpeg do the rest of the job
2019-03-06 20:19:10 +01:00
_, output_filename = mkstemp(prefix='prolefeeder', suffix='.mp3', dir=app.config['OUT_DIR'])
output_filename = os.path.basename(output_filename)
download_filename = '{}_{}.mp3'.format(form.start_time.data, form.length.data)
2018-11-11 19:55:57 +01:00
2018-11-12 23:36:07 +01:00
c = [
'ffmpeg', '-y',
'-ss', str(ss),
'-i', 'concat:' + '|'.join(s['fn'] for s in sources),
2018-11-12 23:36:07 +01:00
'-codec', 'copy',
'-t', str(form.length.data * 60),
2019-03-06 20:19:10 +01:00
os.path.join(app.config['OUT_DIR'], output_filename)
2018-11-12 23:36:07 +01:00
]
2018-11-11 19:55:57 +01:00
app.logger.debug(' '.join(c))
subprocess.call(c)
return output_filename, download_filename
2018-11-11 13:56:51 +01:00
if __name__ == '__main__':
app.run(debug=True)