Add parse/rename CLI options

This commit is contained in:
Maks Snegov 2022-02-09 18:08:06 +03:00
parent 2204a3a2c3
commit ae47d476f3

View File

@ -2,9 +2,11 @@
import argparse
import collections
import enum
import logging
import os
import os.path
import pprint
import re
import sys
@ -42,12 +44,48 @@ PATTERNS = (
("unknown", r".*")
)
# noinspection PyInterpreter
class EnumAction(argparse.Action):
"""
Argparse action for handling Enums
"""
def __init__(self, **kwargs):
# Pop off the type value
enum_type = kwargs.pop("type", None)
# Ensure an Enum subclass is provided
if enum_type is None:
raise ValueError("type must be assigned an Enum when using EnumAction")
if not issubclass(enum_type, enum.Enum):
raise TypeError("type must be an Enum when using EnumAction")
# Generate choices from the Enum
kwargs.setdefault("choices", tuple(e.value for e in enum_type))
super(EnumAction, self).__init__(**kwargs)
self._enum = enum_type
def __call__(self, parser, namespace, values, option_string=None):
# Convert value back into an Enum
value = self._enum(values)
setattr(namespace, self.dest, value)
class CliAction(enum.Enum):
parse = "parse"
rename = "rename"
_lg = logging.getLogger("spqr.movie-renamer")
def main():
parser = argparse.ArgumentParser(description="Rename media files.")
parser.add_argument("target", type=str,
parser.add_argument("action", type=CliAction, action=EnumAction, metavar="ACTION",
help="what to do with media file/directory (%(choices)s)")
parser.add_argument("target", type=str, metavar="TARGET",
help="path to the media file/directory")
parser.add_argument("-v", "--verbose", action="store_true", default=False,
help="verbose output")
@ -56,23 +94,41 @@ def main():
loglevel = logging.DEBUG if args.verbose else logging.INFO
logging.basicConfig(level=loglevel)
if os.path.isdir(args.target):
process_dir(args.target)
else:
process_file(args.target)
process_path(args.action, args.target)
return 0
def process_dir(dir_path):
"""
Process dir with media files.
If this dir is season of some tv show -> process them as season.
Otherwise -> process each file individually.
"""
for fname in os.listdir(dir_path):
fpath = os.path.join(dir_path, fname)
process_file(fpath)
def process_path(action: CliAction, path):
# process only files
if os.path.isdir(path):
for child_path in sorted(os.listdir(path)):
process_path(action, os.path.join(path, child_path))
# split filepath to dir path, title, and extension
dir_path, fname = os.path.split(path)
title, ext = os.path.splitext(fname)
ext = ext[1:]
if ext not in PROCESSED_FILETYPES:
_lg.debug("Extension is not supported: %s", path)
return
parsed_title = parse_title(title)
if action == CliAction.parse:
print_parsed_title(title, parsed_title)
return
if action == CliAction.rename:
pretty_title = generate_pretty_name(parsed_title)
pretty_title += ".%s" % ext
if pretty_title != fname:
_lg.warning("%s -> %s", fname, pretty_title)
return
def print_parsed_title(title, parsed):
print(title)
pprint.pprint(parsed, indent=4)
def generate_pretty_name(parsed_title):
@ -91,28 +147,6 @@ def generate_pretty_name(parsed_title):
return result
def process_file(fpath):
# process only files
if not os.path.isfile(fpath):
_lg.debug("Not a file: %s", fpath)
return
# split filepath to dir path, title, and extension
dir_path, fname = os.path.split(fpath)
title, ext = os.path.splitext(fname)
ext = ext[1:]
if ext not in PROCESSED_FILETYPES:
_lg.debug("Extension is not supported: %s", fpath)
return
parsed_title = parse_title(title)
pretty_title = generate_pretty_name(parsed_title)
pretty_title += ".%s" % ext
if pretty_title != fname:
_lg.warning("%s -> %s", fname, pretty_title)
def _get_parsed_title_dict(chunk_list, chunk_map):
""" Get {chunk_type: [chunk_value_1, ..., chunk_value_n]} dictionary. """
p_title = collections.defaultdict(list)