diff --git a/m4b/cli.py b/m4b/cli.py index 034da7f..6c81f88 100644 --- a/m4b/cli.py +++ b/m4b/cli.py @@ -3,6 +3,9 @@ import os, sys, subprocess, shutil, logging, argparse, dataclasses, collections, pprint, typing, pathlib, zipfile, mimetypes import xml.etree.ElementTree as ET from datetime import datetime as dt +from importlib.metadata import version + +__version__ = version('m4b') import mutagen @@ -57,13 +60,15 @@ class Cli: def get_parser(self): self.parser = argparse.ArgumentParser() self.parser.add_argument("input", type=str, help="input directory or file") - self.parser.add_argument("-g","--glob", type=str, nargs=1, help="Glob pattern in input folder. See pathlib documentation.") + self.parser.add_argument('--version', action='version', version=f"%(prog)s {__version__}") + self.parser.add_argument("-g","--glob", type=str, nargs=1, default="*", help="Glob pattern in input folder. See pathlib documentation.") self.parser.add_argument("-m", "--mode", type=str, choices=['single', 'multi'], help="Input format (single book from epub file or an entire directory tree, or multiple books from each subfolder or epub file") self.parser.add_argument("-o","--output", type=str, help="output directory") self.parser.add_argument("--debug", dest="loglevel", action="store_const",const="DEBUG", help="Set log level to DEBUG") self.parser.add_argument("--extract", action="store_true", help="Extract file if compressed archive") self.parser.add_argument("--extract-only-audio", action="store_true", help="Only extract audio from compressed file (default: False)") self.parser.add_argument("--chapters", action="store_true", help="Parse chapters from epub file") + self.parser.add_argument("--cleanup", action=argparse.BooleanOptionalAction, help="Parse chapters from epub file") return self.parser @@ -79,35 +84,18 @@ class Cli: self.info(self.args) # Input - input_path = pathlib.Path(self.args['input']) - if not input_path.exists(): - self.error("Invalid input dir: '%s'", self.args['input']) - self.exit(1) - if input_path.is_dir(): - self.merge_input = input_path.resolve() - elif zipfile.is_zipfile(input_path): - self.tmp_dir = input_path.with_name(input_path.name + self.tmp_suffix) - if self.args['extract']: - self.extract_input(input_path) - self.merge_input = self.tmp_dir - - if self.args['chapters']: - self.parse_chapters(self.tmp_dir) - - else: - self.error("Invalid input dir: '%s'", self.args['input']) - self.exit(1) + self.input_path = pathlib.Path(self.args['input']) # Output if not self.args['output']: - output_path = input_path.parent - output_name = input_path.with_suffix(".m4b").name + self.output_path = self.input_path.parent + self.output_name = self.input_path.with_suffix(".m4b").name else: - output_path = pathlib.Path(self.args['output']) - if output_path.suffix == ".m4b": - output_name = output_path.name - output_path = output_path.parent - self.merge_output = output_path.resolve() / output_name + self.output_path = pathlib.Path(self.args['output']) + if self.output_path.suffix == ".m4b": + self.output_name = self.output_path.name + self.output_path = self.output_path.parent + self.outfile = self.output_path / self.output_name return self.args @@ -236,8 +224,41 @@ class Cli: def debug(self, msg, *args): self.log(logging.DEBUG, msg, *args) + def run(self): + if not self.input_path.exists(): + self.error("Invalid input dir: '%s'", self.args['input']) + self.exit(1) - def run(self, cmd): + if not self.input_path.is_dir() and zipfile.is_zipfile(self.input_path): + self.tmp_dir = self.input_path.with_name(self.input_path.name + self.tmp_suffix) + if self.args['extract']: + self.extract_input(self.input_path) + + if self.args['chapters']: + self.parse_chapters(self.tmp_dir) + + self.input_path = self.tmp_dir/"audio" + else: + self.error("Invalid input: '%s'", self.args['input']) + self.exit(1) + + self.merge_input = [] + for file in self.input_path.glob(self.args['glob']): + if self.supported(file): + self.merge_input.append(file) + self.info("Merging files: %s", ", ".join([str(p) for p in self.merge_input])) + + m4b_return = self.runcmd([config.m4b.path] + config.m4b.flags + + ["merge", "-o", config.outfile, config.merge_input]) + + if self.args['cleanup']: + try: + self.tmp_dir.unlink() + except OSError as e: + self.error("Error removing '%s': %s", self.tmp_dir, e) + + + def runcmd(self, cmd): if not cmd: self.error("Empty cmd") return 1 @@ -315,10 +336,6 @@ class Cli: audiopath.move(newpath) -def cli(): - Cli().run([config.m4b.path] + config.m4b.flags + - ["merge", "-o", config.merge_output, config.merge_input]) - if __name__ == "__main__": - sys.exit(cli()) + sys.exit(Cli().run())