diff --git a/src/providers/sources/neputo.ts b/src/providers/sources/neputo.ts new file mode 100644 index 0000000..ab03582 --- /dev/null +++ b/src/providers/sources/neputo.ts @@ -0,0 +1,45 @@ +import { flags } from '@/entrypoint/utils/targets'; +import { SourcererOutput, makeSourcerer } from '@/providers/base'; +import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; +import { NotFoundError } from '@/utils/errors'; + +const nepuBase = 'https://nscrape.andresdev.org/api'; + +async function scrape(ctx: MovieScrapeContext | ShowScrapeContext): Promise { + const tmdbId = ctx.media.tmdbId; + + let url: string; + if (ctx.media.type === 'movie') { + url = `${nepuBase}/get-stream?tmdbId=${tmdbId}`; + } else { + url = `${nepuBase}/get-show-stream?tmdbId=${tmdbId}&season=${ctx.media.season.number}&episode=${ctx.media.episode.number}`; + } + + const response = await ctx.proxiedFetcher(url); + + if (!response.success || !response.rurl) { + throw new NotFoundError('No stream found'); + } + + return { + stream: [ + { + id: 'neputo', + type: 'hls', + playlist: response.rurl, + flags: [flags.CORS_ALLOWED], + captions: [], + }, + ], + embeds: [], + }; +} + +export const nepuScraper = makeSourcerer({ + id: 'neputo', + name: 'Nepu.to', + rank: 201, + flags: [flags.CORS_ALLOWED], + scrapeMovie: scrape, + scrapeShow: scrape, +});