You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
prolefeeder/prolefeeder.py

105 lines
3.5 KiB
Python

from flask import (Flask, render_template, flash, redirect,
url_for, request, send_from_directory)
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import DateTimeField, DecimalField, SubmitField
6 years ago
from wtforms.validators import DataRequired, NumberRange
from datetime import datetime, timedelta
import os
import random
import re
import subprocess
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
Bootstrap(app)
class DownloadForm(FlaskForm):
start_time = DateTimeField('Start time', validators=[DataRequired()], id='start_time')
6 years ago
length = DecimalField('Length', validators=[DataRequired(),
NumberRange(min=1, max=app.config['MAX_LENGTH'])])
submit = SubmitField('Download')
@app.route('/', methods=['GET', 'POST'])
def download():
form = DownloadForm()
if request.method == 'GET':
form.start_time.data = datetime.now().replace(minute=0, second=0) - timedelta(hours=1)
form.length.data = 60
elif form.validate_on_submit():
output_filename = prepare_download(form)
if output_filename:
flash('The download should start immediately.', 'success')
return render_template('download.html', form=form, filename=output_filename)
else:
flash('Error preparing download!', 'warning')
else:
flash('Error in form!', 'warning')
return render_template('download.html', form=form)
@app.route('/download_file/<path:filename>')
def download_file(filename):
return send_from_directory(app.config['DATA_DIR'], filename,
as_attachment=True)
6 years ago
def prepare_download(form):
"""Prepare a download given the user's request form"""
def start_time_for_source_fn(fn):
return datetime.strptime(fn, 'qfhi-%Y%m%d-%H%M.mp3')
def length_for_source_fn(fn):
size = os.stat(os.path.join(app.config['DATA_DIR'], fn)).st_size
length = timedelta(minutes=size / (1000*app.config['KBITS']/8) / 60)
return length
# Get a sorted list of all source files with start time and length
sources = []
for fn in os.listdir(app.config['DATA_DIR']):
try:
start_time = start_time_for_source_fn(fn)
length = length_for_source_fn(fn)
sources.append({'fn': fn, 'start_time': start_time, 'length': length})
except ValueError:
pass
sources = sorted(sources, key=lambda s: s['start_time'])
# 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
sources = sources[start_index:]
# Seek into the first file
ss = (form.start_time.data - sources[0]['start_time']).total_seconds()
# Let ffmpeg do the rest of the job
# XXX Necessary to limit the concat files?
output_filename = '{}_{}.mp3'.format(form.start_time.data, form.length.data)
c = ['ffmpeg', '-y']
c += ['-ss', str(ss)]
c += ['-i', 'concat:' + '|'.join([os.path.join(app.config['DATA_DIR'],
source['fn']) for source in sources])]
c += ['-codec', 'copy']
c += ['-t', str(form.length.data * 60)]
c += [os.path.join(app.config['DATA_DIR'], output_filename)]
app.logger.debug(' '.join(c))
subprocess.call(c)
return output_filename
6 years ago
if __name__ == '__main__':
app.run(debug=True)