From c423a51b4cb489b1408a2344a85d298c862e84eb Mon Sep 17 00:00:00 2001 From: lonelil <51315646+lonelil@users.noreply.github.com> Date: Mon, 29 Jan 2024 20:36:36 +0800 Subject: [PATCH] add nepu provider --- src/providers/all.ts | 2 + src/providers/sources/nepu/index.ts | 78 +++++++++++++++++++++++++++++ src/providers/sources/nepu/types.ts | 9 ++++ 3 files changed, 89 insertions(+) create mode 100644 src/providers/sources/nepu/index.ts create mode 100644 src/providers/sources/nepu/types.ts diff --git a/src/providers/all.ts b/src/providers/all.ts index 13e9039..edbe50b 100644 --- a/src/providers/all.ts +++ b/src/providers/all.ts @@ -23,6 +23,7 @@ import { ridooScraper } from './embeds/ridoo'; import { smashyStreamDScraper } from './embeds/smashystream/dued'; import { smashyStreamFScraper } from './embeds/smashystream/video1'; import { vidplayScraper } from './embeds/vidplay'; +import { nepuScraper } from './sources/nepu'; import { ridooMoviesScraper } from './sources/ridomovies'; import { smashyStreamScraper } from './sources/smashystream'; import { vidSrcToScraper } from './sources/vidsrcto'; @@ -41,6 +42,7 @@ export function gatherAllSources(): Array { smashyStreamScraper, ridooMoviesScraper, vidSrcToScraper, + nepuScraper, ]; } diff --git a/src/providers/sources/nepu/index.ts b/src/providers/sources/nepu/index.ts new file mode 100644 index 0000000..d6e1505 --- /dev/null +++ b/src/providers/sources/nepu/index.ts @@ -0,0 +1,78 @@ +import { load } from 'cheerio'; + +import { flags } from '@/entrypoint/utils/targets'; +import { SourcererOutput, makeSourcerer } from '@/providers/base'; +import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; +import { NotFoundError } from '@/utils/errors'; + +import { SearchResults } from './types'; + +const nepuBase = 'https://nepu.to'; +const nepuReferer = `${nepuBase}/`; + +const universalScraper = async (ctx: MovieScrapeContext | ShowScrapeContext) => { + const searchResultRequest = await ctx.proxiedFetcher('/ajax/posts', { + baseUrl: nepuBase, + query: { + q: ctx.media.title, + }, + }); + // json isn't parsed by searchResultRequest for some reason. + const searchResult = JSON.parse(searchResultRequest) as SearchResults; + + const show = searchResult.data[0]; + if (!show) throw new NotFoundError('No watchable item found'); + + let videoUrl = show.url; + + if (ctx.media.type === 'show') { + videoUrl = `${show.url}/season/${ctx.media.season.number}/episode/${ctx.media.episode.number}`; + } + + const videoPage = await ctx.proxiedFetcher(videoUrl, { + baseUrl: nepuBase, + }); + const videoPage$ = load(videoPage); + const embedId = videoPage$('a.btn-service').attr('data-embed'); + + if (!embedId) throw new NotFoundError('No embed found.'); + + const playerPage = await ctx.proxiedFetcher('/ajax/embed', { + method: 'POST', + baseUrl: nepuBase, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `id=${embedId}`, + }); + + const streamUrl = playerPage.match(/"file":"(http[^"]+)"/); + + if (!streamUrl) throw new NotFoundError('No stream found.'); + + return { + embeds: [], + stream: [ + { + id: 'primary', + captions: [], + playlist: streamUrl[1], + type: 'hls', + flags: [flags.CORS_ALLOWED], + preferredHeaders: { + Origin: nepuBase, + Referer: nepuReferer, + }, + }, + ], + } as SourcererOutput; +}; + +export const nepuScraper = makeSourcerer({ + id: 'nepu', + name: 'Nepu', + rank: 111, + flags: [flags.CORS_ALLOWED], + scrapeMovie: universalScraper, + scrapeShow: universalScraper, +}); diff --git a/src/providers/sources/nepu/types.ts b/src/providers/sources/nepu/types.ts new file mode 100644 index 0000000..7c8275b --- /dev/null +++ b/src/providers/sources/nepu/types.ts @@ -0,0 +1,9 @@ +export type SearchResults = { + data: { + id: number; + name: string; + second_name: string; + url: string; + type: 'Movie' | 'Serie'; + }[]; +};