diff --git a/abogen/web/debug_tts_runner.py b/abogen/web/debug_tts_runner.py index 9a54591..d8996ef 100644 --- a/abogen/web/debug_tts_runner.py +++ b/abogen/web/debug_tts_runner.py @@ -90,7 +90,29 @@ def run_debug_tts_wavs( if missing: raise RuntimeError(f"Debug EPUB missing expected codes: {', '.join(missing)}") - language = str(settings.get("language") or "en").strip() or "en" + language = str(settings.get("language") or "a").strip() or "a" + # Kokoro's KPipeline expects short language codes like "a" (American English), + # but older settings may store ISO-like values such as "en". + language_aliases = { + "en": "a", + "en-us": "a", + "en_us": "a", + "en-gb": "b", + "en_gb": "b", + "es": "e", + "es-es": "e", + "fr": "f", + "fr-fr": "f", + "hi": "h", + "it": "i", + "pt": "p", + "pt-br": "p", + "ja": "j", + "jp": "j", + "zh": "z", + "zh-cn": "z", + } + language = language_aliases.get(language.lower(), language) voice_spec = str(settings.get("default_voice") or "").strip() use_gpu = bool(settings.get("use_gpu", False)) speed = float(settings.get("default_speed", 1.0) or 1.0) diff --git a/abogen/web/routes/settings.py b/abogen/web/routes/settings.py index b3340b2..30e166a 100644 --- a/abogen/web/routes/settings.py +++ b/abogen/web/routes/settings.py @@ -195,12 +195,38 @@ def run_debug_wavs() -> ResponseReturnValue: return redirect(url_for("settings.settings_page", _anchor="debug")) flash("Debug WAV generation completed.", "success") - return redirect( - url_for( - "settings.settings_page", - debug_run_id=str(manifest.get("run_id") or ""), - _anchor="debug", - ) + return redirect(url_for("settings.debug_wavs_page", run_id=str(manifest.get("run_id") or ""))) + + +@settings_bp.get("/debug/") +def debug_wavs_page(run_id: str) -> ResponseReturnValue: + safe_run = (run_id or "").strip() + if not safe_run: + abort(404) + + root = Path(current_app.config.get("OUTPUT_FOLDER") or get_user_output_path("web")) + run_dir = (root / "debug" / safe_run).resolve() + manifest_path = run_dir / "manifest.json" + if not manifest_path.exists(): + abort(404) + + try: + import json + + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + except Exception: + abort(404) + + artifacts = manifest.get("artifacts") or [] + # Precompute download URLs for each artifact. + for item in artifacts: + filename = str(item.get("filename") or "") + item["url"] = url_for("settings.download_debug_wav", run_id=safe_run, filename=filename) + + return render_template( + "debug_wavs.html", + run_id=safe_run, + artifacts=artifacts, ) diff --git a/abogen/web/templates/debug_wavs.html b/abogen/web/templates/debug_wavs.html new file mode 100644 index 0000000..69b766b --- /dev/null +++ b/abogen/web/templates/debug_wavs.html @@ -0,0 +1,61 @@ +{% extends "base.html" %} + +{% block title %}abogen · Debug WAVs{% endblock %} + +{% block content %} +
+

Debug WAVs

+

Run ID: {{ run_id }}

+ +
+ +

Click an ID to play its WAV. “Overall” is the concatenation of all samples.

+
+ + {% if artifacts %} +
+ +
    + {% for item in artifacts %} +
  • + + {{ item.filename }} +
  • + {% endfor %} +
+
+ {% endif %} + + +
+ + +{% endblock %} diff --git a/tests/test_debug_tts_samples.py b/tests/test_debug_tts_samples.py index aaa6c24..3b72b14 100644 --- a/tests/test_debug_tts_samples.py +++ b/tests/test_debug_tts_samples.py @@ -84,10 +84,10 @@ def test_settings_debug_route_writes_manifest(tmp_path, monkeypatch): resp = client.post("/settings/debug/run") assert resp.status_code in {302, 303} location = resp.headers.get("Location", "") - assert "debug_run_id=" in location + assert "/settings/debug/" in location - # Extract run id from query string. - run_id = location.split("debug_run_id=")[1].split("&")[0].split("#")[0] + # Extract run id from /settings/debug/ + run_id = location.rsplit("/settings/debug/", 1)[1].split("?", 1)[0].split("#", 1)[0] manifest_path = tmp_path / "debug" / run_id / "manifest.json" assert manifest_path.exists()