Skip to content

Commit 74d29bb

Browse files
fix: use proper language api to return tmdb available languages (#73)
* fix: use proper language api to return tmdb available languages * fix: escape languages to nullify xss security
1 parent eebc91b commit 74d29bb

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

app/api/endpoints/meta.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import asyncio
2+
13
from fastapi import APIRouter, HTTPException
24
from loguru import logger
35

@@ -8,15 +10,41 @@
810

911
@router.get("/api/languages")
1012
async def get_languages():
11-
"""
12-
Proxy endpoint to fetch languages from TMDB.
13-
"""
1413
try:
1514
tmdb = get_tmdb_service()
16-
languages = await tmdb.get_languages()
17-
if not languages:
18-
return []
19-
return languages
15+
tasks = [
16+
tmdb.get_primary_translations(),
17+
tmdb.get_languages(),
18+
tmdb.get_countries(),
19+
]
20+
primary_translations, languages, countries = await asyncio.gather(*tasks)
21+
22+
language_map = {lang["iso_639_1"]: lang["english_name"] for lang in languages}
23+
24+
country_map = {country["iso_3166_1"]: country["english_name"] for country in countries}
25+
26+
result = []
27+
for element in primary_translations:
28+
# element looks like "en-US"
29+
parts = element.split("-")
30+
if len(parts) != 2:
31+
continue
32+
33+
lang_code, country_code = parts
34+
35+
language_name = language_map.get(lang_code)
36+
country_name = country_map.get(country_code)
37+
38+
if language_name and country_name:
39+
result.append(
40+
{
41+
"iso_639_1": element,
42+
"language": language_name,
43+
"country": country_name,
44+
}
45+
)
46+
return result
47+
2048
except Exception as e:
2149
logger.error(f"Failed to fetch languages: {e}")
2250
raise HTTPException(status_code=502, detail="Failed to fetch languages from TMDB")

app/services/tmdb/service.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ async def get_languages(self) -> list[dict[str, Any]]:
111111
"""Fetch supported languages from TMDB."""
112112
return await self.client.get("/configuration/languages")
113113

114+
@alru_cache(maxsize=1, ttl=86400)
115+
async def get_countries(self) -> list[dict[str, Any]]:
116+
"""Fetch supported countries from TMDB."""
117+
return await self.client.get("/configuration/countries")
118+
119+
@alru_cache(maxsize=1, ttl=86400)
120+
async def get_primary_translations(self) -> list[str]:
121+
"""Fetch supported primary translations from TMDB."""
122+
return await self.client.get("/configuration/primary_translations")
123+
114124

115125
@functools.lru_cache(maxsize=16)
116126
def get_tmdb_service(language: str = "en-US") -> TMDBService:

app/static/script.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -676,18 +676,17 @@ async function initializeLanguageSelect() {
676676
if (!languagesResponse.ok) throw new Error('Failed to fetch languages');
677677
const languages = await languagesResponse.json();
678678
languages.sort((a, b) => {
679-
if (a.iso_639_1 === 'en') return -1;
680-
if (b.iso_639_1 === 'en') return 1;
681-
return a.english_name.localeCompare(b.english_name);
679+
if (a.iso_639_1 === 'en-US') return -1;
680+
if (b.iso_639_1 === 'en-US') return 1;
681+
return a.language.localeCompare(b.language);
682682
});
683683
languageSelect.innerHTML = languages.map(lang => {
684684
const code = lang.iso_639_1;
685-
const label = lang.name ? lang.name : lang.english_name;
686-
const fullLabel = lang.name && lang.name !== lang.english_name ? `${lang.english_name} (${lang.name})` : lang.english_name;
687-
return `<option value="${code}" ${code === 'en' ? 'selected' : ''}>${fullLabel}</option>`;
685+
const fullLabel = escapeHtml(lang.language) + ' (' + escapeHtml(lang.country) + ')';
686+
return '<option value="' + escapeHtml(code) + '"' + (code === 'en-US' ? ' selected' : '') + '>' + fullLabel + '</option>';
688687
}).join('');
689688
} catch (err) {
690-
languageSelect.innerHTML = '<option value="en">English</option>';
689+
languageSelect.innerHTML = '<option value="en-US">English (US)</option>';
691690
}
692691
}
693692

0 commit comments

Comments
 (0)