diff options
Diffstat (limited to 'patternutils/commands/tmv.py')
| -rw-r--r-- | patternutils/commands/tmv.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/patternutils/commands/tmv.py b/patternutils/commands/tmv.py index e69de29..145a261 100644 --- a/patternutils/commands/tmv.py +++ b/patternutils/commands/tmv.py @@ -0,0 +1,90 @@ +import json +import os.path +import shutil + +import click + +from .. import template +from .. import config + + +def move_file(old_filename: str, new_filename: str) -> None: + # Create new directories if needed + dirs = os.path.dirname(new_filename) + if dirs: + os.makedirs(dirs, exist_ok=True) + + shutil.move(old_filename, new_filename) + + +@click.command(context_settings={'help_option_names': ('-h', '--help', '-?')}) +@click.option('-i', '--interactive', is_flag=True, default=False, + help='prompt before renaming files') +@click.option('-f', '--force', is_flag=True, default=False, + help='force rename') +@click.option('-t', '--template-engine', default='python', type=click.Choice(['python', 'jinja2']), + help='select the template engine to use') +@click.option('-p', '--use-predefined-template', is_flag=True, default=False, + help='use predefined template') +@click.option('--read-from', default='-', type=click.File('r')) +@click.option('--abort-on-path-exist', is_flag=True, default=False, + help='exit if a renamed path already exists') +@click.option('-n', '--dry-run', is_flag=True, default=False, + help='perform a trial run with no changes made') +@click.option('-v', '--verbose', is_flag=True, default=False, + help='explain what is being done') +@click.version_option() +@click.argument('output-pattern') +def tmv( + output_pattern: str, + interactive: bool, + force: bool, + template_engine: str, + abort_on_path_exist: bool, + use_predefined_template: bool, + read_from: click.File, + dry_run: bool, + verbose: bool, +) -> None: + + try: + data = json.load(read_from) # type: ignore + except json.JSONDecodeError: + click.secho('JSON not valid!', fg='red', err=True) + raise SystemExit + + if use_predefined_template: + output_pattern, template_engine = config.load_template(output_pattern, 'tmv') + + try: + render = template.get_render_function(output_pattern, engine=template_engine) + except RuntimeError: + click.secho('jinja2 not installed!', fg='red', err=True) + raise SystemExit + + new_filenames = dict((entry['_abspath'], render(**entry)) for entry in data) + + has_existing = False + non_existing = {} + for old, new in new_filenames.items(): + if os.path.exists(new): + click.secho('{} does exist!'.format(new), fg='red', err=True) + has_existing = True + else: + non_existing[old] = new + + if has_existing and abort_on_path_exist: + raise SystemExit + + if force: + files_to_move = new_filenames.items() + else: + files_to_move = non_existing.items() + + for old, new in files_to_move: + if verbose or interactive: + click.echo('{} -> {}'.format(old, new)) + + if not (interactive and not click.confirm('Is the match correct?')): + if not dry_run: + move_file(old, new) |
