Просмотр исходного кода

refactoring: scan_dir moved to fsutils

boyska 7 лет назад
Родитель
Сommit
e129d24968

+ 5 - 2
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):

+ 1 - 8
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):

+ 1 - 8
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):

+ 1 - 0
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
 

+ 27 - 1
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/<int:actionid>', methods=['GET', 'POST'])
@@ -120,6 +145,7 @@ def edit_audio(actionid):
                            form=form,
                            kind=kind,
                            mode='edit',
+                           suggested_files=get_suggested_files()
                            )
 
 

+ 5 - 0
larigira/dbadmin/templates/add_audio_kind.html

@@ -10,6 +10,11 @@
 	resubmit
 </div>
 {% endif %}
+<datalist id="dl-suggested-files">
+	{% for fname in suggested_files %}
+		<option value="{{fname}}">
+	{% endfor %}
+</datalist>
 <div class="container-fluid">
 	{{wtf.quick_form(form)}}
 </div>

+ 23 - 0
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)

+ 24 - 0
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)

+ 2 - 0
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