Forge timeout + forge from CLI

Usage is different now: you must switch to calling "cli.py serve" for
the previous "server.py" behaviour
This commit is contained in:
boyska 2013-12-23 19:58:44 +01:00
parent 19cf564aa9
commit 4c4f332f55
4 changed files with 108 additions and 51 deletions

79
server/cli.py Normal file
View file

@ -0,0 +1,79 @@
import os
import sys
from argparse import ArgumentParser, Action
from datetime import datetime
import logging
logger = logging.getLogger('cli')
import forge
from config_manager import get_config
import server
def pre_check_permissions():
import sys
def is_writable(d):
return os.access(d, os.W_OK)
if is_writable(get_config()['AUDIO_INPUT']):
yield "Audio input '%s' writable" % get_config()['AUDIO_INPUT']
if not os.access(get_config()['AUDIO_INPUT'], os.R_OK):
yield "Audio input '%s' unreadable" % get_config()['AUDIO_INPUT']
sys.exit(10)
if is_writable(os.getcwd()):
yield "Code writable"
if not is_writable(get_config()['AUDIO_OUTPUT']):
yield "Audio output '%s' not writable" % get_config()['AUDIO_OUTPUT']
sys.exit(10)
def pre_check_user():
if os.geteuid() == 0:
yield "You're running as root; this is dangerous"
class DateTimeAction(Action):
def __call__(self, parser, namespace, values, option_string=None):
if len(values) == 15:
parsed_val = datetime.strptime(values, '%Y%m%d-%H%M%S')
elif len(values) == 13:
parsed_val = datetime.strptime(values, '%Y%m%d-%H%M%S')
else:
raise ValueError("'%s' is not a valid datetime" % values)
setattr(namespace, self.dest, parsed_val)
if __name__ == "__main__":
prechecks = [pre_check_user, pre_check_permissions]
configs = ['default_config.py']
if 'TECHREC_CONFIG' in os.environ:
for conf in os.environ['TECHREC_CONFIG'].split(':'):
if not conf:
continue
path = os.path.realpath(conf)
if not os.path.exists(path):
logger.warn("Configuration file '%s' does not exist; skipping"
% path)
continue
configs.append(path)
os.chdir(os.path.dirname(os.path.realpath(__file__)))
for conf in configs:
get_config().from_pyfile(conf)
for check in prechecks:
for warn in check():
logging.warn(warn)
parser = ArgumentParser(description='creates mp3 files from live recordings')
sub = parser.add_subparsers(title='subcommands',
description='valid subcommands',
help='additional help')
serve_p = sub.add_parser('serve')
serve_p.set_defaults(func=server.main_cmd)
forge_p = sub.add_parser('forge')
forge_p.add_argument('starttime', metavar='FROM', action=DateTimeAction)
forge_p.add_argument('endtime', metavar='TO', action=DateTimeAction)
forge_p.add_argument('-o', metavar='OUTFILE', dest='outfile',
default='out.mp3', help='Path of the output mp3')
forge_p.set_defaults(func=forge.main_cmd)
options = parser.parse_args()
options.func(options)

View file

@ -1,7 +1,8 @@
OUTPUT_DIR='output'
HOST='localhost'
PORT='8000'
DEBUG=True
DB_URI='sqlite:///techrec.db'
AUDIO_OUTPUT='output/'
AUDIO_INPUT='rec/'
OUTPUT_DIR = 'output'
HOST = 'localhost'
PORT = '8000'
DEBUG = True
DB_URI = 'sqlite:///techrec.db'
AUDIO_OUTPUT = 'output/'
AUDIO_INPUT = 'rec/'
FORGE_TIMEOUT = 20

View file

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from time import sleep
import os.path
from subprocess import Popen
@ -87,10 +88,25 @@ def mp3_join(named_intervals, target):
def create_mp3(start, end, outfile, options={}, **kwargs):
p = Popen(mp3_join([(get_timefile(begin), start_cut, end_cut)
for begin, start_cut, end_cut
in get_files_and_intervals(start, end)],
outfile))
p.wait()
for begin, start_cut, end_cut
in get_files_and_intervals(start, end)],
outfile))
if get_config()['FORGE_TIMEOUT'] == 0:
p.wait()
else:
start = datetime.now()
while (datetime.now() - start).total_seconds() < \
get_config()['FORGE_TIMEOUT']:
p.poll()
if p.returncode is None:
sleep(1)
else:
break
if p.returncode is None:
raise Exception('timeout') # TODO: make a specific TimeoutError
if p.returncode != 0:
raise OSError("return code was %d" % p.returncode)
return True
def main_cmd(options):
create_mp3(options.starttime, options.endtime, options.outfile)

View file

@ -261,47 +261,8 @@ class RecServer:
callback=partial(static_file, 'tempo.html',
root='pages/'))
def pre_check_permissions():
import sys
def is_writable(d):
return os.access(d, os.W_OK)
if is_writable(get_config()['AUDIO_INPUT']):
yield "Audio input '%s' writable" % get_config()['AUDIO_INPUT']
if not os.access(get_config()['AUDIO_INPUT'], os.R_OK):
yield "Audio input '%s' unreadable" % get_config()['AUDIO_INPUT']
sys.exit(1)
if is_writable(os.getcwd()):
yield "Code writable"
if not is_writable(get_config()['AUDIO_OUTPUT']):
yield "Audio output '%s' not writable" % get_config()['AUDIO_OUTPUT']
sys.exit(1)
def pre_check_user():
if os.geteuid() == 0:
yield "You're running as root; this is dangerous"
if __name__ == "__main__":
prechecks=[pre_check_user, pre_check_permissions]
configs = ['default_config.py']
if 'TECHREC_CONFIG' in os.environ:
for conf in os.environ['TECHREC_CONFIG'].split(':'):
if not conf:
continue
path = os.path.realpath(conf)
if not os.path.exists(path):
logger.warn("Configuration file '%s' does not exist; skipping"
% path)
continue
configs.append(path)
os.chdir(os.path.dirname(os.path.realpath(__file__)))
for conf in configs:
get_config().from_pyfile(conf)
for check in prechecks:
for warn in check():
logging.warn(warn)
def main_cmd(*args):
c = RecServer()
c._app.mount('/date', DateApp())
c._app.mount('/api', RecAPI())