recognition: глобальный переключатель языка вывода [general].language

- новое поле [general].language (ru|en, дефолт en) — единый источник языка
  локализованного title детектора и локали запросов к метабазам; original_title
  всегда на языке оригинала
- локаль TMDB (поиск + credits) выводится из него, [metadata.tmdb].language убран
- промпт LLM явно задаёт язык title с fallback на оригинал
This commit is contained in:
av
2026-07-24 14:09:04 +03:00
parent 8309ce0664
commit a2d8140e22
18 changed files with 556 additions and 48 deletions
+29 -9
View File
@@ -109,13 +109,13 @@ func TestTMDB_ErrorStatus(t *testing.T) {
}
func TestTMDB_SearchDefaultLanguage(t *testing.T) {
// Язык не задан в конфиге → дефолт ru-RU; original_title не зависит от локали.
// Язык не задан в конфиге → дефолт en-US; original_title не зависит от локали.
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("language"); got != "ru-RU" {
t.Errorf("language = %q, want ru-RU", got)
if got := r.URL.Query().Get("language"); got != "en-US" {
t.Errorf("language = %q, want en-US", got)
}
_, _ = w.Write([]byte(`{"results":[
{"id":155,"title":"Тёмный рыцарь","original_title":"The Dark Knight","release_date":"2008-07-18"}
{"id":155,"title":"The Dark Knight","original_title":"The Dark Knight","release_date":"2008-07-18"}
]}`))
}))
defer srv.Close()
@@ -124,21 +124,22 @@ func TestTMDB_SearchDefaultLanguage(t *testing.T) {
if err != nil {
t.Fatalf("Search: %v", err)
}
if got[0].Title != "Тёмный рыцарь" || got[0].OriginalTitle != "The Dark Knight" {
if got[0].Title != "The Dark Knight" || got[0].OriginalTitle != "The Dark Knight" {
t.Errorf("candidate = %+v", got[0])
}
}
func TestTMDB_SearchLanguageOverride(t *testing.T) {
func TestTMDB_SearchRussianLanguage(t *testing.T) {
// language = "ru" → диалект локали TMDB ru-RU (маппинг у провайдера).
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("language"); got != "en-US" {
t.Errorf("language = %q, want en-US", got)
if got := r.URL.Query().Get("language"); got != "ru-RU" {
t.Errorf("language = %q, want ru-RU", got)
}
_, _ = w.Write([]byte(`{"results":[]}`))
}))
defer srv.Close()
c, err := NewTMDB(TMDBConfig{APIKey: "k", BaseURL: srv.URL, Language: "en-US"}, nil)
c, err := NewTMDB(TMDBConfig{APIKey: "k", BaseURL: srv.URL, Language: "ru"}, nil)
if err != nil {
t.Fatalf("NewTMDB: %v", err)
}
@@ -147,6 +148,25 @@ func TestTMDB_SearchLanguageOverride(t *testing.T) {
}
}
func TestTMDB_DirectorCarriesLanguage(t *testing.T) {
// Локаль выведенного языка передаётся и в запрос credits (режиссёр).
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("language"); got != "ru-RU" {
t.Errorf("language = %q, want ru-RU", got)
}
_, _ = w.Write([]byte(`{"crew":[{"job":"Director","name":"Тимур Бекмамбетов"}]}`))
}))
defer srv.Close()
c, err := NewTMDB(TMDBConfig{APIKey: "k", BaseURL: srv.URL, Language: "ru"}, nil)
if err != nil {
t.Fatalf("NewTMDB: %v", err)
}
if _, err := c.Director(context.Background(), Movie, "1"); err != nil {
t.Fatalf("Director: %v", err)
}
}
func TestNewTMDB_RequiresKey(t *testing.T) {
if _, err := NewTMDB(TMDBConfig{}, nil); err == nil {
t.Fatal("want error without api_key")