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 argparse
import collections import collections
import enum
import logging import logging
import os import os
import os.path import os.path
import pprint
import re import re
import sys import sys
@ -42,12 +44,48 @@ PATTERNS = (
("unknown", r".*") ("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") _lg = logging.getLogger("spqr.movie-renamer")
def main(): def main():
parser = argparse.ArgumentParser(description="Rename media files.") 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") help="path to the media file/directory")
parser.add_argument("-v", "--verbose", action="store_true", default=False, parser.add_argument("-v", "--verbose", action="store_true", default=False,
help="verbose output") help="verbose output")
@ -56,23 +94,41 @@ def main():
loglevel = logging.DEBUG if args.verbose else logging.INFO loglevel = logging.DEBUG if args.verbose else logging.INFO
logging.basicConfig(level=loglevel) logging.basicConfig(level=loglevel)
if os.path.isdir(args.target): process_path(args.action, args.target)
process_dir(args.target)
else:
process_file(args.target)
return 0 return 0
def process_dir(dir_path): def process_path(action: CliAction, path):
""" # process only files
Process dir with media files. if os.path.isdir(path):
If this dir is season of some tv show -> process them as season. for child_path in sorted(os.listdir(path)):
Otherwise -> process each file individually. process_path(action, os.path.join(path, child_path))
"""
for fname in os.listdir(dir_path): # split filepath to dir path, title, and extension
fpath = os.path.join(dir_path, fname) dir_path, fname = os.path.split(path)
process_file(fpath) 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): def generate_pretty_name(parsed_title):
@ -91,28 +147,6 @@ def generate_pretty_name(parsed_title):
return result 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): def _get_parsed_title_dict(chunk_list, chunk_map):
""" Get {chunk_type: [chunk_value_1, ..., chunk_value_n]} dictionary. """ """ Get {chunk_type: [chunk_value_1, ..., chunk_value_n]} dictionary. """
p_title = collections.defaultdict(list) p_title = collections.defaultdict(list)