Skip to content
This repository has been archived by the owner on Jul 14, 2024. It is now read-only.

Commit

Permalink
Update v4.2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
DevanAbinaya committed Oct 28, 2023
1 parent f7374d0 commit a252824
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 50 deletions.
3 changes: 3 additions & 0 deletions components/admin/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,14 @@ export default function AdminDashboard({
</div>
<div className="flex font-karla font-semibold gap-2">
<button
title="Broadcast"
type="submit"
className="bg-image text-white py-2 px-4 rounded-md hover:bg-opacity-80 transition duration-300"
>
Broadcast
</button>
<button
title="Remove"
type="button"
onClick={handleRemove}
className="bg-red-700 text-white py-2 px-4 rounded-md hover:bg-opacity-80 transition duration-300"
Expand Down Expand Up @@ -247,6 +249,7 @@ export default function AdminDashboard({
)}
<button
type="button"
title="Resolved"
onClick={() => {
setReportId(i?.id);
handleResolved();
Expand Down
1 change: 1 addition & 0 deletions components/admin/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default function AdminLayout({ children, page, setPage }) {
<div className="flex flex-col px-1">
{Navigation.map((item, index) => (
<button
title="Dashboard"
key={item.name}
onClick={() => {
setPage(item.page);
Expand Down
72 changes: 50 additions & 22 deletions components/anime/episode.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import ThumbnailDetail from "./viewMode/thumbnailDetail";
import ListMode from "./viewMode/listMode";
import { toast } from "sonner";

function allProvider(response, setMapProviders, setProviderId) {
const getMap = response.find((i) => i?.map === true);
let allProvider = response;

if (getMap) {
allProvider = response.filter((i) => {
if (i?.providerId === "gogoanime" && i?.map !== true) {
return null;
}
return i;
});
setMapProviders(getMap?.episodes);
}

if (allProvider.length > 0) {
const defaultProvider = allProvider.find(
(x) => x.providerId === "gogoanime" || x.providerId === "9anime"
);
setProviderId(defaultProvider?.providerId || allProvider[0].providerId); // set to first provider id
}

return allProvider;
}

export default function AnimeEpisode({
info,
session,
Expand Down Expand Up @@ -34,29 +58,12 @@ export default function AnimeEpisode({
info.status === "RELEASING" ? "true" : "false"
}${isDub ? "&dub=true" : ""}`
).then((res) => res.json());
const getMap = response.find((i) => i?.map === true);
let allProvider = response;

if (getMap) {
allProvider = response.filter((i) => {
if (i?.providerId === "gogoanime" && i?.map !== true) {
return null;
}
return i;
});
setMapProviders(getMap?.episodes);
}

if (allProvider.length > 0) {
const defaultProvider = allProvider.find(
(x) => x.providerId === "gogoanime" || x.providerId === "9anime"
);
setProviderId(defaultProvider?.providerId || allProvider[0].providerId); // set to first provider id
}
const providers = allProvider(response, setMapProviders, setProviderId);

setView(Number(localStorage.getItem("view")) || 3);
setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings")));
setProviders(allProvider);
setProviders(providers);
setLoading(false);
};
fetchData();
Expand Down Expand Up @@ -172,11 +179,32 @@ export default function AnimeEpisode({
}${isDub ? "&dub=true" : ""}&refresh=true`
);
if (!res.ok) {
console.log(res);
toast.error("Something went wrong");
setProviders([]);
const json = await res.json();
if (res.status === 429) {
toast.error(json.error);
const resp = await fetch(
`/api/v2/episode/${info.id}?releasing=${
info.status === "RELEASING" ? "true" : "false"
}${isDub ? "&dub=true" : ""}`
).then((res) => res.json());

if (resp) {
const providers = allProvider(
resp,
setMapProviders,
setProviderId
);
setProviders(providers);
}
} else {
toast.error("Something went wrong");
setProviders([]);
}
setLoading(false);
} else {
const remainingRequests = res.headers.get("X-RateLimit-Remaining");
toast.success("Remaining requests " + remainingRequests);

const data = await res.json();
const getMap = data.find((i) => i?.map === true) || data[0];
let allProvider = data;
Expand Down
3 changes: 2 additions & 1 deletion components/home/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ExclamationCircleIcon, PlayIcon } from "@heroicons/react/24/solid";
import { useRouter } from "next/router";
import HistoryOptions from "./content/historyOptions";
import { toast } from "sonner";
import { truncateImgUrl } from "@/utils/imageUtils";

export default function Content({
ids,
Expand Down Expand Up @@ -287,7 +288,7 @@ export default function Content({
anime.image ||
anime.coverImage?.extraLarge ||
anime.coverImage?.large ||
anime?.coverImage ||
truncateImgUrl(anime?.coverImage) ||
"https://cdn.discordapp.com/attachments/986579286397964290/1058415946945003611/gray_pfp.png"
}
alt={
Expand Down
1 change: 1 addition & 0 deletions components/listEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ const ListEditor = ({
</div>
<button
type="submit"
title="Save"
className="bg-[#363642] text-white rounded-sm mt-2 py-1 text-sm sm:text-base"
>
Save
Expand Down
2 changes: 1 addition & 1 deletion components/search/searchByImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function SearchByImage({
useEffect(() => {
// Add a global event listener for the paste event
const handlePaste = async (e) => {
e.preventDefault();
// e.preventDefault();

const items = e.clipboardData.items;

Expand Down
3 changes: 3 additions & 0 deletions components/searchPalette.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export default function SearchPalette() {
<Menu.Item>
{({ active }) => (
<button
title="Anime"
onClick={() => setType("ANIME")}
className={`${
active
Expand All @@ -164,6 +165,7 @@ export default function SearchPalette() {
<Menu.Item>
{({ active }) => (
<button
title="Manga"
onClick={() => setType("MANGA")}
className={`${
active
Expand Down Expand Up @@ -239,6 +241,7 @@ export default function SearchPalette() {
{nextPage && (
<button
type="button"
title="View More"
onClick={() => {
router.push(
`/en/search/${type.toLowerCase()}/${
Expand Down
1 change: 1 addition & 0 deletions components/shared/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export function NewNavbar({
<div className="flex w-[20%] justify-end items-center gap-4">
<button
type="button"
title="Search"
onClick={() => setIsOpen(true)}
className="flex-center w-[26px] h-[26px]"
>
Expand Down
13 changes: 12 additions & 1 deletion lib/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const REDIS_URL = process.env.REDIS_URL;
let redis;
let rateLimiterRedis;
let rateLimitStrict;
let rateSuperStrict;

if (REDIS_URL) {
redis = new Redis(REDIS_URL);
Expand All @@ -27,10 +28,20 @@ if (REDIS_URL) {
duration: 1,
};

const optSuperStrict = {
storeClient: redis,
keyPrefix: "rateLimitSuperStrict",
points: 3,
// duration 10 minutes
duration: 10 * 60,
blockDuration: 10 * 60,
};

rateLimiterRedis = new RateLimiterRedis(opt);
rateLimitStrict = new RateLimiterRedis(optStrict);
rateSuperStrict = new RateLimiterRedis(optSuperStrict);
} else {
console.warn("REDIS_URL is not defined. Redis caching will be disabled.");
}

export { redis, rateLimiterRedis, rateLimitStrict };
export { redis, rateLimiterRedis, rateLimitStrict, rateSuperStrict };
44 changes: 39 additions & 5 deletions pages/api/v2/episode/[id].js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
});
}

Expand All @@ -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");
Expand All @@ -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([
Expand Down Expand Up @@ -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" : ""}`;
}
}
45 changes: 30 additions & 15 deletions pages/api/v2/etc/recent/[page].js
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 });
}
Expand Down
Loading

0 comments on commit a252824

Please sign in to comment.