Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:koikiss-dev/jimov_api into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
koikiss-dev committed Aug 29, 2024
2 parents 2d9a445 + c895504 commit bbcf118
Show file tree
Hide file tree
Showing 20 changed files with 494 additions and 123 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# JIMOV - Media Content API

![image description](<.gitbook/assets/JIMOV\_logo (1).png>)
![image description](<./src/images/JIMOV_logo.png>)

[![discordBadge](https://img.shields.io/badge/Chat-Click%20here-7289d9?style=for-the-badge\&logo=discord)](https://discord.com/invite/tyZ39GCX7R)[![documentationBadge](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://choosealicense.com/licenses/mit/)[![documentationBadge](https://img.shields.io/badge/Documentation-Click%20here-blue?style=for-the-badge)](https://jimov-api-docs.vercel.app/)

Expand Down
10 changes: 4 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ import cors from "cors";
/* Anime */
import flv from "../src/routes/v1/anime/animeflv/AnimeflvRoutes";
import latinhd from "../src/routes/v1/anime/animelatinohd/AnimeLatinoHDRoutes";
//import gogoanime from "../src/routes/v1/anime/gogoanime/GogoAnimeRoute";
import zoro from "../src/routes/v1/anime/zoro/ZoroRoutes";
import monoschinos from "../src/routes/v1/anime/monoschinos/MonosChinosRoute";
import tioanime from "../src/routes/v1/anime/tioanime/TioAnimeRoute";
import WcoStream from "../src/routes/v1/anime/wcostream/wcostreamRoutes";
import AnimeBlix from "../src/routes/v1/anime/animeblix/AnimeBlixRoutes";
import Animevostfr from "../src/routes/v1/anime/animevostfr/AnimevostfrRoutes";
import hentaila from "../src/routes/v1/anime/hentaila/HentaiLaRoutes";
import HentaiHaven from "../src/routes/v1/anime/hentaihaven/HentaiHavenRoutes";

/* Manga */
import comick from "../src/routes/v1/manga/comick/ComickRoutes";
import inmanga from "../src/routes/v1/manga/inmanga/InmangaRoutes";
import nhentai from "../src/routes/v1/manga/nhentai/NhentaiRoutes";
import mangareader from "../src/routes/v1/manga/mangareader/MangaReaderRoutes";
import manganelo from "../src/routes/v1/manga/manganelo/ManganeloRoutes";

Expand All @@ -40,20 +39,19 @@ app.use(cors());
/*anime*/
app.use(flv);
app.use(latinhd);
//app.use(gogoanime);
app.use(monoschinos);
app.use(zoro);
app.use(tioanime);
app.use(WcoStream);
app.use(AnimeBlix);
app.use(Animevostfr);
app.use(hentaila);
app.use(HentaiHaven);

/* anime */

/*Manga*/
app.use(comick);
app.use(inmanga);
app.use(nhentai);
app.use(mangareader);
app.use(manganelo);
/*Manga*/
Expand Down
31 changes: 31 additions & 0 deletions src/routes/v1/anime/hentaihaven/HentaiHavenRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Router } from "express";
import { HentaiHaven } from "../../../../scraper/sites/anime/hentaihaven/HentaiHaven";
const Anime = new HentaiHaven();
const router = Router();

// Filter
router.get("/anime/hentaihaven/filter", async (req, res) => {
const { search, page } = req.query;

const data = await Anime.GetItemByFilter(
search as string,
page as unknown as number
);
res.send(data);
});

// Anime Info +(Episodes list)
router.get("/anime/hentaihaven/name/:name", async (req, res) => {
const { name } = req.params;
const data = await Anime.GetItemInfo(name);
res.send(data);
});

// Episode Info +(Video Servers)
router.get("/anime/hentaihaven/episode/:episode", async (req, res) => {
const { episode } = req.params;
const data = await Anime.GetEpisodeServers(episode);
res.send(data);
});

export default router;
30 changes: 30 additions & 0 deletions src/routes/v1/anime/hentaila/HentaiLaRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Router } from "express";
import { HentaiLa } from "../../../../scraper/sites/anime/hentaila/HentaiLa";
const Anime = new HentaiLa();
const router = Router();

