aboutsummaryrefslogtreecommitdiff
path: root/src/controllers
diff options
context:
space:
mode:
authorRitesh Ghosh <[email protected]>2024-10-06 01:13:23 +0530
committerGitHub <[email protected]>2024-10-06 01:13:23 +0530
commit46f688ac12a99b8fb145b0745dd4cc6babff1e1e (patch)
tree9560dd057822069a2162ef01a1118f3ac05e6d07 /src/controllers
parent55810ccf2372209f9b46c96ac12811e5a05f7961 (diff)
downloadaniwatch-api-46f688ac12a99b8fb145b0745dd4cc6babff1e1e.tar.xz
aniwatch-api-46f688ac12a99b8fb145b0745dd4cc6babff1e1e.zip
Aniwatch API Version 2 (#66)
BREAKING CHANGE: * chore: remove files that are not necessary for api v2 * test: update existing tests to use pkg * feat: organized aniwatch api envs and add more info about them * feat: update tsconfig to include strict noUnsed params * feat(api homepage): revamp api home page * feat: update wani kuni image * feat: add dot img * feat: use hono cors * feat: use hono rate limiter * build: remove unnecessary deps, add ones needed and update description * feat: add hianime routes and their handlers * feat: update vercel deployment file * docs: update logo and scraper docs, add envs section * feat: update main server file * feat: update peronal deployments caution section
Diffstat (limited to 'src/controllers')
-rw-r--r--src/controllers/animeAboutInfo.controller.ts31
-rw-r--r--src/controllers/animeCategory.controller.ts39
-rw-r--r--src/controllers/animeEpisodeSrcs.controller.ts75
-rw-r--r--src/controllers/animeEpisodes.controller.ts31
-rw-r--r--src/controllers/animeGenre.controller.ts37
-rw-r--r--src/controllers/animeProducer.controller.ts37
-rw-r--r--src/controllers/animeSearch.controller.ts57
-rw-r--r--src/controllers/animeSearchSuggestion.controller.ts31
-rw-r--r--src/controllers/episodeServers.controller.ts30
-rw-r--r--src/controllers/estimatedSchedule.controller.ts36
-rw-r--r--src/controllers/homePage.controller.ts18
-rw-r--r--src/controllers/index.ts25
12 files changed, 0 insertions, 447 deletions
diff --git a/src/controllers/animeAboutInfo.controller.ts b/src/controllers/animeAboutInfo.controller.ts
deleted file mode 100644
index 6d50b50..0000000
--- a/src/controllers/animeAboutInfo.controller.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeAnimeAboutInfo } from "../parsers/index.js";
-import { type AnimeAboutInfoQueryParams } from "../types/controllers/index.js";
-
-// /anime/info?id=${anime-id}
-const getAnimeAboutInfo: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeAnimeAboutInfo>>,
- unknown,
- AnimeAboutInfoQueryParams
-> = async (req, res, next) => {
- try {
- const animeId = req.query.id
- ? decodeURIComponent(req.query.id as string)
- : null;
-
- if (animeId === null) {
- throw createHttpError.BadRequest("Anime unique id required");
- }
-
- const data = await scrapeAnimeAboutInfo(animeId);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeAboutInfo;
diff --git a/src/controllers/animeCategory.controller.ts b/src/controllers/animeCategory.controller.ts
deleted file mode 100644
index 373b8e3..0000000
--- a/src/controllers/animeCategory.controller.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import createHttpError from "http-errors";
-import type { RequestHandler } from "express";
-import type { AnimeCategories } from "../types/anime.js";
-import { scrapeAnimeCategory } from "../parsers/index.js";
-import type {
- CategoryAnimePathParams,
- CategoryAnimeQueryParams,
-} from "../types/controllers/index.js";
-
-// /anime/:category?page=${page}
-const getAnimeCategory: RequestHandler<
- CategoryAnimePathParams,
- Awaited<ReturnType<typeof scrapeAnimeCategory>>,
- unknown,
- CategoryAnimeQueryParams
-> = async (req, res, next) => {
- try {
- const category = req.params.category
- ? decodeURIComponent(req.params.category)
- : null;
-
- const page: number = req.query.page
- ? Number(decodeURIComponent(req.query?.page as string))
- : 1;
-
- if (category === null) {
- throw createHttpError.BadRequest("category required");
- }
-
- const data = await scrapeAnimeCategory(category as AnimeCategories, page);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeCategory;
diff --git a/src/controllers/animeEpisodeSrcs.controller.ts b/src/controllers/animeEpisodeSrcs.controller.ts
deleted file mode 100644
index 6190ce5..0000000
--- a/src/controllers/animeEpisodeSrcs.controller.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import axios from "axios";
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { type CheerioAPI, load } from "cheerio";
-import { scrapeAnimeEpisodeSources } from "../parsers/index.js";
-import { USER_AGENT_HEADER, SRC_BASE_URL } from "../utils/constants.js";
-import { type AnimeServers, Servers } from "../types/anime.js";
-import { type AnimeEpisodeSrcsQueryParams } from "../types/controllers/index.js";
-
-type AnilistID = number | null;
-type MalID = number | null;
-
-// /anime/episode-srcs?id=${episodeId}?server=${server}&category=${category (dub or sub)}
-const getAnimeEpisodeSources: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeAnimeEpisodeSources & AnilistID>>,
- unknown,
- AnimeEpisodeSrcsQueryParams
-> = async (req, res, next) => {
- try {
- const episodeId = req.query.id ? decodeURIComponent(req.query.id) : null;
-
- const server = (
- req.query.server
- ? decodeURIComponent(req.query.server)
- : Servers.VidStreaming
- ) as AnimeServers;
-
- const category = (
- req.query.category ? decodeURIComponent(req.query.category) : "sub"
- ) as "sub" | "dub";
-
- if (episodeId === null) {
- throw createHttpError.BadRequest("Anime episode id required");
- }
-
- let malID: MalID;
- let anilistID: AnilistID;
- const animeURL = new URL(episodeId?.split("?ep=")[0], SRC_BASE_URL)?.href;
-
- const [episodeSrcData, animeSrc] = await Promise.all([
- scrapeAnimeEpisodeSources(episodeId, server, category),
- axios.get(animeURL, {
- headers: {
- Referer: SRC_BASE_URL,
- "User-Agent": USER_AGENT_HEADER,
- "X-Requested-With": "XMLHttpRequest",
- },
- }),
- ]);
-
- const $: CheerioAPI = load(animeSrc?.data);
-
- try {
- anilistID = Number(
- JSON.parse($("body")?.find("#syncData")?.text())?.anilist_id
- );
- malID = Number(JSON.parse($("body")?.find("#syncData")?.text())?.mal_id);
- } catch (err) {
- anilistID = null;
- malID = null;
- }
-
- res.status(200).json({
- ...episodeSrcData,
- anilistID,
- malID,
- });
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeEpisodeSources;
diff --git a/src/controllers/animeEpisodes.controller.ts b/src/controllers/animeEpisodes.controller.ts
deleted file mode 100644
index cf815f5..0000000
--- a/src/controllers/animeEpisodes.controller.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeAnimeEpisodes } from "../parsers/index.js";
-import { type AnimeEpisodePathParams } from "../types/controllers/index.js";
-
-// /anime/episodes/${anime-id}
-const getAnimeEpisodes: RequestHandler<
- AnimeEpisodePathParams,
- Awaited<ReturnType<typeof scrapeAnimeEpisodes>>,
- unknown,
- unknown
-> = async (req, res, next) => {
- try {
- const animeId = req.params.animeId
- ? decodeURIComponent(req.params.animeId)
- : null;
-
- if (animeId === null) {
- throw createHttpError.BadRequest("Anime Id required");
- }
-
- const data = await scrapeAnimeEpisodes(animeId);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeEpisodes;
diff --git a/src/controllers/animeGenre.controller.ts b/src/controllers/animeGenre.controller.ts
deleted file mode 100644
index 486b4c7..0000000
--- a/src/controllers/animeGenre.controller.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeGenreAnime } from "../parsers/index.js";
-import type {
- GenreAnimePathParams,
- GenreAnimeQueryParams,
-} from "../types/controllers/index.js";
-
-// /anime/genre/${name}?page=${page}
-const getGenreAnime: RequestHandler<
- GenreAnimePathParams,
- Awaited<ReturnType<typeof scrapeGenreAnime>>,
- unknown,
- GenreAnimeQueryParams
-> = async (req, res, next) => {
- try {
- const name: string | null = req.params.name
- ? decodeURIComponent(req.params.name as string)
- : null;
-
- const page: number = req.query.page
- ? Number(decodeURIComponent(req.query?.page as string))
- : 1;
-
- if (name === null) {
- throw createHttpError.BadRequest("Anime genre required");
- }
-
- const data = await scrapeGenreAnime(name, page);
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getGenreAnime;
diff --git a/src/controllers/animeProducer.controller.ts b/src/controllers/animeProducer.controller.ts
deleted file mode 100644
index 3ebcd8a..0000000
--- a/src/controllers/animeProducer.controller.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeProducerAnimes } from "../parsers/index.js";
-import type {
- AnimeProducerPathParams,
- AnimeProducerQueryParams,
-} from "../types/controllers/index.js";
-
-// /anime/producer/${name}?page=${page}
-const getProducerAnimes: RequestHandler<
- AnimeProducerPathParams,
- Awaited<ReturnType<typeof scrapeProducerAnimes>>,
- unknown,
- AnimeProducerQueryParams
-> = async (req, res, next) => {
- try {
- const name: string | null = req.params.name
- ? decodeURIComponent(req.params.name as string)
- : null;
-
- const page: number = req.query.page
- ? Number(decodeURIComponent(req.query?.page as string))
- : 1;
-
- if (name === null) {
- throw createHttpError.BadRequest("Anime producer name required");
- }
-
- const data = await scrapeProducerAnimes(name, page);
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getProducerAnimes;
diff --git a/src/controllers/animeSearch.controller.ts b/src/controllers/animeSearch.controller.ts
deleted file mode 100644
index 8937b0a..0000000
--- a/src/controllers/animeSearch.controller.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeAnimeSearch } from "../parsers/index.js";
-import type {
- SearchFilters,
- AnimeSearchQueryParams,
-} from "../types/controllers/index.js";
-
-const searchFilters: Record<string, boolean> = {
- filter: true,
- type: true,
- status: true,
- rated: true,
- score: true,
- season: true,
- language: true,
- start_date: true,
- end_date: true,
- sort: true,
- genres: true,
-} as const;
-
-// /anime/search?q=${query}&page=${page}
-const getAnimeSearch: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeAnimeSearch>>,
- unknown,
- AnimeSearchQueryParams
-> = async (req, res, next) => {
- try {
- let { q: query, page, ...filters } = req.query;
-
- query = query ? decodeURIComponent(query) : undefined;
- const pageNo = page ? Number(decodeURIComponent(page as string)) : 1;
-
- if (query === undefined) {
- throw createHttpError.BadRequest("Search keyword required");
- }
-
- const parsedFilters: SearchFilters = {};
- for (const key in filters) {
- if (searchFilters[key]) {
- parsedFilters[key as keyof SearchFilters] =
- filters[key as keyof SearchFilters];
- }
- }
-
- const data = await scrapeAnimeSearch(query, pageNo, parsedFilters);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeSearch;
diff --git a/src/controllers/animeSearchSuggestion.controller.ts b/src/controllers/animeSearchSuggestion.controller.ts
deleted file mode 100644
index ed8784f..0000000
--- a/src/controllers/animeSearchSuggestion.controller.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeAnimeSearchSuggestion } from "../parsers/index.js";
-import { type AnimeSearchSuggestQueryParams } from "../types/controllers/index.js";
-
-// /anime/search/suggest?q=${query}
-const getAnimeSearchSuggestion: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeAnimeSearchSuggestion>>,
- unknown,
- AnimeSearchSuggestQueryParams
-> = async (req, res, next) => {
- try {
- const query: string | null = req.query.q
- ? decodeURIComponent(req.query.q as string)
- : null;
-
- if (query === null) {
- throw createHttpError.BadRequest("Search keyword required");
- }
-
- const data = await scrapeAnimeSearchSuggestion(query);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getAnimeSearchSuggestion;
diff --git a/src/controllers/episodeServers.controller.ts b/src/controllers/episodeServers.controller.ts
deleted file mode 100644
index 16e1ca5..0000000
--- a/src/controllers/episodeServers.controller.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeEpisodeServers } from "../parsers/index.js";
-import { type EpisodeServersQueryParams } from "../types/controllers/index.js";
-
-// /anime/servers?episodeId=${id}
-const getEpisodeServers: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeEpisodeServers>>,
- unknown,
- EpisodeServersQueryParams
-> = async (req, res, next) => {
- try {
- const episodeId = req.query.episodeId
- ? decodeURIComponent(req.query?.episodeId as string)
- : null;
-
- if (episodeId === null) {
- throw createHttpError.BadRequest("Episode id required");
- }
-
- const data = await scrapeEpisodeServers(episodeId);
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getEpisodeServers;
diff --git a/src/controllers/estimatedSchedule.controller.ts b/src/controllers/estimatedSchedule.controller.ts
deleted file mode 100644
index fef2516..0000000
--- a/src/controllers/estimatedSchedule.controller.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import createHttpError from "http-errors";
-import { type RequestHandler } from "express";
-import { scrapeEstimatedSchedule } from "../parsers/index.js";
-import { type EstimatedScheduleQueryParams } from "../types/controllers/index.js";
-
-// /anime/schedule?date=${date}
-const getEstimatedSchedule: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeEstimatedSchedule>>,
- unknown,
- EstimatedScheduleQueryParams
-> = async (req, res, next) => {
- try {
- const dateQuery = req.query.date
- ? decodeURIComponent(req.query.date as string)
- : null;
-
- if (dateQuery === null) {
- throw createHttpError.BadRequest("Date payload required");
- }
- if (!/^\d{4}-\d{2}-\d{2}$/.test(dateQuery)) {
- throw createHttpError.BadRequest(
- "Invalid date payload format. Months and days must have 2 digits"
- );
- }
-
- const data = await scrapeEstimatedSchedule(dateQuery);
-
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getEstimatedSchedule;
diff --git a/src/controllers/homePage.controller.ts b/src/controllers/homePage.controller.ts
deleted file mode 100644
index 36e1fe9..0000000
--- a/src/controllers/homePage.controller.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { type RequestHandler } from "express";
-import { scrapeHomePage } from "../parsers/index.js";
-
-// /anime/home
-const getHomePageInfo: RequestHandler<
- unknown,
- Awaited<ReturnType<typeof scrapeHomePage>>
-> = async (req, res, next) => {
- try {
- const data = await scrapeHomePage();
- res.status(200).json(data);
- } catch (err: any) {
- console.error(err);
- next(err);
- }
-};
-
-export default getHomePageInfo;
diff --git a/src/controllers/index.ts b/src/controllers/index.ts
deleted file mode 100644
index 6e90440..0000000
--- a/src/controllers/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import getGenreAnime from "./animeGenre.controller.js";
-import getHomePageInfo from "./homePage.controller.js";
-import getAnimeSearch from "./animeSearch.controller.js";
-import getAnimeEpisodes from "./animeEpisodes.controller.js";
-import getAnimeCategory from "./animeCategory.controller.js";
-import getProducerAnimes from "./animeProducer.controller.js";
-import getEpisodeServers from "./episodeServers.controller.js";
-import getAnimeAboutInfo from "./animeAboutInfo.controller.js";
-import getEstimatedSchedule from "./estimatedSchedule.controller.js";
-import getAnimeEpisodeSources from "./animeEpisodeSrcs.controller.js";
-import getAnimeSearchSuggestion from "./animeSearchSuggestion.controller.js";
-
-export {
- getGenreAnime,
- getAnimeSearch,
- getHomePageInfo,
- getAnimeEpisodes,
- getAnimeCategory,
- getEpisodeServers,
- getProducerAnimes,
- getAnimeAboutInfo,
- getEstimatedSchedule,
- getAnimeEpisodeSources,
- getAnimeSearchSuggestion,
-};