aboutsummaryrefslogtreecommitdiff
path: root/pages/api
diff options
context:
space:
mode:
Diffstat (limited to 'pages/api')
-rw-r--r--pages/api/v2/admin/broadcast/index.js54
-rw-r--r--pages/api/v2/admin/bug-report/index.js30
-rw-r--r--pages/api/v2/episode/[id].js171
-rw-r--r--pages/api/v2/etc/recent/[page].js6
-rw-r--r--pages/api/v2/info/[id].js47
-rw-r--r--pages/api/v2/info/index.js60
-rw-r--r--pages/api/v2/pages/[...id].js34
-rw-r--r--pages/api/v2/source/index.js8
8 files changed, 287 insertions, 123 deletions
diff --git a/pages/api/v2/admin/broadcast/index.js b/pages/api/v2/admin/broadcast/index.js
index d3d3af0..470d61d 100644
--- a/pages/api/v2/admin/broadcast/index.js
+++ b/pages/api/v2/admin/broadcast/index.js
@@ -1,9 +1,17 @@
import { rateLimitStrict, redis } from "@/lib/redis";
-// import { getServerSession } from "next-auth";
-// import { authOptions } from "pages/api/auth/[...nextauth]";
+import { getServerSession } from "next-auth";
+import { authOptions } from "pages/api/auth/[...nextauth]";
export default async function handler(req, res) {
// Check if the custom header "X-Your-Custom-Header" is present and has a specific value
+ const sessions = await getServerSession(req, res, authOptions);
+
+ const admin = sessions?.user?.name === process.env.ADMIN_USERNAME;
+ // if req.method === POST and admin === false return 401
+ if (!admin && req.method === "DELETE") {
+ return res.status(401).json({ message: "Unauthorized" });
+ }
+
const customHeaderValue = req.headers["x-broadcast-key"];
if (customHeaderValue !== "get-broadcast") {
@@ -21,14 +29,40 @@ export default async function handler(req, res) {
});
}
- const getId = await redis.get(`broadcast`);
- if (getId) {
- const broadcast = JSON.parse(getId);
- return res
- .status(200)
- .json({ message: broadcast.message, startAt: broadcast.startAt });
- } else {
- return res.status(200).json({ message: "No broadcast" });
+ if (req.method === "POST") {
+ const { message, startAt = undefined, show = false } = req.body;
+ if (!message) {
+ return res.status(400).json({ message: "Message is required" });
+ }
+
+ const broadcastContent = {
+ message,
+ startAt,
+ show,
+ };
+ await redis.set(`broadcasts`, JSON.stringify(broadcastContent));
+ return res.status(200).json({ message: "Broadcast created" });
+ } else if (req.method === "DELETE") {
+ const br = await redis.get(`broadcasts`);
+ // set broadcast show as false
+ if (br) {
+ const broadcast = JSON.parse(br);
+ broadcast.show = false;
+ await redis.set(`broadcasts`, JSON.stringify(broadcast));
+ }
+ return res.status(200).json({ message: "Broadcast deleted" });
+ } else if (req.method === "GET") {
+ const getId = await redis.get(`broadcasts`);
+ if (getId) {
+ const broadcast = JSON.parse(getId);
+ return res.status(200).json({
+ message: broadcast.message,
+ startAt: broadcast.startAt,
+ show: broadcast.show,
+ });
+ } else {
+ return res.status(200).json({ message: "No broadcast" });
+ }
}
}
diff --git a/pages/api/v2/admin/bug-report/index.js b/pages/api/v2/admin/bug-report/index.js
index fc5ee77..508e6cd 100644
--- a/pages/api/v2/admin/bug-report/index.js
+++ b/pages/api/v2/admin/bug-report/index.js
@@ -8,16 +8,6 @@ export default async function handler(req, res) {
// create random id each time the endpoint is called
const id = Math.random().toString(36).substr(2, 9);
- // if (!admin) {
- // return res.status(401).json({ message: "Unauthorized" });
- // }
- const { data } = req.body;
-
- // if method is not POST return message "Method not allowed"
- if (req.method !== "POST") {
- return res.status(405).json({ message: "Method not allowed" });
- }
-
try {
if (redis) {
try {
@@ -29,16 +19,22 @@ export default async function handler(req, res) {
});
}
- const getId = await redis.get(`report:${id}`);
- if (getId) {
+ if (req.method === "POST") {
+ const { data } = req.body;
+
+ data.id = id;
+
+ await redis.set(`report:${id}`, JSON.stringify(data));
return res
.status(200)
- .json({ message: `Data already exist for id: ${id}` });
+ .json({ message: `Report has successfully sent, with Id of ${id}` });
+ } else if (req.method === "DELETE") {
+ const { reportId } = req.body;
+ await redis.del(`report:${reportId}`);
+ return res.status(200).json({ message: `Report has been deleted` });
+ } else {
+ return res.status(405).json({ message: "Method not allowed" });
}
- await redis.set(`report:${id}`, JSON.stringify(data));
- return res
- .status(200)
- .json({ message: `Report has successfully sent, with Id of ${id}` });
}
return res.status(200).json({ message: "redis is not defined" });
diff --git a/pages/api/v2/episode/[id].js b/pages/api/v2/episode/[id].js
index c1fac8b..3f1372b 100644
--- a/pages/api/v2/episode/[id].js
+++ b/pages/api/v2/episode/[id].js
@@ -3,7 +3,13 @@ import { rateLimitStrict, rateLimiterRedis, redis } from "@/lib/redis";
import appendImagesToEpisodes from "@/utils/combineImages";
import appendMetaToEpisodes from "@/utils/appendMetaToEpisodes";
-const CONSUMET_URI = process.env.API_URI;
+let CONSUMET_URI;
+
+CONSUMET_URI = process.env.API_URI;
+if (CONSUMET_URI.endsWith("/")) {
+ CONSUMET_URI = CONSUMET_URI.slice(0, -1);
+}
+
const API_KEY = process.env.API_KEY;
const isAscending = (data) => {
@@ -15,37 +21,70 @@ const isAscending = (data) => {
return true;
};
-async function fetchConsumet(id, dub) {
- try {
- if (dub) {
- return [];
+function filterData(data, type) {
+ // Filter the data based on the type (sub or dub) and providerId
+ const filteredData = data.map((item) => {
+ if (item?.map === true) {
+ if (item.episodes[type].length === 0) {
+ return null;
+ } else {
+ return {
+ ...item,
+ episodes: Object?.entries(item.episodes[type]).map(
+ ([id, episode]) => ({
+ ...episode,
+ })
+ ),
+ };
+ }
}
+ return item;
+ });
- const { data } = await axios.get(
- `${CONSUMET_URI}/meta/anilist/episodes/${id}`
- );
+ const noEmpty = filteredData.filter((i) => i !== null);
+ return noEmpty;
+}
- if (data?.message === "Anime not found" && data?.length < 1) {
- return [];
+async function fetchConsumet(id) {
+ try {
+ async function fetchData(dub) {
+ const { data } = await axios.get(
+ `${CONSUMET_URI}/meta/anilist/episodes/${id}${dub ? "?dub=true" : ""}`
+ );
+ if (data?.message === "Anime not found" && data?.length < 1) {
+ return [];
+ }
+
+ if (dub) {
+ if (!data?.some((i) => i.id.includes("dub"))) return [];
+ }
+
+ const reformatted = data.map((item) => ({
+ id: item?.id || null,
+ title: item?.title || null,
+ img: item?.image || null,
+ number: item?.number || null,
+ createdAt: item?.createdAt || null,
+ description: item?.description || null,
+ url: item?.url || null,
+ }));
+
+ return reformatted;
}
- const reformatted = data.map((item) => ({
- id: item?.id || null,
- title: item?.title || null,
- img: item?.image || null,
- number: item?.number || null,
- createdAt: item?.createdAt || null,
- description: item?.description || null,
- url: item?.url || null,
- }));
+ const [subData, dubData] = await Promise.all([
+ fetchData(),
+ fetchData(true),
+ ]);
const array = [
{
map: true,
providerId: "gogoanime",
- episodes: isAscending(reformatted)
- ? reformatted
- : reformatted.reverse(),
+ episodes: {
+ sub: isAscending(subData) ? subData : subData.reverse(),
+ dub: isAscending(dubData) ? dubData : dubData.reverse(),
+ },
},
];
@@ -73,7 +112,15 @@ async function fetchAnify(id) {
const filtered = data.filter(
(item) => item.providerId !== "animepahe" && item.providerId !== "kass"
);
-
+ // const modifiedData = filtered.map((provider) => {
+ // if (provider.providerId === "gogoanime") {
+ // const reversedEpisodes = [...provider.episodes].reverse();
+ // return { ...provider, episodes: reversedEpisodes };
+ // }
+ // return provider;
+ // });
+
+ // return modifiedData;
return filtered;
} catch (error) {
console.error("Error fetching and processing data:", error.message);
@@ -81,12 +128,16 @@ async function fetchAnify(id) {
}
}
-async function fetchCoverImage(id) {
+async function fetchCoverImage(id, available = false) {
try {
if (!process.env.API_KEY) {
return [];
}
+ if (available) {
+ return null;
+ }
+
const { data } = await axios.get(
`https://api.anify.tv/content-metadata/${id}?apikey=${API_KEY}`
);
@@ -95,7 +146,9 @@ async function fetchCoverImage(id) {
return [];
}
- return data;
+ const getData = data[0].data;
+
+ return getData;
} catch (error) {
console.error("Error fetching and processing data:", error.message);
return [];
@@ -124,10 +177,10 @@ export default async function handler(req, res) {
}
if (refresh) {
- await redis.del(id);
+ await redis.del(`episode:${id}`);
console.log("deleted cache");
} else {
- cached = await redis.get(id);
+ cached = await redis.get(`episode:${id}`);
console.log("using redis");
}
@@ -136,49 +189,75 @@ export default async function handler(req, res) {
if (cached && !refresh) {
if (dub) {
- const filtered = JSON.parse(cached).filter((item) =>
- item.episodes.some((epi) => epi.hasDub === true)
+ const filteredData = filterData(JSON.parse(cached), "dub");
+
+ let filtered = filteredData.filter((item) =>
+ item?.episodes?.some((epi) => epi.hasDub !== false)
);
+
+ if (meta) {
+ filtered = await appendMetaToEpisodes(filtered, JSON.parse(meta));
+ }
+
return res.status(200).json(filtered);
} else {
- return res.status(200).json(JSON.parse(cached));
+ const filteredData = filterData(JSON.parse(cached), "sub");
+
+ let filtered = filteredData;
+
+ if (meta) {
+ filtered = await appendMetaToEpisodes(filteredData, JSON.parse(meta));
+ }
+
+ return res.status(200).json(filtered);
}
} else {
const [consumet, anify, cover] = await Promise.all([
fetchConsumet(id, dub),
fetchAnify(id),
- fetchCoverImage(id),
+ fetchCoverImage(id, meta),
]);
- const hasImage = consumet.map((i) =>
- i.episodes.some(
- (e) => e.img !== null || !e.img.includes("https://s4.anilist.co/")
- )
- );
+ // const hasImage = consumet.map((i) =>
+ // i.episodes?.sub?.some(
+ // (e) => e.img !== null || !e.img.includes("https://s4.anilist.co/")
+ // )
+ // );
+
+ let subDub = "sub";
+ if (dub) {
+ subDub = "dub";
+ }
- const rawData = [...consumet, ...(anify[0]?.data ?? [])];
+ const rawData = [...consumet, ...anify];
- let data = rawData;
+ const filteredData = filterData(rawData, subDub);
+
+ let data = filteredData;
if (meta) {
- data = await appendMetaToEpisodes(rawData, JSON.parse(meta));
- } else if (cover && cover?.length > 0 && !hasImage.includes(true))
- data = await appendImagesToEpisodes(rawData, cover);
+ data = await appendMetaToEpisodes(filteredData, JSON.parse(meta));
+ } else if (cover && !cover.some((e) => e.img === null)) {
+ await redis.set(`meta:${id}`, JSON.stringify(cover));
+ data = await appendMetaToEpisodes(filteredData, cover);
+ }
if (redis && cacheTime !== null) {
await redis.set(
- id,
- JSON.stringify(data.filter((i) => i.episodes.length > 0)),
+ `episode:${id}`,
+ JSON.stringify(rawData),
"EX",
cacheTime
);
}
if (dub) {
- const filtered = data.filter((item) =>
- item.episodes.some((epi) => epi.hasDub === true)
+ const filtered = data.filter(
+ (item) => !item.episodes.some((epi) => epi.hasDub === false)
);
- return res.status(200).json(filtered);
+ return res
+ .status(200)
+ .json(filtered.filter((i) => i.episodes.length > 0));
}
console.log("fresh data");
diff --git a/pages/api/v2/etc/recent/[page].js b/pages/api/v2/etc/recent/[page].js
index 6727787..b1bda0f 100644
--- a/pages/api/v2/etc/recent/[page].js
+++ b/pages/api/v2/etc/recent/[page].js
@@ -1,6 +1,10 @@
import { rateLimiterRedis, redis } from "@/lib/redis";
-const API_URL = process.env.API_URI;
+let API_URL;
+API_URL = process.env.API_URI;
+if (API_URL.endsWith("/")) {
+ API_URL = API_URL.slice(0, -1);
+}
export default async function handler(req, res) {
try {
diff --git a/pages/api/v2/info/[id].js b/pages/api/v2/info/[id].js
deleted file mode 100644
index 243756c..0000000
--- a/pages/api/v2/info/[id].js
+++ /dev/null
@@ -1,47 +0,0 @@
-import axios from "axios";
-import { rateLimiterRedis, redis } from "@/lib/redis";
-
-const API_KEY = process.env.API_KEY;
-
-export async function fetchInfo(id) {
- try {
- const { data } = await axios.get(
- `https://api.anify.tv/info/${id}?apikey=${API_KEY}`
- );
- return data;
- } catch (error) {
- console.error("Error fetching data:", error);
- return null;
- }
-}
-
-export default async function handler(req, res) {
- const id = req.query.id;
- let cached;
- if (redis) {
- try {
- const ipAddress = req.socket.remoteAddress;
- await rateLimiterRedis.consume(ipAddress);
- } catch (error) {
- return res.status(429).json({
- error: `Too Many Requests, retry after ${error.msBeforeNext / 1000}`,
- });
- }
- cached = await redis.get(id);
- }
- if (cached) {
- // console.log("Using cached data");
- return res.status(200).json(JSON.parse(cached));
- } else {
- const data = await fetchInfo(id);
- if (data) {
- // console.log("Setting cache");
- if (redis) {
- await redis.set(id, JSON.stringify(data), "EX", 60 * 10);
- }
- return res.status(200).json(data);
- } else {
- return res.status(404).json({ message: "Schedule not found" });
- }
- }
-}
diff --git a/pages/api/v2/info/index.js b/pages/api/v2/info/index.js
new file mode 100644
index 0000000..95770bd
--- /dev/null
+++ b/pages/api/v2/info/index.js
@@ -0,0 +1,60 @@
+import { redis } from "@/lib/redis";
+import axios from "axios";
+
+const API_KEY = process.env.API_KEY;
+
+export async function fetchInfo(id) {
+ try {
+ // console.log(id);
+ const { data } = await axios
+ .get(`https://api.anify.tv/info/${id}?apikey=${API_KEY}`)
+ .catch((err) => {
+ return {
+ data: null,
+ };
+ });
+
+ if (!data) {
+ return null;
+ }
+
+ const { data: Chapters } = await axios.get(
+ `https://api.anify.tv/chapters/${data.id}?apikey=${API_KEY}`
+ );
+
+ if (!Chapters) {
+ return null;
+ }
+
+ return { id: data.id, chapters: Chapters };
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ return null;
+ }
+}
+
+export default async function handler(req, res) {
+ //const [romaji, english, native] = req.query.title;
+ const { id } = req.query;
+ try {
+ let cached;
+ // const data = await fetchInfo(id);
+ cached = await redis.get(`manga:${id}`);
+
+ if (cached) {
+ return res.status(200).json(JSON.parse(cached));
+ }
+
+ const manga = await fetchInfo(id);
+
+ if (!manga) {
+ return res.status(404).json({ error: "Manga not found" });
+ }
+
+ await redis.set(`manga:${id}`, JSON.stringify(manga), "ex", 60 * 60 * 24);
+
+ res.status(200).json(manga);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+}
diff --git a/pages/api/v2/pages/[...id].js b/pages/api/v2/pages/[...id].js
new file mode 100644
index 0000000..a9fe0f9
--- /dev/null
+++ b/pages/api/v2/pages/[...id].js
@@ -0,0 +1,34 @@
+import axios from "axios";
+
+async function fetchData(id, number, provider, readId) {
+ try {
+ const { data } = await axios.get(
+ `https://api.anify.tv/pages?id=${id}&chapterNumber=${number}&providerId=${provider}&readId=${encodeURIComponent(
+ readId
+ )}`
+ );
+
+ if (!data) {
+ return null;
+ }
+
+ return data;
+ } catch (error) {
+ return null;
+ }
+}
+
+export default async function handler(req, res) {
+ const [id, number, provider, readId] = req.query.id;
+
+ try {
+ const data = await fetchData(id, number, provider, readId);
+ // if (!data) {
+ // return res.status(400).json({ error: "Invalid query" });
+ // }
+
+ return res.status(200).json(data);
+ } catch (error) {
+ return res.status(500).json({ error: error.message });
+ }
+}
diff --git a/pages/api/v2/source/index.js b/pages/api/v2/source/index.js
index f15e47d..9ec6082 100644
--- a/pages/api/v2/source/index.js
+++ b/pages/api/v2/source/index.js
@@ -1,7 +1,11 @@
import { rateLimiterRedis, redis } from "@/lib/redis";
import axios from "axios";
-const CONSUMET_URI = process.env.API_URI;
+let CONSUMET_URI;
+CONSUMET_URI = process.env.API_URI;
+if (CONSUMET_URI.endsWith("/")) {
+ CONSUMET_URI = CONSUMET_URI.slice(0, -1);
+}
const API_KEY = process.env.API_KEY;
async function consumetSource(id) {
@@ -25,7 +29,7 @@ async function anifySource(providerId, watchId, episode, id, sub) {
);
return data;
} catch (error) {
- return null;
+ return { error: error.message, status: error.response.status };
}
}