Add parse/rename CLI options
This commit is contained in:
parent
2204a3a2c3
commit
ae47d476f3
106
renamer.py
106
renamer.py
@ -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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user