mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
scape tmdb data with languages
This commit is contained in:
parent
4d45dfd06e
commit
1205eebc2e
5 changed files with 83 additions and 23 deletions
|
|
@ -1,7 +1,9 @@
|
|||
import slugify from "slugify";
|
||||
|
||||
import { conf } from "@/setup/config";
|
||||
import { useLanguageStore } from "@/stores/language";
|
||||
import { usePreferencesStore } from "@/stores/preferences";
|
||||
import { getTmdbLanguageCode } from "@/utils/language";
|
||||
import { MediaItem } from "@/utils/mediaTypes";
|
||||
import { getProxyUrls } from "@/utils/proxyUrls";
|
||||
|
||||
|
|
@ -176,12 +178,20 @@ export async function get<T>(url: string, params?: object): Promise<T> {
|
|||
const proxyUrls = getProxyUrls();
|
||||
const proxy = getNextProxy(proxyUrls);
|
||||
const shouldProxyTmdb = usePreferencesStore.getState().proxyTmdb;
|
||||
const userLanguage = useLanguageStore.getState().language;
|
||||
const formattedLanguage = getTmdbLanguageCode(userLanguage);
|
||||
|
||||
if (!apiKey) throw new Error("TMDB API key not set");
|
||||
|
||||
// directly writing parameters, otherwise it will start the first parameter in the proxied request as "&" instead of "?" because it doesnt understand its proxied
|
||||
const fullUrl = new URL(tmdbBaseUrl1 + url);
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
const allParams = {
|
||||
...params,
|
||||
language: formattedLanguage,
|
||||
};
|
||||
|
||||
if (allParams) {
|
||||
Object.entries(allParams).forEach(([key, value]) => {
|
||||
fullUrl.searchParams.append(key, String(value));
|
||||
});
|
||||
}
|
||||
|
|
@ -205,18 +215,14 @@ export async function get<T>(url: string, params?: object): Promise<T> {
|
|||
return await mwFetch<T>(encodeURI(url), {
|
||||
headers: tmdbHeaders,
|
||||
baseURL: tmdbBaseUrl1,
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
params: allParams,
|
||||
signal: abortOnTimeout(5000),
|
||||
});
|
||||
} catch (err) {
|
||||
return mwFetch<T>(encodeURI(url), {
|
||||
headers: tmdbHeaders,
|
||||
baseURL: tmdbBaseUrl2,
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
params: allParams,
|
||||
signal: abortOnTimeout(30000),
|
||||
});
|
||||
}
|
||||
|
|
@ -228,7 +234,6 @@ export async function multiSearch(
|
|||
const data = await get<TMDBSearchResult>("search/multi", {
|
||||
query,
|
||||
include_adult: false,
|
||||
language: "en-US",
|
||||
page: 1,
|
||||
});
|
||||
// filter out results that aren't movies or shows
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ import { Dropdown } from "@/components/form/Dropdown";
|
|||
import { Icon, Icons } from "@/components/Icon";
|
||||
import { hasAired } from "@/components/player/utils/aired";
|
||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||
import { useLanguageStore } from "@/stores/language";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { shouldShowProgress } from "@/stores/progress/utils";
|
||||
import { scrapeIMDb } from "@/utils/imdbScraper";
|
||||
import { getTmdbLanguageCode } from "@/utils/language";
|
||||
|
||||
import { useModal } from "./Modal";
|
||||
import { OverlayPortal } from "./OverlayDisplay";
|
||||
|
|
@ -199,7 +201,17 @@ function DetailsContent({
|
|||
|
||||
setIsLoadingImdb(true);
|
||||
try {
|
||||
const imdbMetadata = await scrapeIMDb(data.imdbId);
|
||||
// Get the user's selected language and format it properly
|
||||
const userLanguage = useLanguageStore.getState().language;
|
||||
const formattedLanguage = getTmdbLanguageCode(userLanguage);
|
||||
|
||||
// Pass the language to the scrapeIMDb function
|
||||
const imdbMetadata = await scrapeIMDb(
|
||||
data.imdbId,
|
||||
undefined,
|
||||
undefined,
|
||||
formattedLanguage,
|
||||
);
|
||||
setImdbData(imdbMetadata);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch IMDb data:", error);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import {
|
|||
} from "@/pages/discover/common";
|
||||
import { conf } from "@/setup/config";
|
||||
import { MediaItem } from "@/utils/mediaTypes";
|
||||
import { useLanguageStore } from "@/stores/language";
|
||||
import { getTmdbLanguageCode } from "@/utils/language";
|
||||
|
||||
import { CategoryButtons } from "./components/CategoryButtons";
|
||||
import { LazyMediaCarousel } from "./components/LazyMediaCarousel";
|
||||
|
|
@ -132,6 +134,9 @@ export function DiscoverContent() {
|
|||
// );
|
||||
const { t } = useTranslation();
|
||||
|
||||
const userLanguage = useLanguageStore.getState().language;
|
||||
const formattedLanguage = getTmdbLanguageCode(userLanguage);
|
||||
|
||||
// Only load data for the active tab
|
||||
const isMoviesTab = selectedCategory === "movies";
|
||||
const isTVShowsTab = selectedCategory === "tvshows";
|
||||
|
|
@ -145,7 +150,7 @@ export function DiscoverContent() {
|
|||
try {
|
||||
const data = await get<any>("/genre/tv/list", {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
});
|
||||
// Fetch only the first 10 TV show genres
|
||||
setTVGenres(data.genres.slice(0, 10));
|
||||
|
|
@ -155,7 +160,7 @@ export function DiscoverContent() {
|
|||
};
|
||||
|
||||
fetchTVGenres();
|
||||
}, [isTVShowsTab]);
|
||||
}, [isTVShowsTab, formattedLanguage]);
|
||||
|
||||
// Fetch Movie genres
|
||||
useEffect(() => {
|
||||
|
|
@ -165,7 +170,7 @@ export function DiscoverContent() {
|
|||
try {
|
||||
const data = await get<any>("/genre/movie/list", {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
});
|
||||
|
||||
// Fetch only the first 12 genres
|
||||
|
|
@ -176,7 +181,7 @@ export function DiscoverContent() {
|
|||
};
|
||||
|
||||
fetchGenres();
|
||||
}, [isMoviesTab]);
|
||||
}, [isMoviesTab, formattedLanguage]);
|
||||
|
||||
// Fetch Editor Picks Movies
|
||||
useEffect(() => {
|
||||
|
|
@ -187,7 +192,7 @@ export function DiscoverContent() {
|
|||
const moviePromises = EDITOR_PICKS_MOVIES.map((item) =>
|
||||
get<any>(`/movie/${item.id}`, {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
append_to_response: "videos,images",
|
||||
}),
|
||||
);
|
||||
|
|
@ -202,7 +207,7 @@ export function DiscoverContent() {
|
|||
};
|
||||
|
||||
fetchEditorPicksMovies();
|
||||
}, [isEditorPicksTab]);
|
||||
}, [isEditorPicksTab, formattedLanguage]);
|
||||
|
||||
// Fetch Editor Picks TV Shows
|
||||
useEffect(() => {
|
||||
|
|
@ -213,7 +218,7 @@ export function DiscoverContent() {
|
|||
const tvShowPromises = EDITOR_PICKS_TV_SHOWS.map((item) =>
|
||||
get<any>(`/tv/${item.id}`, {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
append_to_response: "videos,images",
|
||||
}),
|
||||
);
|
||||
|
|
@ -228,7 +233,7 @@ export function DiscoverContent() {
|
|||
};
|
||||
|
||||
fetchEditorPicksTVShows();
|
||||
}, [isEditorPicksTab]);
|
||||
}, [isEditorPicksTab, formattedLanguage]);
|
||||
|
||||
useEffect(() => {
|
||||
let countdownInterval: NodeJS.Timeout;
|
||||
|
|
@ -290,7 +295,7 @@ export function DiscoverContent() {
|
|||
api_key: conf().TMDB_READ_API_KEY,
|
||||
with_watch_providers: id,
|
||||
watch_region: "US",
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
});
|
||||
setData(data.results);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { get } from "@/backend/metadata/tmdb";
|
||||
import { useLanguageStore } from "@/stores/language";
|
||||
import { getTmdbLanguageCode } from "@/utils/language";
|
||||
import { Category, Genre, Movie, TVShow } from "@/pages/discover/common";
|
||||
import { conf } from "@/setup/config";
|
||||
|
||||
|
|
@ -19,6 +21,8 @@ export function useTMDBData(
|
|||
[categoryName: string]: Movie[] | TVShow[];
|
||||
}>({});
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const userLanguage = useLanguageStore.getState().language;
|
||||
const formattedLanguage = getTmdbLanguageCode(userLanguage);
|
||||
|
||||
// Unified fetch function
|
||||
const fetchMedia = useCallback(
|
||||
|
|
@ -29,7 +33,7 @@ export function useTMDBData(
|
|||
for (let page = 1; page <= 2; page += 1) {
|
||||
const data = await get<any>(endpoint, {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
page: page.toString(),
|
||||
...(isGenre ? { with_genres: key } : {}),
|
||||
});
|
||||
|
|
@ -51,7 +55,7 @@ export function useTMDBData(
|
|||
return [];
|
||||
}
|
||||
},
|
||||
[mediaType],
|
||||
[mediaType, formattedLanguage],
|
||||
);
|
||||
|
||||
// Fetch media for each genre
|
||||
|
|
@ -104,6 +108,8 @@ export function useLazyTMDBData(
|
|||
) {
|
||||
const [media, setMedia] = useState<Movie[] | TVShow[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const userLanguage = useLanguageStore.getState().language;
|
||||
const formattedLanguage = getTmdbLanguageCode(userLanguage);
|
||||
|
||||
const fetchMedia = useCallback(
|
||||
async (endpoint: string, key: string, isGenre: boolean) => {
|
||||
|
|
@ -113,7 +119,7 @@ export function useLazyTMDBData(
|
|||
// Only fetch one page for better performance
|
||||
const data = await get<any>(endpoint, {
|
||||
api_key: conf().TMDB_READ_API_KEY,
|
||||
language: "en-US",
|
||||
language: formattedLanguage,
|
||||
page: "1",
|
||||
...(isGenre ? { with_genres: key } : {}),
|
||||
});
|
||||
|
|
@ -130,7 +136,7 @@ export function useLazyTMDBData(
|
|||
return [];
|
||||
}
|
||||
},
|
||||
[mediaType],
|
||||
[mediaType, formattedLanguage],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -224,3 +224,35 @@ export function getLocaleInfo(locale: string): LocaleInfo | null {
|
|||
nativeName: output.nativeName[0] ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a language code to a TMDB-compatible format (ISO 639-1 with region)
|
||||
* @param language The language code to convert
|
||||
* @returns A TMDB-compatible language code (e.g., "en-US", "el-GR")
|
||||
*/
|
||||
export function getTmdbLanguageCode(language: string): string {
|
||||
// Handle empty or undefined
|
||||
if (!language) return "en-US";
|
||||
|
||||
// If it already has a region code (e.g., "en-US"), use it directly
|
||||
if (language.includes("-")) return language;
|
||||
|
||||
// Handle special/custom languages by defaulting to English
|
||||
if (language.length > 2 || Object.keys(extraLanguages).includes(language))
|
||||
return "en-US";
|
||||
|
||||
// For standard language codes, find the appropriate region from the existing defaultLanguageCodes array
|
||||
const defaultCode = defaultLanguageCodes.find((code) =>
|
||||
code.startsWith(`${language}-`),
|
||||
);
|
||||
|
||||
if (defaultCode) return defaultCode;
|
||||
|
||||
// If we can't find a good match, create a standard format like "fr-FR" from "fr"
|
||||
if (language.length === 2) {
|
||||
return `${language}-${language.toUpperCase()}`;
|
||||
}
|
||||
|
||||
// Last resort fallback
|
||||
return "en-US";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue