diff options
| author | Factiven <[email protected]> | 2023-10-28 22:50:51 +0700 |
|---|---|---|
| committer | Factiven <[email protected]> | 2023-10-28 22:50:51 +0700 |
| commit | a25282429761ff0670a50fd74f8c24bdb38e728c (patch) | |
| tree | 0cd14840e665f1912842967de7427a31556190e6 /pages | |
| parent | Update v4.2.3 (diff) | |
| download | moopa-a25282429761ff0670a50fd74f8c24bdb38e728c.tar.xz moopa-a25282429761ff0670a50fd74f8c24bdb38e728c.zip | |
Update v4.2.4
Diffstat (limited to 'pages')
| -rw-r--r-- | pages/api/v2/episode/[id].js | 44 | ||||
| -rw-r--r-- | pages/api/v2/etc/recent/[page].js | 45 | ||||
| -rw-r--r-- | pages/en/anime/recent.js | 10 |
3 files changed, 76 insertions, 23 deletions
diff --git a/pages/api/v2/episode/[id].js b/pages/api/v2/episode/[id].js index 8d0f443..0e747d6 100644 --- a/pages/api/v2/episode/[id].js +++ b/pages/api/v2/episode/[id].js @@ -1,5 +1,5 @@ import axios from "axios"; -import { rateLimitStrict, rateLimiterRedis, redis } from "@/lib/redis"; +import { rateLimiterRedis, rateSuperStrict, redis } from "@/lib/redis"; import appendMetaToEpisodes from "@/utils/appendMetaToEpisodes"; let CONSUMET_URI; @@ -159,16 +159,26 @@ export default async function handler(req, res) { let cached; let meta; + let headers; if (redis) { try { const ipAddress = req.socket.remoteAddress; refresh - ? await rateLimitStrict.consume(ipAddress) + ? await rateSuperStrict.consume(ipAddress) : await rateLimiterRedis.consume(ipAddress); + + headers = refresh + ? await rateSuperStrict.get(ipAddress) + : await rateLimiterRedis.get(ipAddress); + + console.log(headers); } catch (error) { return res.status(429).json({ - error: `Too Many Requests, retry after ${error.msBeforeNext / 1000}`, + error: `Too Many Requests, retry after ${getTimeFromMs( + error.msBeforeNext + )}`, + remaining: error.remainingPoints, }); } @@ -195,6 +205,9 @@ export default async function handler(req, res) { filtered = await appendMetaToEpisodes(filtered, JSON.parse(meta)); } + res.setHeader("X-RateLimit-Remaining", headers.remainingPoints); + res.setHeader("X-RateLimit-BeforeReset", headers.msBeforeNext); + return res.status(200).json(filtered); } else { const filteredData = filterData(JSON.parse(cached), "sub"); @@ -205,7 +218,10 @@ export default async function handler(req, res) { filtered = await appendMetaToEpisodes(filteredData, JSON.parse(meta)); } - return res.status(200).json(filtered); + res.setHeader("X-RateLimit-Remaining", headers.remainingPoints); + res.setHeader("X-RateLimit-BeforeReset", headers.msBeforeNext); + + return res.status(200).send(filtered); } } else { const [consumet, anify, cover] = await Promise.all([ @@ -256,8 +272,26 @@ export default async function handler(req, res) { .json(filtered.filter((i) => i.episodes.length > 0)); } - console.log("fresh data"); + if (redis) { + res.setHeader("X-RateLimit-Limit", refresh ? 1 : 50); + res.setHeader("X-RateLimit-Remaining", headers.remainingPoints); + res.setHeader("X-RateLimit-BeforeReset", headers.msBeforeNext); + } return res.status(200).json(data.filter((i) => i.episodes.length > 0)); } } + +function getTimeFromMs(time) { + const timeInSeconds = time / 1000; + + if (timeInSeconds >= 3600) { + const hours = Math.floor(timeInSeconds / 3600); + return `${hours} hour${hours > 1 ? "s" : ""}`; + } else if (timeInSeconds >= 60) { + const minutes = Math.floor(timeInSeconds / 60); + return `${minutes} minute${minutes > 1 ? "s" : ""}`; + } else { + return `${timeInSeconds} second${timeInSeconds > 1 ? "s" : ""}`; + } +} diff --git a/pages/api/v2/etc/recent/[page].js b/pages/api/v2/etc/recent/[page].js index e21c38e..2ff22ea 100644 --- a/pages/api/v2/etc/recent/[page].js +++ b/pages/api/v2/etc/recent/[page].js @@ -1,4 +1,4 @@ -import { rateLimiterRedis, redis } from "@/lib/redis"; +import { rateLimitStrict, redis } from "@/lib/redis"; let API_URL; API_URL = process.env.API_URI || null; @@ -11,31 +11,46 @@ export default async function handler(req, res) { if (redis) { try { const ipAddress = req.socket.remoteAddress; - await rateLimiterRedis.consume(ipAddress); + await rateLimitStrict.consume(ipAddress); } catch (error) { return res.status(429).json({ error: `Too Many Requests, retry after ${error.msBeforeNext / 1000}`, }); } } - const page = req.query.page || 1; - var hasNextPage = true; - var datas = []; + let cache; - async function fetchData(page) { - const data = await fetch( - `${API_URL}/meta/anilist/recent-episodes?page=${page}&perPage=30&provider=gogoanime` - ).then((res) => res.json()); - - const filtered = data?.results?.filter((i) => i.type !== "ONA"); - hasNextPage = data?.hasNextPage; - datas = filtered; + if (redis) { + cache = await redis.get(`recent-episode`); } - await fetchData(page); + if (cache) { + return res.status(200).json({ results: JSON.parse(cache) }); + } else { + const page = req.query.page || 1; + + var hasNextPage = true; + var datas = []; + + async function fetchData(page) { + const data = await fetch( + `https://api.anify.tv/recent?type=anime&page=${page}&perPage=45` + ).then((res) => res.json()); + + // const filtered = data?.results?.filter((i) => i.type !== "ONA"); + // hasNextPage = data?.hasNextPage; + datas = data; + } + + await fetchData(page); - return res.status(200).json({ hasNextPage, results: datas }); + if (redis) { + await redis.set(`recent-episode`, JSON.stringify(datas), "EX", 60 * 60); + } + + return res.status(200).json({ results: datas }); + } } catch (error) { res.status(500).json({ error }); } diff --git a/pages/en/anime/recent.js b/pages/en/anime/recent.js index 400e926..4a8111d 100644 --- a/pages/en/anime/recent.js +++ b/pages/en/anime/recent.js @@ -8,6 +8,7 @@ import { getServerSession } from "next-auth"; import { authOptions } from "../../api/auth/[...nextauth]"; import Image from "next/image"; import MobileNav from "@/components/shared/MobileNav"; +import { truncateImgUrl } from "@/utils/imageUtils"; export async function getServerSideProps(context) { const session = await getServerSession(context.req, context.res, authOptions); @@ -99,7 +100,7 @@ export default function Recent({ sessions }) { <div className="w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] object-cover rounded opacity-90 z-20"> <div className="absolute bg-gradient-to-b from-black/30 to-transparent from-5% to-30% top-0 z-30 w-[140px] h-[190px] lg:w-[170px] lg:h-[230px] rounded" /> <Image - src={i.image} + src={i.image || truncateImgUrl(i.coverImage)} alt={i.title.romaji} width={500} height={500} @@ -108,13 +109,16 @@ export default function Recent({ sessions }) { </div> <Image src="/svg/episode-badge.svg" - alt="episode-bade" + alt="episode-badge" width={200} height={100} className="w-24 lg:w-28 absolute top-1 -right-[13px] lg:-right-[15px] z-40" /> <p className="absolute z-40 text-center w-[80px] lg:w-[100px] top-[5px] -right-2 lg:top-[4px] lg:-right-3 font-karla text-sm lg:text-base"> - Episode <span className="text-white">{i?.episodeNumber}</span> + Episode{" "} + <span className="text-white"> + {i?.episodeNumber || i?.currentEpisode} + </span> </p> </Link> <Link |