mirror of
https://github.com/movie-web/movie-web.git
synced 2025-01-14 14:19:07 +01:00
refactor and improve legacy redirect
This commit is contained in:
parent
f5f69ca7d4
commit
394271857f
@ -8,6 +8,7 @@ import {
|
|||||||
getExternalIds,
|
getExternalIds,
|
||||||
getMediaDetails,
|
getMediaDetails,
|
||||||
getMediaPoster,
|
getMediaPoster,
|
||||||
|
getMovieFromExternalId,
|
||||||
mediaTypeToTMDB,
|
mediaTypeToTMDB,
|
||||||
} from "./tmdb";
|
} from "./tmdb";
|
||||||
import {
|
import {
|
||||||
@ -206,11 +207,23 @@ export async function convertLegacyUrl(
|
|||||||
if (url.startsWith("/media/JW")) {
|
if (url.startsWith("/media/JW")) {
|
||||||
const urlParts = url.split("/").slice(2);
|
const urlParts = url.split("/").slice(2);
|
||||||
const [, type, id] = urlParts[0].split("-", 3);
|
const [, type, id] = urlParts[0].split("-", 3);
|
||||||
const meta = await getLegacyMetaFromId(TMDBMediaToMediaType(type), id);
|
|
||||||
|
const mediaType = TMDBMediaToMediaType(type);
|
||||||
|
const meta = await getLegacyMetaFromId(mediaType, id);
|
||||||
|
|
||||||
if (!meta) return undefined;
|
if (!meta) return undefined;
|
||||||
const tmdbId = meta.tmdbId;
|
const { tmdbId, imdbId } = meta;
|
||||||
if (!tmdbId) return undefined;
|
if (!tmdbId && !imdbId) return undefined;
|
||||||
return `/media/tmdb-${type}-${tmdbId}`;
|
|
||||||
|
// movies always have an imdb id on tmdb
|
||||||
|
if (imdbId && mediaType === MWMediaType.MOVIE) {
|
||||||
|
const movieId = await getMovieFromExternalId(imdbId);
|
||||||
|
if (movieId) return `/media/tmdb-movie-${movieId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmdbId) {
|
||||||
|
return `/media/tmdb-${type}-${tmdbId}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { conf } from "@/setup/config";
|
|||||||
|
|
||||||
import { MWMediaMeta, MWMediaType, MWSeasonMeta } from "./types/mw";
|
import { MWMediaMeta, MWMediaType, MWSeasonMeta } from "./types/mw";
|
||||||
import {
|
import {
|
||||||
|
ExternalIdMovieSearchResult,
|
||||||
TMDBContentTypes,
|
TMDBContentTypes,
|
||||||
TMDBEpisodeShort,
|
TMDBEpisodeShort,
|
||||||
TMDBExternalIds,
|
TMDBExternalIds,
|
||||||
@ -195,6 +196,19 @@ export async function getExternalIds(
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getMovieFromExternalId(
|
||||||
|
imdbId: string
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
const data = await get<ExternalIdMovieSearchResult>(`/find/${imdbId}`, {
|
||||||
|
external_source: "imdb_id",
|
||||||
|
});
|
||||||
|
|
||||||
|
const movie = data.movie_results[0];
|
||||||
|
if (!movie) return undefined;
|
||||||
|
|
||||||
|
return movie.id.toString();
|
||||||
|
}
|
||||||
|
|
||||||
export function formatTMDBSearchResult(
|
export function formatTMDBSearchResult(
|
||||||
result: TMDBShowResult | TMDBMovieResult,
|
result: TMDBShowResult | TMDBMovieResult,
|
||||||
mediatype: TMDBContentTypes
|
mediatype: TMDBContentTypes
|
||||||
|
@ -282,3 +282,27 @@ export interface TMDBMovieExternalIds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type TMDBExternalIds = TMDBShowExternalIds | TMDBMovieExternalIds;
|
export type TMDBExternalIds = TMDBShowExternalIds | TMDBMovieExternalIds;
|
||||||
|
|
||||||
|
export interface ExternalIdMovieSearchResult {
|
||||||
|
movie_results: {
|
||||||
|
adult: boolean;
|
||||||
|
backdrop_path: string;
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
original_language: string;
|
||||||
|
original_title: string;
|
||||||
|
overview: string;
|
||||||
|
poster_path: string;
|
||||||
|
media_type: string;
|
||||||
|
genre_ids: number[];
|
||||||
|
popularity: number;
|
||||||
|
release_date: string;
|
||||||
|
video: boolean;
|
||||||
|
vote_average: number;
|
||||||
|
vote_count: number;
|
||||||
|
}[];
|
||||||
|
person_results: any[];
|
||||||
|
tv_results: any[];
|
||||||
|
tv_episode_results: any[];
|
||||||
|
tv_season_results: any[];
|
||||||
|
}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { lazy } from "react";
|
import { lazy, useEffect, useState } from "react";
|
||||||
import {
|
import { Redirect, Route, Switch, useLocation } from "react-router-dom";
|
||||||
Redirect,
|
|
||||||
Route,
|
|
||||||
Switch,
|
|
||||||
useHistory,
|
|
||||||
useLocation,
|
|
||||||
} from "react-router-dom";
|
|
||||||
|
|
||||||
import { convertLegacyUrl } from "@/backend/metadata/getmeta";
|
import { convertLegacyUrl } from "@/backend/metadata/getmeta";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
@ -19,86 +13,105 @@ import { NotFoundPage } from "@/views/notfound/NotFoundView";
|
|||||||
import { V2MigrationView } from "@/views/other/v2Migration";
|
import { V2MigrationView } from "@/views/other/v2Migration";
|
||||||
import { SearchView } from "@/views/search/SearchView";
|
import { SearchView } from "@/views/search/SearchView";
|
||||||
|
|
||||||
function App() {
|
// eslint-disable-next-line react/function-component-definition, react/prop-types
|
||||||
|
const LegacyUrlView: React.FC = ({ children }) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const history = useHistory();
|
const [redirectUrl, setRedirectUrl] = useState<string | null>(null);
|
||||||
|
|
||||||
// Call the conversion function and redirect if necessary
|
useEffect(() => {
|
||||||
convertLegacyUrl(location.pathname).then((convertedUrl) => {
|
// Call the conversion function and set the redirect URL if necessary
|
||||||
if (convertedUrl) {
|
convertLegacyUrl(location.pathname).then((convertedUrl) => {
|
||||||
history.replace(convertedUrl);
|
if (convertedUrl) {
|
||||||
}
|
setRedirectUrl(convertedUrl);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
if (redirectUrl) {
|
||||||
|
return <Redirect to={redirectUrl} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
|
return <>{children}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function App() {
|
||||||
return (
|
return (
|
||||||
<SettingsProvider>
|
<SettingsProvider>
|
||||||
<WatchedContextProvider>
|
<WatchedContextProvider>
|
||||||
<BookmarkContextProvider>
|
<BookmarkContextProvider>
|
||||||
<BannerContextProvider>
|
<BannerContextProvider>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Switch>
|
<LegacyUrlView>
|
||||||
{/* functional routes */}
|
<Switch>
|
||||||
<Route exact path="/v2-migration" component={V2MigrationView} />
|
{/* functional routes */}
|
||||||
<Route exact path="/">
|
<Route
|
||||||
<Redirect to={`/search/${MWMediaType.MOVIE}`} />
|
exact
|
||||||
</Route>
|
path="/v2-migration"
|
||||||
|
component={V2MigrationView}
|
||||||
|
/>
|
||||||
|
<Route exact path="/">
|
||||||
|
<Redirect to={`/search/${MWMediaType.MOVIE}`} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
{/* pages */}
|
{/* pages */}
|
||||||
<Route exact path="/media/:media" component={MediaView} />
|
<Route exact path="/media/:media" component={MediaView} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/media/:media/:season/:episode"
|
path="/media/:media/:season/:episode"
|
||||||
component={MediaView}
|
component={MediaView}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/search/:type/:query?"
|
path="/search/:type/:query?"
|
||||||
component={SearchView}
|
component={SearchView}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* other */}
|
{/* other */}
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dev"
|
path="/dev"
|
||||||
component={lazy(
|
component={lazy(
|
||||||
() => import("@/views/developer/DeveloperView")
|
() => import("@/views/developer/DeveloperView")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dev/video"
|
path="/dev/video"
|
||||||
component={lazy(
|
component={lazy(
|
||||||
() => import("@/views/developer/VideoTesterView")
|
() => import("@/views/developer/VideoTesterView")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{/* developer routes that can abuse workers are disabled in production */}
|
{/* developer routes that can abuse workers are disabled in production */}
|
||||||
{process.env.NODE_ENV === "development" ? (
|
{process.env.NODE_ENV === "development" ? (
|
||||||
<>
|
<>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dev/test"
|
path="/dev/test"
|
||||||
component={lazy(
|
component={lazy(
|
||||||
() => import("@/views/developer/TestView")
|
() => import("@/views/developer/TestView")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dev/providers"
|
path="/dev/providers"
|
||||||
component={lazy(
|
component={lazy(
|
||||||
() => import("@/views/developer/ProviderTesterView")
|
() => import("@/views/developer/ProviderTesterView")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dev/embeds"
|
path="/dev/embeds"
|
||||||
component={lazy(
|
component={lazy(
|
||||||
() => import("@/views/developer/EmbedTesterView")
|
() => import("@/views/developer/EmbedTesterView")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<Route path="*" component={NotFoundPage} />
|
<Route path="*" component={NotFoundPage} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
</LegacyUrlView>
|
||||||
</Layout>
|
</Layout>
|
||||||
</BannerContextProvider>
|
</BannerContextProvider>
|
||||||
</BookmarkContextProvider>
|
</BookmarkContextProvider>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user