fix(cli)!: источник языка в шапке транскрипта на русском
- Зачем: - в одной строке шапки смешивались английские и русские значения, а при неизвестном языке в неё попадало служебное «unknown (не определён)». - Что: - формулировки источника языка вынесены константами в formatter и переведены на русский. - оба бэкенда используют общий признак UNKNOWN_LANGUAGE вместо «auto» и «unknown». - неизвестный язык печатается одной строкой, без служебного значения. - Проверка: - uv run pytest -q: 242 passed, 1 skipped. - ruff check .: 48 замечаний, столько же, сколько до правки. BREAKING CHANGE: в шапке транскрипта значения detected и forced заменены на «определён автоматически» и «задан явно»; при неизвестном языке строка выглядит как «- **Язык**: не определён».
This commit is contained in:
@@ -11,7 +11,7 @@ from local_transcriber.backends.openvino import (
|
||||
OpenVINOBackend,
|
||||
_validate_model_dir,
|
||||
)
|
||||
from local_transcriber.types import Segment
|
||||
from local_transcriber.types import UNKNOWN_LANGUAGE, Segment
|
||||
|
||||
|
||||
# === _resolve_repo ===
|
||||
@@ -301,7 +301,7 @@ def test_transcribe_no_language_auto():
|
||||
|
||||
call_kwargs = mock_model.generate.call_args.kwargs
|
||||
assert "language" not in call_kwargs
|
||||
assert result.language == "auto"
|
||||
assert result.language == UNKNOWN_LANGUAGE
|
||||
assert result.language_probability == 0.0
|
||||
|
||||
|
||||
|
||||
+11
-4
@@ -6,7 +6,14 @@ from rich.console import Console
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from local_transcriber.cli import _format_device_info, _format_language_mode, app
|
||||
from local_transcriber.formatter import (
|
||||
LANGUAGE_DETECTED,
|
||||
LANGUAGE_FORCED,
|
||||
LANGUAGE_FROM_MODEL,
|
||||
LANGUAGE_UNKNOWN,
|
||||
)
|
||||
from local_transcriber.transcriber import Segment, TranscribeFileResult, TranscribeResult
|
||||
from local_transcriber.types import UNKNOWN_LANGUAGE
|
||||
|
||||
runner = CliRunner()
|
||||
|
||||
@@ -45,10 +52,10 @@ def _make_tfr(result=None, model=None, actual_device="cpu", backend=None, model_
|
||||
@pytest.mark.parametrize(
|
||||
("requested_language", "language", "probability", "expected"),
|
||||
[
|
||||
("ru", "ru", 1.0, "forced"),
|
||||
("auto", "ru", 0.95, "detected"),
|
||||
("auto", "ru", 0.0, "из профиля модели"),
|
||||
("auto", "unknown", 0.0, "не определён"),
|
||||
("ru", "ru", 1.0, LANGUAGE_FORCED),
|
||||
("auto", "ru", 0.95, LANGUAGE_DETECTED),
|
||||
("auto", "ru", 0.0, LANGUAGE_FROM_MODEL),
|
||||
("auto", UNKNOWN_LANGUAGE, 0.0, LANGUAGE_UNKNOWN),
|
||||
],
|
||||
)
|
||||
def test_format_language_mode(
|
||||
|
||||
+37
-12
@@ -2,12 +2,16 @@ from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from local_transcriber.formatter import (
|
||||
LANGUAGE_DETECTED,
|
||||
LANGUAGE_FORCED,
|
||||
LANGUAGE_UNKNOWN,
|
||||
_group_segments,
|
||||
format_timestamp,
|
||||
format_transcript,
|
||||
write_transcript,
|
||||
)
|
||||
from local_transcriber.transcriber import Segment, TranscribeResult
|
||||
from local_transcriber.types import UNKNOWN_LANGUAGE
|
||||
|
||||
|
||||
def test_format_timestamp_minutes():
|
||||
@@ -40,14 +44,14 @@ def test_format_transcript_basic():
|
||||
source_filename="meeting.mp4",
|
||||
model_name="large-v3",
|
||||
device_info="CUDA (NVIDIA GeForce RTX 3060)",
|
||||
language_mode="detected",
|
||||
language_mode=LANGUAGE_DETECTED,
|
||||
transcription_date=datetime(2026, 3, 17, 14, 30, 5),
|
||||
)
|
||||
|
||||
assert "# Транскрипт: meeting.mp4" in content
|
||||
assert "**Дата транскрипции**: 2026-03-17 14:30:05" in content
|
||||
assert "**Модель**: large-v3" in content
|
||||
assert "**Язык**: ru (detected)" in content
|
||||
assert "**Язык**: ru (определён автоматически)" in content
|
||||
assert "**Длительность**: 02:00" in content
|
||||
assert "**Устройство**: CUDA (NVIDIA GeForce RTX 3060)" in content
|
||||
assert "---" in content
|
||||
@@ -55,6 +59,27 @@ def test_format_transcript_basic():
|
||||
assert "[00:00.00 - 00:09.15] Добрый день, коллеги. Первый вопрос." in content
|
||||
|
||||
|
||||
def test_format_transcript_unknown_language_without_placeholder():
|
||||
"""Неизвестный язык печатается одной строкой, без служебного значения."""
|
||||
result = TranscribeResult(
|
||||
segments=[Segment(start=0.0, end=4.0, text=" Добрый день.")],
|
||||
language=UNKNOWN_LANGUAGE,
|
||||
language_probability=0.0,
|
||||
duration=120.0,
|
||||
device_used="openvino-cpu",
|
||||
)
|
||||
content = format_transcript(
|
||||
result,
|
||||
source_filename="meeting.mp4",
|
||||
model_name="medium",
|
||||
device_info="OpenVINO (CPU)",
|
||||
language_mode=LANGUAGE_UNKNOWN,
|
||||
)
|
||||
|
||||
assert "**Язык**: не определён" in content
|
||||
assert UNKNOWN_LANGUAGE not in content
|
||||
|
||||
|
||||
def test_format_transcript_segment_no_leading_space():
|
||||
"""Сегменты без ведущего пробела должны форматироваться корректно."""
|
||||
result = TranscribeResult(
|
||||
@@ -69,7 +94,7 @@ def test_format_transcript_segment_no_leading_space():
|
||||
source_filename="f.mp3",
|
||||
model_name="tiny",
|
||||
device_info="CPU",
|
||||
language_mode="detected",
|
||||
language_mode=LANGUAGE_DETECTED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
assert "[00:00.00 - 00:02.00] Hello" in content
|
||||
@@ -88,7 +113,7 @@ def test_format_transcript_empty():
|
||||
source_filename="silence.wav",
|
||||
model_name="tiny",
|
||||
device_info="CPU",
|
||||
language_mode="detected",
|
||||
language_mode=LANGUAGE_DETECTED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -113,12 +138,12 @@ def test_format_transcript_long():
|
||||
source_filename="long.mp4",
|
||||
model_name="large-v3",
|
||||
device_info="CUDA",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 3, 17, 10, 0, 0),
|
||||
)
|
||||
|
||||
assert "**Длительность**: 01:03:20" in content
|
||||
assert "**Язык**: en (forced)" in content
|
||||
assert "**Язык**: en (задан явно)" in content
|
||||
# Timestamps should use hours format
|
||||
assert "[00:00:00.00 - 00:00:10.50] Начало." in content
|
||||
assert "[01:01:40.00 - 01:01:50.25] Конец." in content
|
||||
@@ -188,7 +213,7 @@ def test_format_transcript_tail_gap_warning():
|
||||
source_filename="tail.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -210,7 +235,7 @@ def test_format_transcript_no_tail_gap_warning_for_small_gap():
|
||||
source_filename="ok.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -231,7 +256,7 @@ def test_format_transcript_no_tail_gap_warning_for_exact_threshold():
|
||||
source_filename="ok.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -257,7 +282,7 @@ def test_format_transcript_repetition_warning():
|
||||
source_filename="repeat.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -284,7 +309,7 @@ def test_format_transcript_repetition_warning_uses_hours():
|
||||
source_filename="long-repeat.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
@@ -305,7 +330,7 @@ def test_format_transcript_without_anomalies_has_no_warning_lines():
|
||||
source_filename="ok.mp3",
|
||||
model_name="medium",
|
||||
device_info="CPU",
|
||||
language_mode="forced",
|
||||
language_mode=LANGUAGE_FORCED,
|
||||
transcription_date=datetime(2026, 1, 1, 0, 0, 0),
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import warnings
|
||||
import pytest
|
||||
|
||||
from local_transcriber.backends.onnx_asr import OnnxAsrBackend
|
||||
from local_transcriber.types import Segment, TranscribeResult
|
||||
from local_transcriber.types import UNKNOWN_LANGUAGE, Segment, TranscribeResult
|
||||
|
||||
|
||||
class FakeVadSegment:
|
||||
@@ -390,7 +390,7 @@ class TestTranscribe:
|
||||
result = backend.transcribe(FakeModel(), wav_file, language=None)
|
||||
|
||||
assert len(result.segments) == 0
|
||||
assert result.language == "unknown"
|
||||
assert result.language == UNKNOWN_LANGUAGE
|
||||
assert result.duration == 1.0
|
||||
|
||||
def test_transcribe_skips_zero_length_vad_segments(self, monkeypatch, tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user