From e129d249688a057a9a0573f1a0b14d325385c22b Mon Sep 17 00:00:00 2001 From: boyska Date: Tue, 3 Jan 2017 19:22:49 +0100 Subject: [PATCH] refactoring: scan_dir moved to fsutils --- larigira/audioform_static.py | 7 +++-- larigira/audiogen_mostrecent.py | 9 +----- larigira/audiogen_randomdir.py | 9 +----- larigira/config.py | 1 + larigira/dbadmin/__init__.py | 28 ++++++++++++++++++- .../dbadmin/templates/add_audio_kind.html | 5 ++++ larigira/formutils.py | 23 +++++++++++++++ larigira/fsutils.py | 24 ++++++++++++++++ larigira/rpc.py | 2 ++ 9 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 larigira/formutils.py create mode 100644 larigira/fsutils.py diff --git a/larigira/audioform_static.py b/larigira/audioform_static.py index b172c8f..21c9449 100644 --- a/larigira/audioform_static.py +++ b/larigira/audioform_static.py @@ -3,12 +3,15 @@ from __future__ import print_function from flask_wtf import Form from wtforms import StringField, validators, SubmitField +from larigira.formutils import AutocompleteStringField + class StaticAudioForm(Form): nick = StringField('Audio nick', validators=[validators.required()], description='A simple name to recognize this audio') - path = StringField('Path', validators=[validators.required()], - description='Full path to audio file') + path = AutocompleteStringField('dl-suggested-files', + 'Path', validators=[validators.required()], + description='Full path to audio file') submit = SubmitField('Submit') def populate_from_audiospec(self, audiospec): diff --git a/larigira/audiogen_mostrecent.py b/larigira/audiogen_mostrecent.py index f0b8194..2df0d2b 100644 --- a/larigira/audiogen_mostrecent.py +++ b/larigira/audiogen_mostrecent.py @@ -3,17 +3,10 @@ import logging import shutil import time from tempfile import mkstemp -import fnmatch from pytimeparse.timeparse import timeparse - -def scan_dir(dirname, extension=None): - if extension is None: - extension = '*' - for root, dirnames, filenames in os.walk(dirname): - for fname in fnmatch.filter(filenames, extension): - yield os.path.join(root, fname) +from larigira.fsutils import scan_dir def get_mtime(fname): diff --git a/larigira/audiogen_randomdir.py b/larigira/audiogen_randomdir.py index 2d6ac10..3a75ccf 100644 --- a/larigira/audiogen_randomdir.py +++ b/larigira/audiogen_randomdir.py @@ -3,15 +3,8 @@ import logging import shutil import random from tempfile import mkstemp -import fnmatch - -def scan_dir(dirname, extension=None): - if extension is None: - extension = '*' - for root, dirnames, filenames in os.walk(dirname): - for fname in fnmatch.filter(filenames, extension): - yield os.path.join(root, fname) +from larigira.fsutils import scan_dir def generate(spec): diff --git a/larigira/config.py b/larigira/config.py index df6b3fa..8c8031a 100644 --- a/larigira/config.py +++ b/larigira/config.py @@ -28,6 +28,7 @@ def get_conf(prefix='LARIGIRA_'): conf['DEBUG'] = False conf['LOG_CONFIG'] = False conf['TMPDIR'] = os.getenv('TMPDIR', '/tmp/') + conf['FILE_PATH_SUGGESTION'] = () # tuple of paths conf.update(from_envvars(prefix=prefix)) return conf diff --git a/larigira/dbadmin/__init__.py b/larigira/dbadmin/__init__.py index 1448033..26d4f61 100644 --- a/larigira/dbadmin/__init__.py +++ b/larigira/dbadmin/__init__.py @@ -5,6 +5,8 @@ Templates are self-contained in this directory ''' from __future__ import print_function +import os + from flask import current_app, Blueprint, render_template, jsonify, abort, \ request, redirect, url_for @@ -12,6 +14,8 @@ from larigira.entrypoints_utils import get_avail_entrypoints from larigira.audiogen import get_audiogenerator from larigira.timegen import get_timegenerator from larigira import forms +from larigira.config import get_conf +from larigira.fsutils import scan_dir_audio db = Blueprint('db', __name__, url_prefix='/db', template_folder='templates') @@ -19,6 +23,26 @@ def get_model(): return current_app.larigira.controller.monitor.model +def get_suggested_files(): + if not get_conf()['FILE_PATH_SUGGESTION']: + return [] + if current_app.cache.has('dbadmin.get_suggested_files'): + return current_app.cache.get('dbadmin.get_suggested_files') + current_app.logger.debug('get_suggested_files MISS in cache') + files = [] + for path in get_conf()['FILE_PATH_SUGGESTION']: + if not os.path.isdir(path): + current_app.logger.warn('Invalid suggestion path: %s' % path) + continue + pathfiles = scan_dir_audio(path) + files.extend(pathfiles) + current_app.logger.debug('Suggested files: %s' % ', '.join(files)) + + current_app.cache.set('dbadmin.get_suggested_files', files, + timeout=600) # ten minutes + return files + + @db.route('/') def home(): return render_template('dbadmin_base.html') @@ -99,7 +123,8 @@ def addaudio_kind(kind): eid = model.add_action(data) return jsonify(dict(inserted=eid, data=data)) - return render_template('add_audio_kind.html', form=form, kind=kind) + return render_template('add_audio_kind.html', form=form, kind=kind, + suggested_files=get_suggested_files()) @db.route('/edit/audio/', methods=['GET', 'POST']) @@ -120,6 +145,7 @@ def edit_audio(actionid): form=form, kind=kind, mode='edit', + suggested_files=get_suggested_files() ) diff --git a/larigira/dbadmin/templates/add_audio_kind.html b/larigira/dbadmin/templates/add_audio_kind.html index 6b3b4ce..c1f1722 100644 --- a/larigira/dbadmin/templates/add_audio_kind.html +++ b/larigira/dbadmin/templates/add_audio_kind.html @@ -10,6 +10,11 @@ resubmit {% endif %} + + {% for fname in suggested_files %} +
{{wtf.quick_form(form)}}
diff --git a/larigira/formutils.py b/larigira/formutils.py new file mode 100644 index 0000000..c3b93e1 --- /dev/null +++ b/larigira/formutils.py @@ -0,0 +1,23 @@ +from wtforms.fields import StringField +import wtforms.widgets + + +class AutocompleteTextInput(wtforms.widgets.Input): + def __init__(self, datalist=None): + super().__init__('text') + self.datalist = datalist + + def __call__(self, field, **kwargs): + # every second can be specified + if self.datalist is not None: + return super(AutocompleteTextInput, self).__call__( + field, list=self.datalist, autocomplete="autocomplete", + **kwargs) + return super(AutocompleteTextInput, self).__call__( + field, **kwargs) + + +class AutocompleteStringField(StringField): + def __init__(self, datalist, *args, **kwargs): + super().__init__(*args, **kwargs) + self.widget = AutocompleteTextInput(datalist) diff --git a/larigira/fsutils.py b/larigira/fsutils.py new file mode 100644 index 0000000..0b38c6f --- /dev/null +++ b/larigira/fsutils.py @@ -0,0 +1,24 @@ +import os +import fnmatch + + +def scan_dir(dirname, extension=None): + if extension is None: + extension = '*' + for root, dirnames, filenames in os.walk(dirname): + for fname in fnmatch.filter(filenames, extension): + yield os.path.join(root, fname) + + +def multi_fnmatch(fname, extensions): + for ext in extensions: + if fnmatch.fnmatch(fname, '*.' + ext): + return True + return False + + +def scan_dir_audio(dirname, extensions=('mp3', 'oga', 'wav', 'ogg')): + for root, dirnames, filenames in os.walk(dirname): + for fname in filenames: + if multi_fnmatch(fname, extensions): + yield os.path.join(root, fname) diff --git a/larigira/rpc.py b/larigira/rpc.py index 43fee23..4a2904c 100644 --- a/larigira/rpc.py +++ b/larigira/rpc.py @@ -6,6 +6,7 @@ from greenlet import greenlet from flask import current_app, Blueprint, Flask, jsonify, render_template, \ request, abort from flask_bootstrap import Bootstrap +from werkzeug.contrib.cache import SimpleCache from .dbadmin import db from .config import get_conf @@ -179,4 +180,5 @@ def create_app(queue, larigira): app.register_blueprint(db) app.queue = queue app.larigira = larigira + app.cache = SimpleCache() return app