Merge pull request #60 from WBRK-dev/main

feat: estimated schedule && home && japenese anime names
This commit is contained in:
Ritesh Ghosh
2024-07-21 19:02:50 +05:30
committed by GitHub
8 changed files with 77 additions and 38 deletions
+39 -2
View File
@@ -182,9 +182,7 @@ console.log(data);
id: string, id: string,
name: string, name: string,
poster: string, poster: string,
duration: string,
type: string, type: string,
rating: string,
episodes: { episodes: {
sub: number, sub: number,
dub: number, dub: number,
@@ -258,6 +256,45 @@ console.log(data);
}, },
{...}, {...},
], ],
mostPopularAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
mostFavoriteAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
latestCompletedAnimes: [
{
id: string,
name: string,
poster: string,
type: string,
episodes: {
sub: number,
dub: number,
}
},
{...},
],
} }
``` ```
+1
View File
@@ -55,6 +55,7 @@ async function scrapeEstimatedSchedule(
?.trim() || null, ?.trim() || null,
airingTimestamp, airingTimestamp,
secondsUntilAiring: Math.floor((airingTimestamp - Date.now()) / 1000), secondsUntilAiring: Math.floor((airingTimestamp - Date.now()) / 1000),
episode: Number($(el).find("a .fd-play button").text().trim().split(" ")[1])
}); });
}); });
+13 -30
View File
@@ -5,6 +5,7 @@ import {
ACCEPT_ENCODING_HEADER, ACCEPT_ENCODING_HEADER,
extractTop10Animes, extractTop10Animes,
extractAnimes, extractAnimes,
extractMostPopularAnimes,
} from "../utils/index.js"; } from "../utils/index.js";
import axios, { AxiosError } from "axios"; import axios, { AxiosError } from "axios";
import createHttpError, { type HttpError } from "http-errors"; import createHttpError, { type HttpError } from "http-errors";
@@ -24,6 +25,9 @@ async function scrapeHomePage(): Promise<ScrapedHomePage | HttpError> {
month: [], month: [],
}, },
topAiringAnimes: [], topAiringAnimes: [],
mostPopularAnimes: [],
mostFavoriteAnimes: [],
latestCompletedAnimes: [],
genres: [], genres: [],
}; };
@@ -114,11 +118,15 @@ async function scrapeHomePage(): Promise<ScrapedHomePage | HttpError> {
rank: parseInt( rank: parseInt(
$(el).find(".item .number")?.children()?.first()?.text()?.trim() $(el).find(".item .number")?.children()?.first()?.text()?.trim()
), ),
id: $(el).find(".item .film-poster")?.attr("href")?.slice(1)?.trim(),
name: $(el) name: $(el)
.find(".item .number .film-title.dynamic-name") .find(".item .number .film-title.dynamic-name")
?.text() ?.text()
?.trim(), ?.trim(),
id: $(el).find(".item .film-poster")?.attr("href")?.slice(1)?.trim(), jname: $(el)
.find(".item .number .film-title.dynamic-name")
?.attr("data-jname")
?.trim(),
poster: $(el) poster: $(el)
.find(".item .film-poster .film-poster-img") .find(".item .film-poster .film-poster-img")
?.attr("data-src") ?.attr("data-src")
@@ -158,35 +166,10 @@ async function scrapeHomePage(): Promise<ScrapedHomePage | HttpError> {
} }
}); });
const topAiringSelector: SelectorType = res.topAiringAnimes = extractMostPopularAnimes($, "#anime-featured .row div:nth-of-type(1) .anif-block-ul ul li");
"#anime-featured .row div:nth-of-type(1) .anif-block-ul ul li"; res.mostPopularAnimes = extractMostPopularAnimes($, "#anime-featured .row div:nth-of-type(2) .anif-block-ul ul li");
$(topAiringSelector).each((i, el) => { res.mostFavoriteAnimes = extractMostPopularAnimes($, "#anime-featured .row div:nth-of-type(3) .anif-block-ul ul li");
const otherInfo = $(el) res.latestCompletedAnimes = extractMostPopularAnimes($, "#anime-featured .row div:nth-of-type(4) .anif-block-ul ul li");
.find(".fd-infor .fdi-item")
.map((i, el) => $(el).text().trim())
.get();
res.topAiringAnimes.push({
id: $(el)
.find(".film-detail .film-name .dynamic-name")
?.attr("href")
?.slice(1)
?.trim(),
name: $(el)
.find(".film-detail .film-name .dynamic-name")
?.attr("title")
?.trim(),
jname: $(el)
.find(".film-detail .film-name .dynamic-name")
?.attr("data-jname")
?.trim(),
poster: $(el)
.find(".film-poster a .film-poster-img")
?.attr("data-src")
?.trim(),
otherInfo,
});
});
return res; return res;
} catch (err: any) { } catch (err: any) {
+4
View File
@@ -1,6 +1,7 @@
export interface Anime { export interface Anime {
id: string | null; id: string | null;
name: string | null; name: string | null;
jname: string | null;
poster: string | null; poster: string | null;
duration: string | null; duration: string | null;
type: string | null; type: string | null;
@@ -15,6 +16,7 @@ type CommonAnimeProps = "id" | "name" | "poster";
export interface Top10Anime extends Pick<Anime, CommonAnimeProps | "episodes"> { export interface Top10Anime extends Pick<Anime, CommonAnimeProps | "episodes"> {
rank: number | null; rank: number | null;
jname: string | null;
} }
export type Top10AnimeTimePeriod = "day" | "week" | "month"; export type Top10AnimeTimePeriod = "day" | "week" | "month";
@@ -39,6 +41,8 @@ export interface LatestEpisodeAnime extends Anime {}
export interface TopUpcomingAnime extends Anime {} export interface TopUpcomingAnime extends Anime {}
export interface TopAiringAnime extends MostPopularAnime {} export interface TopAiringAnime extends MostPopularAnime {}
export interface MostFavoriteAnime extends MostPopularAnime {}
export interface LatestCompletedAnime extends MostPopularAnime {}
export interface AnimeGeneralAboutInfo export interface AnimeGeneralAboutInfo
extends Pick<Anime, CommonAnimeProps>, extends Pick<Anime, CommonAnimeProps>,
+1
View File
@@ -5,6 +5,7 @@ type EstimatedSchedule = {
jname: string | null; jname: string | null;
airingTimestamp: number; airingTimestamp: number;
secondsUntilAiring: number; secondsUntilAiring: number;
episode: number;
}; };
export type ScrapedEstimatedSchedule = { export type ScrapedEstimatedSchedule = {
+6
View File
@@ -4,6 +4,9 @@ import type {
TopAiringAnime, TopAiringAnime,
TopUpcomingAnime, TopUpcomingAnime,
LatestEpisodeAnime, LatestEpisodeAnime,
MostFavoriteAnime,
MostPopularAnime,
LatestCompletedAnime,
} from "../anime.js"; } from "../anime.js";
import type { HttpError } from "http-errors"; import type { HttpError } from "http-errors";
import type { ScrapedAnimeCategory } from "./animeCategory.js"; import type { ScrapedAnimeCategory } from "./animeCategory.js";
@@ -15,4 +18,7 @@ export interface ScrapedHomePage
latestEpisodeAnimes: Array<LatestEpisodeAnime> | HttpError; latestEpisodeAnimes: Array<LatestEpisodeAnime> | HttpError;
topUpcomingAnimes: Array<TopUpcomingAnime> | HttpError; topUpcomingAnimes: Array<TopUpcomingAnime> | HttpError;
topAiringAnimes: Array<TopAiringAnime> | HttpError; topAiringAnimes: Array<TopAiringAnime> | HttpError;
mostPopularAnimes: Array<MostPopularAnime> | HttpError;
mostFavoriteAnimes: Array<MostFavoriteAnime> | HttpError;
latestCompletedAnimes: Array<LatestCompletedAnime> | HttpError;
} }
+10 -6
View File
@@ -39,6 +39,10 @@ export const extractAnimes = (
.find(".film-detail .film-name .dynamic-name") .find(".film-detail .film-name .dynamic-name")
?.text() ?.text()
?.trim(), ?.trim(),
jname: $(el)
.find(".film-detail .film-name .dynamic-name")
?.attr("data-jname")
?.trim() || null,
poster: poster:
$(el) $(el)
.find(".film-poster .film-poster-img") .find(".film-poster .film-poster-img")
@@ -102,6 +106,7 @@ export const extractTop10Animes = (
.trim() || null, .trim() || null,
rank: Number($(el).find(".film-number span")?.text()?.trim()) || null, rank: Number($(el).find(".film-number span")?.text()?.trim()) || null,
name: $(el).find(".film-detail .dynamic-name")?.text()?.trim() || null, name: $(el).find(".film-detail .dynamic-name")?.text()?.trim() || null,
jname: $(el).find(".film-detail .dynamic-name")?.attr("data-jname")?.trim() || null,
poster: poster:
$(el) $(el)
.find(".film-poster .film-poster-img") .find(".film-poster .film-poster-img")
@@ -150,17 +155,16 @@ export const extractMostPopularAnimes = (
?.slice(1) ?.slice(1)
.trim() || null, .trim() || null,
name: $(el).find(".film-detail .dynamic-name")?.text()?.trim() || null, name: $(el).find(".film-detail .dynamic-name")?.text()?.trim() || null,
poster:
$(el)
.find(".film-poster .film-poster-img")
?.attr("data-src")
?.trim() || null,
jname: jname:
$(el) $(el)
.find(".film-detail .film-name .dynamic-name") .find(".film-detail .film-name .dynamic-name")
.attr("data-jname") .attr("data-jname")
?.trim() || null, ?.trim() || null,
poster:
$(el)
.find(".film-poster .film-poster-img")
?.attr("data-src")
?.trim() || null,
episodes: { episodes: {
sub: sub:
Number($(el)?.find(".fd-infor .tick .tick-sub")?.text()?.trim()) || Number($(el)?.find(".fd-infor .tick .tick-sub")?.text()?.trim()) ||
+3
View File
@@ -9,6 +9,9 @@ test("returns anime information present in homepage", async () => {
expect(data.latestEpisodeAnimes).not.toEqual([]); expect(data.latestEpisodeAnimes).not.toEqual([]);
expect(data.topUpcomingAnimes).not.toEqual([]); expect(data.topUpcomingAnimes).not.toEqual([]);
expect(data.topAiringAnimes).not.toEqual([]); expect(data.topAiringAnimes).not.toEqual([]);
expect(data.mostPopularAnimes).not.toEqual([]);
expect(data.mostFavoriteAnimes).not.toEqual([]);
expect(data.latestCompletedAnimes).not.toEqual([]);
expect(data.genres).not.toEqual([]); expect(data.genres).not.toEqual([]);
expect(data.top10Animes.today).not.toEqual([]); expect(data.top10Animes.today).not.toEqual([]);