Merge pull request #60 from WBRK-dev/main
feat: estimated schedule && home && japenese anime names
This commit is contained in:
@@ -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,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{...},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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>,
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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
@@ -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()) ||
|
||||||
|
|||||||
@@ -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([]);
|
||||||
|
|||||||
Reference in New Issue
Block a user