From fcdaf2b2a837d7525d922e586ee0310ec4861d14 Mon Sep 17 00:00:00 2001 From: Artem Akymenko Date: Sat, 18 Jul 2026 09:00:24 +0000 Subject: [PATCH] refactor(domain): extract FakeToken to domain/tokens.py Shared token stub used by both WebUI and PyQt for languages without per-word token support. --- abogen/domain/tokens.py | 13 +++++++++++++ abogen/pyqt/conversion.py | 9 +-------- abogen/webui/conversion_runner.py | 13 ++----------- 3 files changed, 16 insertions(+), 19 deletions(-) create mode 100644 abogen/domain/tokens.py diff --git a/abogen/domain/tokens.py b/abogen/domain/tokens.py new file mode 100644 index 0000000..5a8c8b2 --- /dev/null +++ b/abogen/domain/tokens.py @@ -0,0 +1,13 @@ +"""Shared token stubs for TTS processing.""" + +from __future__ import annotations + + +class FakeToken: + """Minimal token stub for languages without per-word token support.""" + + def __init__(self, text: str, start: float, end: float): + self.text = text + self.start_ts = start + self.end_ts = end + self.whitespace = "" diff --git a/abogen/pyqt/conversion.py b/abogen/pyqt/conversion.py index 3a86005..852e164 100644 --- a/abogen/pyqt/conversion.py +++ b/abogen/pyqt/conversion.py @@ -31,6 +31,7 @@ from abogen.domain.output_paths import ( ) from abogen.domain.audio_helpers import build_ffmpeg_command, to_float32 from abogen.domain.audio_sink import AudioSink, open_audio_sink +from abogen.domain.tokens import FakeToken from abogen.domain.audio_buffer import ( create_silence, mix_audio, @@ -1086,14 +1087,6 @@ class ConversionThread(QThread): # Fallback for languages without token support (non-English) # Create a single token representing the entire segment duration if not tokens_list and result.graphemes: - - class FakeToken: - def __init__(self, text, start, end): - self.text = text - self.start_ts = start - self.end_ts = end - self.whitespace = "" - tokens_list = [ FakeToken(result.graphemes, 0, chunk_dur) ] diff --git a/abogen/webui/conversion_runner.py b/abogen/webui/conversion_runner.py index 4e0a728..2789da9 100644 --- a/abogen/webui/conversion_runner.py +++ b/abogen/webui/conversion_runner.py @@ -121,6 +121,7 @@ from abogen.domain.audio_buffer import ( SAMPLE_RATE, ) from abogen.domain.audio_sink import AudioSink, open_audio_sink +from abogen.domain.tokens import FakeToken from .service import Job, JobStatus @@ -132,16 +133,6 @@ SPLIT_PATTERN = r"\n+" # Kept for backward compatibility; prefer get_split_patt SAMPLE_RATE = 24000 -class _FakeToken: - """Minimal token stub for languages without per-word token support.""" - - def __init__(self, text: str, start: float, end: float): - self.text = text - self.start_ts = start - self.end_ts = end - self.whitespace = "" - - class _JobCancelled(Exception): """Raised internally to abort a conversion when the client cancels.""" @@ -543,7 +534,7 @@ def run_conversion_job(job: Job) -> None: # Fallback for languages without token support: create a single token if not tokens_list and graphemes: - tokens_list = [_FakeToken(graphemes, 0, duration)] + tokens_list = [FakeToken(graphemes, 0, duration)] for tok in tokens_list: accumulated_tokens.append({