diff --git a/larigira/audiogen_randomdir.py b/larigira/audiogen_randomdir.py index 2453210..fdd99f7 100644 --- a/larigira/audiogen_randomdir.py +++ b/larigira/audiogen_randomdir.py @@ -3,11 +3,25 @@ import logging import shutil import random from tempfile import mkstemp +from pathlib import Path -from larigira.fsutils import scan_dir, shortname +from larigira.fsutils import scan_dir_audio, shortname, is_audio log = logging.getLogger(__name__) +def candidates(paths): + c = set() + for path in paths: + if not path.exists(): + log.warning("Can't find requested path: %s", path) + continue + if path.is_file() and is_audio(str(path)): + c.add(str(path)) + elif path.is_dir(): + c.update(scan_dir_audio(str(path))) + return c + + def generate(spec): ''' resolves audiospec-randomdir @@ -21,18 +35,12 @@ def generate(spec): if attr not in spec: raise ValueError("Malformed audiospec: missing '%s'" % attr) - found_files = set() - for path in spec['paths']: - if not os.path.exists(path): - log.warning("Can't find requested path: %s", path) - continue - if os.path.isfile(path): - found_files.add(path) - elif os.path.isdir(path): - found_files.update(scan_dir(path)) + found_files = candidates([Path(p) for p in spec['paths']]) picked = random.sample(found_files, int(spec['howmany'])) + # TODO: use specnick + nick = spec.get('nick', spec.eid) for path in picked: tmp = mkstemp(suffix=os.path.splitext(path)[-1], prefix='randomdir-%s-' % shortname(path)) diff --git a/larigira/fsutils.py b/larigira/fsutils.py index 6501e21..0cdbf41 100644 --- a/larigira/fsutils.py +++ b/larigira/fsutils.py @@ -1,5 +1,6 @@ import os import fnmatch +import mimetypes def scan_dir(dirname, extension=None): @@ -17,10 +18,15 @@ def multi_fnmatch(fname, extensions): return False +def is_audio(fname): + mimetype = mimetypes.guess_type(fname)[0] + return mimetype.split('/')[0] == 'audio' + + 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): + if is_audio(fname): yield os.path.join(root, fname) diff --git a/larigira/tests/test_audiogen_randomdir.py b/larigira/tests/test_audiogen_randomdir.py index 36c92fe..95944ae 100644 --- a/larigira/tests/test_audiogen_randomdir.py +++ b/larigira/tests/test_audiogen_randomdir.py @@ -1,18 +1,45 @@ -from gevent import monkey -monkey.patch_all(subprocess=True) +from pathlib import Path -import pytest - -from larigira.audiogen_randomdir import generate +from larigira.audiogen_randomdir import candidates -@pytest.fixture -def simplerandom(): - return { - 'paths': '/tmp/do/not/exist', - } +def P(pypathlocal): + return Path(str(pypathlocal)) -def test_accepted_syntax(simplerandom): - '''Check the minimal needed configuration for randomdir''' - generate(simplerandom) +def test_txt_files_are_excluded(tmpdir): + p = tmpdir.join("foo.txt") + p.write('') + assert len(candidates([P(p)])) == 0 + assert len(candidates([P(tmpdir)])) == 0 + + +def test_nested_txt_files_are_excluded(tmpdir): + p = tmpdir.mkdir('one').mkdir('two').join("foo.txt") + p.write('') + assert len(candidates([P(p)])) == 0 + assert len(candidates([P(tmpdir)])) == 0 + + +def test_mp3_files_are_considered(tmpdir): + p = tmpdir.join("foo.mp3") + p.write('') + assert len(candidates([P(p)])) == 1 + assert len(candidates([P(tmpdir)])) == 1 + + +def test_nested_mp3_files_are_considered(tmpdir): + p = tmpdir.mkdir('one').mkdir('two').join("foo.mp3") + p.write('') + assert len(candidates([P(p)])) == 1 + assert len(candidates([P(tmpdir)])) == 1 + + +def test_same_name(tmpdir): + '''file with same name on different dir should not be confused''' + p = tmpdir.mkdir('one').mkdir('two').join("foo.mp3") + p.write('') + p = tmpdir.join("foo.mp3") + p.write('') + + assert len(candidates([P(tmpdir)])) == 2