diff --git a/src/controllers/episodes/getByAniListId/index.ts b/src/controllers/episodes/getByAniListId/index.ts index 1e0d83a..6e531f2 100644 --- a/src/controllers/episodes/getByAniListId/index.ts +++ b/src/controllers/episodes/getByAniListId/index.ts @@ -3,7 +3,7 @@ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; import { fetchFromMultipleSources } from "~/libs/fetchFromMultipleSources"; import { readEnvVariable } from "~/libs/readEnvVariable"; import type { Env } from "~/types/env"; -import { EpisodesResponseSchema } from "~/types/episode"; +import { EpisodesResponse, EpisodesResponseSchema } from "~/types/episode"; import { AniListIdQuerySchema, ErrorResponse, @@ -43,6 +43,23 @@ const route = createRoute({ const app = new OpenAPIHono(); +export function fetchEpisodesFromAllProviders( + aniListId: number, + isAnifyEnabled: boolean, +): Promise { + return Promise.allSettled([ + import("./aniwatch").then(({ getEpisodesFromAniwatch }) => + getEpisodesFromAniwatch(aniListId), + ), + getEpisodesFromAnify(isAnifyEnabled, aniListId), + ]).then((episodeResults) => + episodeResults + .filter((result) => result.status === "fulfilled") + .map((result) => result.value) + .filter((episodes) => !!episodes), + ); +} + export function fetchEpisodes(aniListId: number, isAnifyEnabled: boolean) { return fetchFromMultipleSources([ () => getEpisodesFromAnify(isAnifyEnabled, aniListId), diff --git a/src/controllers/internal/new-episode/index.ts b/src/controllers/internal/new-episode/index.ts index 9497b24..a93e39c 100644 --- a/src/controllers/internal/new-episode/index.ts +++ b/src/controllers/internal/new-episode/index.ts @@ -5,7 +5,10 @@ import { env } from "hono/adapter"; import mapKeys from "lodash.mapkeys"; import { z } from "zod"; -import { fetchEpisodes } from "~/controllers/episodes/getByAniListId"; +import { + fetchEpisodes, + fetchEpisodesFromAllProviders, +} from "~/controllers/episodes/getByAniListId"; import { fetchEpisodeUrl } from "~/controllers/episodes/getEpisodeUrl"; import { Case, changeStringCase } from "~/libs/changeStringCase"; import type { AdminSdkCredentials } from "~/libs/fcm/getGoogleAuthToken"; @@ -59,11 +62,11 @@ app.post( env(c, "workerd"), "ENABLE_ANIFY", ); - const { - errorOccurred: fetchEpisodesErrorOccurred, - result: fetchEpisodesResult, - } = await fetchEpisodes(aniListId, isAnifyEnabled); - if (fetchEpisodesErrorOccurred) { + const fetchEpisodesResult = await fetchEpisodesFromAllProviders( + aniListId, + isAnifyEnabled, + ); + if (fetchEpisodesResult.length === 0) { console.error(`Failed to fetch episodes for title ${aniListId}`); return c.json( { success: false, message: "Failed to fetch episodes" }, @@ -71,31 +74,45 @@ app.post( ); } - const { episodes, providerId } = fetchEpisodesResult; - const episode = episodes.find( - (episode) => episode.number === episodeNumber, - ); - if (!episode) { - return c.json({ success: false, message: "Episode not found" }, 404); - } - + let episodes; let fetchUrlResult; - try { - fetchUrlResult = await fetchEpisodeUrl( + + for (const { + episodes: episodesResult, + providerId, + } of fetchEpisodesResult) { + const episode = episodesResult.find( + (episode) => episode.number === episodeNumber, + ); + if (!episode) { + continue; + } + episodes = episodesResult; + + const urlResult = await fetchEpisodeUrl( providerId, episode.id, aniListId, isAnifyEnabled, ); if (!fetchUrlResult) { - console.error(`Failed to fetch episode URL for episode ${episode.id}`); - return c.json( - { success: false, message: "Episode URL not found" }, - 404, - ); + continue; } - } catch (error) { - console.error(`Failed to fetch episode URL for episode ${episode.id}`); + + fetchUrlResult = urlResult; + break; + } + + if (!episodes) { + console.error(`Failed to fetch episodes for title ${aniListId}`); + return c.json( + { success: false, message: "Failed to fetch episodes" }, + 500, + ); + } + + if (!fetchUrlResult) { + console.error(`Failed to fetch episode URL for episode`); return c.json( { success: false, message: "Failed to fetch episode URL" }, 500,