// Filter
router.get("/anime/hentaila/filter", async (req, res) => {
const { search } = req.query;

const data = await Anime.GetItemByFilter(
search as string
);
res.send(data);
});

// Anime Info +(Episodes list)
router.get("/anime/hentaila/name/:name", async (req, res) => {
const { name } = req.params;
const data = await Anime.GetItemInfo(name);
res.send(data);
});

// Episode Info +(Video Servers)
router.get("/anime/hentaila/episode/:episode", async (req, res) => {
const { episode } = req.params;
const data = await Anime.GetEpisodeServers(episode);
res.send(data);
});

export default router;
2 changes: 1 addition & 1 deletion src/routes/v1/manga/comick/ComickRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ router.get("/manga/comick/filter", async (req, res) => {
res.send(data);
});

router.get("/manga/comick/title/:manga", async (req, res) => {
router.get("/manga/comick/name/:manga", async (req, res) => {
const { manga } = req.params;
const { lang } = req.query;

Expand Down
2 changes: 1 addition & 1 deletion src/routes/v1/manga/inmanga/InmangaRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ router.get("/manga/inmanga/filter", async (req, res) => {
res.send(data);
});

router.get("/manga/inmanga/title/:manga", async (req, res) => {
router.get("/manga/inmanga/name/:manga", async (req, res) => {
const { manga } = req.params;
const { cid } = req.query;

Expand Down
2 changes: 1 addition & 1 deletion src/routes/v1/manga/manganelo/ManganeloRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Manganelo } from "../../../../scraper/sites/manga/manganelo/Manganelo";
const router = Router();
const manganelo = new Manganelo();

router.get(`/manga/${manganelo.name}/title/:id`, async (req, res) => {
router.get(`/manga/${manganelo.name}/name/:id`, async (req, res) => {
const result = await manganelo.GetItemInfo(
req.params.id as unknown as string,
);
Expand Down
2 changes: 1 addition & 1 deletion src/routes/v1/manga/mangareader/MangaReaderRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
const mangaReader = new MangaReader();
const router = Router();

router.get("/manga/mangareader/title/:id", async (req, res) => {
router.get("/manga/mangareader/name/:id", async (req, res) => {
try {
const id = req.params.id as unknown as string;

Expand Down
114 changes: 78 additions & 36 deletions src/scraper/sites/anime/animeflv/AnimeFlv.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from "axios";
import { load } from "cheerio";
import { AnimeMedia, Chronology } from "../../../../types/anime";
import { Episode, EpisodeServer } from "../../../../types/episode";
import { Episode } from "../../../../types/episode";
import {
Genres,
OrderAnimeflv,
Expand All @@ -17,18 +17,26 @@ import {
import { AnimeScraperModel } from "../../../../models/AnimeScraperModel";

export class AnimeFlv extends AnimeScraperModel {
readonly url = "https://animeflv.ws";
readonly url = "https://m.animeflv.net";

async GetItemInfo(anime: string): Promise<AnimeMedia> {
try {
const { data } = await axios.get(`${this.url}/anime/${anime}`);
const $ = load(data);
const title = $("h2.Title").text().trim();
const title_alt = $("span.TxtAlt").text().trim();
const img = $("div.AnimeCover .Image figure img").attr("src");
const status = $("p.AnmStts span").text().trim();
const synopsis = $("div.Description").text().trim();
const episodes = $(".ListCaps li a");

//relevant information
const title = $("h1.Title").text().trim();
const title_alt = title;
const img = $("meta[property='og:image']").attr("content");
const status = $("p strong.Anm-On").text();
const synopsis = $("header p:contains(Sinopsis)")
.text()
.replace("Sinopsis:", "")
.trim();

//container of episodes
const episodesContainer = $("div.List-Episodes div.AACrdn");

const AnimeReturn = new AnimeMedia();
AnimeReturn.name = title;
AnimeReturn.alt_names = [...title_alt.split(",")];
Expand All @@ -38,6 +46,8 @@ export class AnimeFlv extends AnimeScraperModel {
AnimeReturn.status = status;
AnimeReturn.synopsis = synopsis;
AnimeReturn.chronology = [];
AnimeReturn.genres = [];
AnimeReturn.episodes = [];

//getRelated
$("ul.ListAnmRel li a").each((_i, e) => {
Expand All @@ -46,26 +56,32 @@ export class AnimeFlv extends AnimeScraperModel {
cro.url = `/anime/flv/name/${$(e).attr("href").replace("/anime/", "")}`;
AnimeReturn.chronology.push(cro);
});

//get genres
$("nav.Nvgnrs a").each((_i, e) => {
const gen = $(e).text().trim();
$("footer a").each((_i, e) => {
const gen = $(e).text().trim() as string;

AnimeReturn.genres.push(gen);
});

//get episodes
episodes.each((_i_, e) => {
const l = $(e).attr("href").replace("/", "");
const episode = new Episode();
episode.name = $(e).children(".Title").text().trim();
episode.url = `/anime/flv/episode/${`${l}`.replace(
"/anime",
"/anime/flv"
)}`;
episode.num = Number($(e).children("p").last().text().trim());
episode.thumbnail.url = $(e)
.children("figure")
.find(".lazy")
.attr("src");
AnimeReturn.episodes.push(episode);
episodesContainer.each((_i_, e) => {
$(e)
.find("ul li")
.each((_i, e) => {
const link = $(e).find("a");
const name = link.text().trim();
const numberEpisode = Number(name.split(" ").slice(-1));
console.log(numberEpisode);
const episode = new Episode();
episode.name = name;
episode.url = `/anime/flv/episode/${link
.attr("href")
.replace("/ver/", "")}`;
episode.num = numberEpisode;

AnimeReturn.episodes.push(episode);
});
});
return AnimeReturn;
} catch (error) {
Expand Down Expand Up @@ -128,24 +144,50 @@ export class AnimeFlv extends AnimeScraperModel {

async GetEpisodeServers(episode: string): Promise<Episode> {
try {
const { data } = await axios.get(`${this.url}/${episode}`);
const { data } = await axios.get(`${this.url}/ver/${episode}`);
const $ = load(data);
const title = $(".CapiTop").children("h1").text().trim();
const getLinks = $(".CpCnA .anime_muti_link li");
const title = $("h1").text().trim();
const getLinks = $("script");
const numberEpisode = episode.substring(episode.lastIndexOf("-") + 1);
const episodeReturn = new Episode();
episodeReturn.name = title;
episodeReturn.url = `/anime/flv/episode/${episode}`;
episodeReturn.num = Number(numberEpisode);
episodeReturn.servers = [];

const promises = getLinks.map(async (_i, e) => {
const servers = new EpisodeServer();
const title = $(e).attr("title");
getLinks.each((_i, e) => {
interface VideoObject {
title: string;
code: string;
}

const scriptContent = $(e).html();
const regexVideoObject = /var videos = (\{.*?\});/;

const matchObject = scriptContent.match(regexVideoObject);

if (matchObject) {
const videoObject: VideoObject[] = JSON.parse(matchObject[1]).SUB;

for (let index = 0; index < videoObject.length; index++) {
const element = videoObject[index];

episodeReturn.servers.push({
name: element.title,
url: element.code,
});
}
}
});
/*const promises = getLinks.map(async (_i, e) => {
/* const servers = new EpisodeServer();
const title = $(e).find("a").text().trim();
const videoData = $(e).attr("data-video");
servers.name = title;
servers.url = videoData;
if (videoData.includes("streaming.php")) {
console.log(title); */

/* if (videoData.includes("streaming.php")) {
await this.getM3U(
`${videoData.replace("streaming.php", "ajax.php")}&refer=none`
).then((g) => {
Expand Down Expand Up @@ -175,23 +217,23 @@ export class AnimeFlv extends AnimeScraperModel {
default:
break;
}
episodeReturn.servers.push(servers);
});
await Promise.all(promises);
episodeReturn.servers.push(servers);
})*/
//await Promise.all(promises);
return episodeReturn;
} catch (error) {
console.log("An error occurred while getting the episode servers", error);
throw new Error("An error occurred while getting the episode servers");
}
}

private async getM3U(vidurl: string) {
/* private async getM3U(vidurl: string) {
try {
const res = await axios.get(vidurl);
return res.data;
} catch (error) {
console.log(error);
}
}
} */
}
Loading

0 comments on commit bbcf118

Please sign in to comment.