- Enhances title matching accuracy when fetching Aniwatch IDs. - Prioritizes user-preferred titles and falls back to English titles. - Ensures only one fetch call is made per title if both english and userPreferred title are same. - Adds a score threshold to filter low-quality matches. - Fixes a bug where the episode list was not being returned.
105 lines
2.5 KiB
TypeScript
105 lines
2.5 KiB
TypeScript
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
import { env } from "hono/adapter";
|
|
|
|
import { fetchFromMultipleSources } from "~/libs/fetchFromMultipleSources";
|
|
import type { Env } from "~/types/env";
|
|
import { EpisodesResponse, EpisodesResponseSchema } from "~/types/episode";
|
|
import {
|
|
AniListIdQuerySchema,
|
|
ErrorResponse,
|
|
ErrorResponseSchema,
|
|
} from "~/types/schema";
|
|
|
|
import { getEpisodesFromAnify } from "./anify";
|
|
|
|
const route = createRoute({
|
|
tags: ["aniplay", "episodes"],
|
|
summary: "Fetch episodes for a title",
|
|
operationId: "fetchEpisodes",
|
|
method: "get",
|
|
path: "/{aniListId}",
|
|
request: {
|
|
params: z.object({ aniListId: AniListIdQuerySchema }),
|
|
},
|
|
responses: {
|
|
200: {
|
|
content: {
|
|
"application/json": {
|
|
schema: EpisodesResponseSchema,
|
|
},
|
|
},
|
|
description: "Returns a list of episodes",
|
|
},
|
|
500: {
|
|
content: {
|
|
"application/json": {
|
|
schema: ErrorResponseSchema,
|
|
},
|
|
},
|
|
description: "Error fetching episodes",
|
|
},
|
|
},
|
|
});
|
|
|
|
const app = new OpenAPIHono<Env>();
|
|
|
|
export function fetchEpisodesFromAllProviders(
|
|
aniListId: number,
|
|
env: Env,
|
|
): Promise<EpisodesResponse[]> {
|
|
return Promise.allSettled([
|
|
import("./aniwatch").then(({ getEpisodesFromAniwatch }) =>
|
|
getEpisodesFromAniwatch(aniListId),
|
|
),
|
|
getEpisodesFromAnify(env, aniListId),
|
|
]).then((episodeResults) =>
|
|
episodeResults
|
|
.filter((result) => result.status === "fulfilled")
|
|
.map((result) => result.value)
|
|
.filter((episodes) => !!episodes),
|
|
);
|
|
}
|
|
|
|
export function fetchEpisodes(
|
|
aniListId: number,
|
|
env: Env,
|
|
shouldRetry: boolean = false,
|
|
) {
|
|
return fetchFromMultipleSources([
|
|
() =>
|
|
import("./aniwatch").then(({ getEpisodesFromAniwatch }) =>
|
|
getEpisodesFromAniwatch(aniListId, shouldRetry),
|
|
),
|
|
() => getEpisodesFromAnify(env, aniListId),
|
|
// () =>
|
|
// import("./consumet").then(({ getEpisodesFromConsumet }) =>
|
|
// getEpisodesFromConsumet(aniListId),
|
|
// ),
|
|
]);
|
|
}
|
|
|
|
app.openapi(route, async (c) => {
|
|
const aniListId = Number(c.req.param("aniListId"));
|
|
|
|
const { result, errorOccurred } = await fetchEpisodes(
|
|
aniListId,
|
|
env(c, "workerd"),
|
|
);
|
|
|
|
if (errorOccurred || !result) {
|
|
return c.json(ErrorResponse, { status: 500 });
|
|
}
|
|
|
|
const { episodes, providerId } = result;
|
|
if (!episodes || episodes.length === 0) {
|
|
return c.json(ErrorResponse, { status: 404 });
|
|
}
|
|
|
|
return c.json({
|
|
success: true,
|
|
result: { providerId, episodes },
|
|
});
|
|
});
|
|
|
|
export default app;
|