From da9646745cece6028ffd401d213c68371a83cb82 Mon Sep 17 00:00:00 2001 From: Renato Rosa Date: Thu, 27 Aug 2026 15:20:38 -0300 Subject: [PATCH] Atualizar m4b/cli.py --- m4b/cli.py | 110 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 43 deletions(-) diff --git a/m4b/cli.py b/m4b/cli.py index e675296..034da7f 100644 --- a/m4b/cli.py +++ b/m4b/cli.py @@ -41,20 +41,38 @@ class Cli: def __post_init__(self): self.create_logger() + self.check_tools() + self.get_parser() + self.parse_args() + + + def check_tools(self, tool): for tool_name in [f.name for f in dataclasses.fields(self) if isinstance(f.type, Config.Tool)]: tool_path = self.gettattr(tool_name) if not shutil.which(tool_path): self.error("%s (%s) not found in $PATH", tool_name, tool_path) self.exit(1) - - p = argparse.ArgumentParser() - p.add_argument("input", type=str, help="input directory") - p.add_argument("-o","--output", type=str, help="output directory") - p.add_argument("--debug", dest="loglevel", action="store_const",const="DEBUG", help="Set log level to DEBUG") - p.add_argument("--extract", action="store_true", help="Extract file if compressed archive") - p.add_argument("--chapters", action="store_true", help="Parse chapters from epub file") - self.args = vars(p.parse_args()) + + 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("-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") + return self.parser + + + def parse_args(self, argv: list = None): + if not argv: + argv = sys.argv + self.parsed_args = self.parser.parse_args(argv) + self.args = vars(self.parsed_args) + #for a in self.args: # setattr(self, a, self.args[a]) @@ -89,9 +107,11 @@ class Cli: if output_path.suffix == ".m4b": output_name = output_path.name output_path = output_path.parent - self.merge_output = output_path.resolve() / output_name - + + return self.args + + def extract_input(self, input_path): self.debug("Input is compressed archive: %s", input_path) tmp_dir = pathlib.Path(self.tmp_dir).resolve() if self.tmp_dir else input_path.with_name(input_path.name + self.tmp_suffix).resolve() @@ -101,40 +121,44 @@ class Cli: self.exit(1) self.generate_epub_audio_suffixes() with zipfile.ZipFile(input_path) as compressed: - compressed.extractall(tmp_dir) + if not self.args["extract-only-audio"]: + compressed.extractall(tmp_dir) + return tmp_dir - # audio_files = [] - # #for file in compressed.namelist(): - # for file_info in compressed.infolist(): - # filename = pathlib.Path(file_info.filename) - # if not filename.suffix in self.epub_audio_suffixes: - # self.debug("Ignoring file with unsupported suffix: %s", filename) - # continue - # with compressed.open(file_info, 'r') as src: - # audio_file = mutagen.File(src) - # #guessed_type, _ = mimetypes.guess_file_type(src) - # guessed_type = audio_file.mime[0] - # if guessed_type in self.epub_audio_types: - # target = tmp_dir / filename.name - # self.debug("Extracting %s (%s) to %s", filename.name, guessed_type, target) - # with open(target, 'wb') as dst: - # shutil.copyfileobj(src, dst) - # #dst.write(src) - # audio_files.append(target) - # else: - # self.error("Guessed mimetype is not supported: %s", guessed_type) - # if len(audio_files)==0: - # self.error("No supported audio files in compressed archive: %s", input_path) - # self.exit(1) - # else: - # for file in audio_files: - # if not file.exists(): - # self.error("Error extracting (file does not exist): %s", file) - # if not mutagen.File(file).mime[0] in self.epub_audio_types: - # self.error("Error extracting (wrong mimetype): %s", file) - # if not file.parent == tmp_dir: - # self.error("Error extracting (wrong target path): %s", file) - # self.info("Verified %s", file) + audio_files = [] + #for file in compressed.namelist(): + for file_info in compressed.infolist(): + filename = pathlib.Path(file_info.filename) + if not filename.suffix in self.epub_audio_suffixes: + self.debug("Ignoring file with unsupported suffix: %s", filename) + continue + with compressed.open(file_info, 'r') as src: + audio_file = mutagen.File(src) + #guessed_type, _ = mimetypes.guess_file_type(src) + guessed_type = audio_file.mime[0] + if guessed_type in self.epub_audio_types: + target = tmp_dir / filename.name + self.debug("Extracting %s (%s) to %s", filename.name, guessed_type, target) + with open(target, 'wb') as dst: + shutil.copyfileobj(src, dst) + #dst.write(src) + audio_files.append(target) + else: + self.error("Guessed mimetype is not supported: %s", guessed_type) + if len(audio_files)==0: + self.error("No supported audio files in compressed archive: %s", input_path) + self.exit(1) + else: + for file in audio_files: + if not file.exists(): + self.error("Error extracting (file does not exist): %s", file) + if not mutagen.File(file).mime[0] in self.epub_audio_types: + self.error("Error extracting (wrong mimetype): %s", file) + if not file.parent == tmp_dir: + self.error("Error extracting (wrong target path): %s", file) + self.info("Verified %s", file) + + # Close zipfile return tmp_dir