Source code for jfscripts.list_files

#! /usr/bin/env python3

from jfscripts import __version__
from pathlib import Path
import argparse
import fnmatch
import os
import re


[docs]def is_glob(string): if re.search(r'[\*\?]', string) or re.search(r'\[\!?.*\]', string): return True else: return False
[docs]def common_path(paths): common_path = os.path.commonpath(paths) if os.path.isdir(common_path): return common_path else: return str(Path(common_path).parent.resolve())
[docs]def _split_glob(glob_path): """Split a file path (e. g.: /data/(asterisk).txt) containing glob wildcard characters in a glob free path prefix (e. g.: /data) and a glob pattern (e. g. (asterisk).txt). :param str glob_path: A file path containing glob wildcard characters. """ globs = glob_path.split(os.path.sep) no_globs = [] for g in globs: if not is_glob(g): no_globs.append(g) else: break if not no_globs: dir_path = '.' else: dir_path = os.path.sep.join(no_globs) return ( dir_path, os.path.sep.join(globs[len(no_globs):]), )
[docs]def _list_files_all(dir_path): out = [] for root, dirs, files in os.walk(dir_path): for d in dirs: out.append(os.path.join(root, d)) for f in files: out.append(os.path.join(root, f)) out.sort() return out
[docs]def _list_files_filter(dir_path, glob_pattern): out = [] for root, dirs, files in os.walk(dir_path): relroot = root[len(dir_path):] for f in files: relfiles = os.path.join(relroot, f) if fnmatch.fnmatch(relfiles, glob_pattern): out.append(os.path.join(root, f)) out.sort() return out
[docs]def list_files(files, default_glob=None): """ :param list files: A list of file paths or a single element list containing a glob string. :param string default_glob: A default glob pattern like “(asterisk).txt”. This argument is only taken into account, if “element” is a list with only one entry and this entry is a path to a directory. """ if len(files) > 1: return files file_path = files[0] if not is_glob(file_path): if os.path.isdir(file_path): if default_glob: return _list_files_filter(file_path, default_glob) else: return _list_files_all(file_path) else: # not a directory return [file_path] else: # is glob glob_prefix, glob_pattern = _split_glob(file_path) return _list_files_filter(glob_prefix, glob_pattern) raise ValueError('Something went wrong.')
[docs]def doc_examples(command_name='', extension='txt', indent_spaces=0, inline=False): examples = ( 'a.{}'.format(extension), 'a.{0} b.{0} c.{0}'.format(extension), '(asterisk).{}'.format(extension), '"(asterisk).{}"'.format(extension), 'dir/', '"dir/(asterisk).{}"'.format(extension), ) if command_name or indent_spaces: prefix = '{}{} '.format(' ' * indent_spaces, command_name) else: prefix = '' out = [] for example in examples: command = '{}{}'.format(prefix, example) if inline: command = '“{}”'.format(command) out.append(command) if inline: join_phrase = ', ' else: join_phrase = '\n' return join_phrase.join(out)
[docs]def get_parser(): """The argument parser for the command line interface. :return: A ArgumentParser object. :rtype: argparse.ArgumentParser """ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description='This is a script to demonstrate the list_files() ' 'function in this file.\n\n' + doc_examples('list-files.py', 'txt') ) parser.add_argument( 'input_files', help='Examples for this arguments are: ' + doc_examples(inline=True), nargs='+', ) parser.add_argument( '-V', '--version', action='version', version='%(prog)s {version}'.format(version=__version__), ) return parser
[docs]def main(): args = get_parser().parse_args() files = list_files(args.input_files) if files: for f in files: print(f) else: print('Nothing found to list. :-(')
if __name__ == '__main__': main()