Atualizar m4b/cli.py

This commit is contained in:
2026-08-27 15:54:06 -03:00
parent da9646745c
commit ffbc1adeb1
+49 -32
View File
@@ -3,6 +3,9 @@
import os, sys, subprocess, shutil, logging, argparse, dataclasses, collections, pprint, typing, pathlib, zipfile, mimetypes import os, sys, subprocess, shutil, logging, argparse, dataclasses, collections, pprint, typing, pathlib, zipfile, mimetypes
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime as dt from datetime import datetime as dt
from importlib.metadata import version
__version__ = version('m4b')
import mutagen import mutagen
@@ -57,13 +60,15 @@ class Cli:
def get_parser(self): def get_parser(self):
self.parser = argparse.ArgumentParser() self.parser = argparse.ArgumentParser()
self.parser.add_argument("input", type=str, help="input directory or file") 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("-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("-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("--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", 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("--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("--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 return self.parser
@@ -79,35 +84,18 @@ class Cli:
self.info(self.args) self.info(self.args)
# Input # Input
input_path = pathlib.Path(self.args['input']) self.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)
# Output # Output
if not self.args['output']: if not self.args['output']:
output_path = input_path.parent self.output_path = self.input_path.parent
output_name = input_path.with_suffix(".m4b").name self.output_name = self.input_path.with_suffix(".m4b").name
else: else:
output_path = pathlib.Path(self.args['output']) self.output_path = pathlib.Path(self.args['output'])
if output_path.suffix == ".m4b": if self.output_path.suffix == ".m4b":
output_name = output_path.name self.output_name = self.output_path.name
output_path = output_path.parent self.output_path = self.output_path.parent
self.merge_output = output_path.resolve() / output_name self.outfile = self.output_path / self.output_name
return self.args return self.args
@@ -236,8 +224,41 @@ class Cli:
def debug(self, msg, *args): def debug(self, msg, *args):
self.log(logging.DEBUG, 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: if not cmd:
self.error("Empty cmd") self.error("Empty cmd")
return 1 return 1
@@ -315,10 +336,6 @@ class Cli:
audiopath.move(newpath) audiopath.move(newpath)
def cli():
Cli().run([config.m4b.path] + config.m4b.flags +
["merge", "-o", config.merge_output, config.merge_input])
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(cli()) sys.exit(Cli().run())