aboutsummaryrefslogtreecommitdiff
path: root/app/converter/converter.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/converter/converter.py')
-rw-r--r--app/converter/converter.py34
1 files changed, 22 insertions, 12 deletions
diff --git a/app/converter/converter.py b/app/converter/converter.py
index 455c1fb..1abc85c 100644
--- a/app/converter/converter.py
+++ b/app/converter/converter.py
@@ -64,7 +64,9 @@ def setup_logging(debug: bool = False, console: bool = True) -> None:
(DEBUG with --debug) so progress prints are never mirrored as
timestamped log lines; httpx/httpcore request logs stay file-only.
CONSOLE=False (the TUI run view owns the screen) keeps every record
- in the file only.
+ in the file only. Safe to call repeatedly in one process (the hub
+ calls it once per conversion run): force=True replaces the previous
+ handlers instead of silently keeping them.
"""
LOGS_FOLDER.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(
@@ -82,9 +84,12 @@ def setup_logging(debug: bool = False, console: bool = True) -> None:
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=handlers,
+ force=True,
)
if debug:
logging.getLogger("converter").setLevel(logging.DEBUG)
+ else:
+ logging.getLogger("converter").setLevel(logging.INFO)
def setup_directories() -> None:
@@ -215,10 +220,16 @@ class AudiobookConverter:
self.instructions = instructions
self.request_options = dict(request_options or {})
self._validate_configuration()
+ # Interactive reporting (the TUI run view): PROGRESS receives an
+ # event dict per state change and turns the clients' console prints
+ # off (quiet is set at construction so connect-time lines respect it
+ # too); CANCEL (a threading.Event) stops the run between requests.
+ quiet = progress is not None
if backend == BACKEND_FASTER:
# The faster backend always voice-clones using a reference voice
# configured on the server, so no local reference audio is needed.
- self.tts = FasterTTSClient(voice=voice, api_url=api_url)
+ self.tts = FasterTTSClient(voice=voice, api_url=api_url,
+ quiet=quiet)
elif backend == BACKEND_AUDIOCPP:
# --voice picks the voice: a built-in speaker name on the
# CustomVoice entry, or a server-side preset (cloning)
@@ -230,7 +241,7 @@ class AudiobookConverter:
model_id=model_id,
instructions=instructions,
request_options=self.request_options,
- api_url=api_url)
+ api_url=api_url, quiet=quiet)
else:
self.tts = QwenTTSClient(
voice_mode=voice_mode,
@@ -239,14 +250,10 @@ class AudiobookConverter:
skip_transcription=skip_transcription,
language=self.language,
api_url=api_url,
+ quiet=quiet,
)
- # Interactive reporting/cancellation (the TUI run view): PROGRESS
- # receives an event dict per state change and turns the console
- # prints off (the view owns the screen); CANCEL (a
- # threading.Event) stops the run between requests.
self._progress = progress
self.tts.cancel = cancel
- self.tts.quiet = progress is not None
def _emit(self, event: dict) -> None:
"""Send one progress event (a no-op without a progress callback)."""
@@ -723,11 +730,11 @@ class AudiobookConverter:
self._say(f"Output format: {self.output_format}")
if self.single_file and self.output_format != "m4b":
self._say("Chapter mode: single file (--single-file)")
- if abs(self.speed - 1.0) >= 1e-6:
+ if abs(self.speed - 1.0) >= audio.SPEED_EPSILON:
self._say(f"Playback speed: {self.speed:g}x")
if self.debug:
self._say(f"Debug dumps (per-chunk text + raw audio): {DEBUG_FOLDER}")
- print("=" * 70)
+ self._say("=" * 70)
# ------------------------------------------------------------------
# Pre-flight: overwrite checks before connecting to a TTS server
@@ -857,11 +864,14 @@ class AudiobookConverter:
successful = sum(results.values())
total = len(results)
+ # A cancelled run is not a successful run on either path (the TUI
+ # event consumer and the console summary report it consistently).
+ ok = not cancelled and total > 0 and successful == total
self._emit({"kind": "done", "ok": successful,
"total": total or len(planned), "cancelled": cancelled})
if self._progress is not None:
- return not cancelled and total > 0 and successful == total
+ return ok
print("\n" + "=" * 70)
print("CONVERSION SUMMARY")
@@ -888,4 +898,4 @@ class AudiobookConverter:
print(f"\n[INFO] Generation completed in {duration}")
logger.info("Generation completed in %s", duration)
- return total > 0 and successful == total
+ return ok