From ac52f9d642ff07eeb34eb7a923ddc3be04d9060a Mon Sep 17 00:00:00 2001 From: Xevion Date: Sat, 29 Aug 2020 13:11:06 -0500 Subject: [PATCH] greatly improved file selection with directory/regex/glob selection options, add main.py for no-install testing purposes --- main.py | 10 +++++++ phototag/cli.py | 70 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..2984dfa --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ +""" +main.py + +Main function for running/testing the application without installing repeatedly. +""" + +from phototag import cli + +if __name__ == '__main__': + cli.cli() diff --git a/phototag/cli.py b/phototag/cli.py index 507b7d2..98a7621 100644 --- a/phototag/cli.py +++ b/phototag/cli.py @@ -6,13 +6,18 @@ The file responsible for providing commandline functionality to the user. import logging import os +import re import shutil +from typing import Tuple +from glob import glob import click -from . import config +from . import config, INPUT_PATH +from .helpers import get_extension, valid_extension -log = logging.getLogger("cli") +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) @click.group() @@ -21,17 +26,52 @@ def cli(): pass -@cli.command() -def run(): - """Run tagging of all valid files in the current directory.""" - log.info(f"CLI started tagging at {os.getcwd()}") - from .app import run +@cli.command('run', short_help='Run the tagging service.') +@click.argument('files', nargs=-1, type=click.Path(exists=True)) +@click.option('-a', '--all', is_flag=True, help='Add all files in the current directory to be tagged.') +@click.option('-r', '--regex', help='Use RegEx to match files in the current directory') +@click.option('-g', '--glob', 'glob_pattern', help='Use Glob (UNIX-style file pattern matching) to match files.') +def run(files: Tuple[str], all: bool = False, regex: str = None, glob_pattern: str = None): + """ + Run tagging on FILES. - run() + Files can also be selected using --all, --regex and --glob. + + """ + files = list(files) + + # Just add all files in current working directory + if all: + files.extend(os.listdir(INPUT_PATH)) + else: + # RegEx option pattern matching + if regex: + files.extend( + filter(lambda filename: re.match(re.compile(regex), filename) is not None, os.listdir(INPUT_PATH)) + ) + + # Glob option pattern matching + if glob_pattern: + files.extend(glob(glob_pattern)) + + files = list(dict.fromkeys(os.path.relpath(file) for file in files)) + select = list(filter(lambda filename: valid_extension(get_extension(filename)), files)) + if len(select) == 0: + if len(files) == 0: + logger.info('No files selected.') + else: + logger.info('No valid images selected.') + else: + logger.debug(f'{len(select)} valid images out of {len(files)} files selected.') + + print(files) + # from .app import run + # + # run() -@cli.command() -@click.argument("path") +@cli.command('auth') +@click.argument("path", type=click.Path(exists=True)) @click.option("-m", "--move", default=False, show_default=True, prompt=True, help="Move instead of copying the credentials file", ) def auth(path, move): @@ -46,9 +86,9 @@ def auth(path, move): # Verify that the file exists if not os.path.isfile(path): if os.path.isdir(path): - log.warning("The specified path is a directory, not a file.") + logger.warning("The specified path is a directory, not a file.") else: - log.warning("The specified path does not exist.") + logger.warning("The specified path does not exist.") else: # Identify the final location of the file in the config directory _, head = os.path.split(path) @@ -57,13 +97,13 @@ def auth(path, move): # Move or copy the file if move: shutil.move(path, new_path) - log.info("Successfully moved file to configuration file...") + logger.info("Successfully moved file to configuration file...") elif not move: shutil.copy(path, new_path) - log.info("Successfully copied file to configuration folder...") + logger.info("Successfully copied file to configuration folder...") # Update the configuration file to point to the config.config["google"]["credentials"] = head config.quicksave() - log.info(f"Configuration updated.") + logger.info(f"Configuration updated.")