diff --git a/src/providers/all.ts b/src/providers/all.ts index 6652bfd..ea1c8f2 100644 --- a/src/providers/all.ts +++ b/src/providers/all.ts @@ -28,7 +28,7 @@ import { bflixScraper } from './embeds/bflix'; import { closeLoadScraper } from './embeds/closeload'; import { fileMoonScraper } from './embeds/filemoon'; import { fileMoonMp4Scraper } from './embeds/filemoon/mp4'; -import { deltaScraper } from './embeds/nsbx/delta'; +import { alphaScraper, deltaScraper } from './embeds/nsbx'; import { ridooScraper } from './embeds/ridoo'; import { smashyStreamOScraper } from './embeds/smashystream/opstream'; import { smashyStreamFScraper } from './embeds/smashystream/video1'; @@ -98,6 +98,7 @@ export function gatherAllEmbeds(): Array { fileMoonScraper, fileMoonMp4Scraper, deltaScraper, + alphaScraper, vidplayScraper, wootlyScraper, doodScraper, diff --git a/src/providers/embeds/nsbx.ts b/src/providers/embeds/nsbx.ts new file mode 100644 index 0000000..397a1c9 --- /dev/null +++ b/src/providers/embeds/nsbx.ts @@ -0,0 +1,50 @@ +import { EmbedOutput, makeEmbed } from '@/providers/base'; +import { baseUrl, headers } from '@/providers/sources/nsbx'; +import { NotFoundError } from '@/utils/errors'; + +const providers = [ + { + id: 'delta', + rank: 699, + }, + { + id: 'alpha', + rank: 695, + }, +]; + +function embed(provider: { id: string; rank: number }) { + return makeEmbed({ + id: provider.id, + name: provider.id.charAt(0).toUpperCase() + provider.id.slice(1), + rank: provider.rank, + disabled: false, + async scrape(ctx) { + const search = await ctx.fetcher.full( + `${baseUrl}/search?query=${encodeURIComponent(ctx.url)}&provider=${provider.id}`, + { headers }, + ); + + if (search.statusCode === 429) { + throw new Error('Rate limited'); + } else if (search.statusCode !== 200) { + throw new NotFoundError('Failed to search'); + } + + ctx.progress(50); + + const result = await ctx.fetcher( + `${baseUrl}/provider?resourceId=${encodeURIComponent(search.body.url)}&provider=${provider.id}`, + { + headers, + }, + ); + + ctx.progress(100); + + return result as EmbedOutput; + }, + }); +} + +export const [deltaScraper, alphaScraper] = providers.map(embed); diff --git a/src/providers/embeds/nsbx/delta.ts b/src/providers/embeds/nsbx/delta.ts deleted file mode 100644 index 95f354f..0000000 --- a/src/providers/embeds/nsbx/delta.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { EmbedOutput, makeEmbed } from '@/providers/base'; -import { headers } from '@/providers/sources/nsbx'; - -export const deltaScraper = makeEmbed({ - id: 'delta', - name: 'Delta', - rank: 200, - disabled: false, - async scrape(ctx) { - const url = `https://api.nsbx.ru/provider?resourceId=${encodeURIComponent(ctx.url)}&provider=delta`; - const result = await ctx.fetcher(url, { - headers, - }); - - return result as EmbedOutput; - }, -}); diff --git a/src/providers/sources/nsbx.ts b/src/providers/sources/nsbx.ts index 6082e96..57152ed 100644 --- a/src/providers/sources/nsbx.ts +++ b/src/providers/sources/nsbx.ts @@ -1,8 +1,10 @@ import { flags } from '@/entrypoint/utils/targets'; -import { SourcererEmbed, SourcererOutput, makeSourcerer } from '@/providers/base'; +import { SourcererOutput, makeSourcerer } from '@/providers/base'; import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; import { NotFoundError } from '@/utils/errors'; +export const baseUrl = 'https://api.nsbx.ru'; + export const headers = { Origin: 'https://extension.works.again.with.nsbx', Referer: 'https://extension.works.again.with.nsbx', @@ -24,14 +26,23 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis query.episode = ctx.media.episode.number.toString(); } - const result = await ctx.fetcher(`https://api.nsbx.ru/search?query=${encodeURIComponent(JSON.stringify(query))}`, { + const res = await ctx.fetcher(`${baseUrl}/status`, { headers, }); - if (result.embeds.length === 0) throw new NotFoundError('No watchable item found'); + if (res.providers?.length === 0) { + throw new NotFoundError('No providers available'); + } + + const embeds = res.providers.map((provider: string) => { + return { + embedId: provider, + url: JSON.stringify(query), + }; + }); return { - embeds: result.embeds as SourcererEmbed[], + embeds, }; } diff --git a/src/utils/valid.ts b/src/utils/valid.ts index 82a9b2e..275afd3 100644 --- a/src/utils/valid.ts +++ b/src/utils/valid.ts @@ -1,10 +1,10 @@ -import { deltaScraper } from '@/providers/embeds/nsbx/delta'; +import { alphaScraper, deltaScraper } from '@/providers/embeds/nsbx'; import { warezcdnembedMp4Scraper } from '@/providers/embeds/warezcdn/mp4'; import { Stream } from '@/providers/streams'; import { IndividualEmbedRunnerOptions } from '@/runners/individualRunner'; import { ProviderRunnerOptions } from '@/runners/runner'; -const SKIP_VALIDATION_CHECK_IDS = [warezcdnembedMp4Scraper.id, deltaScraper.id]; +const SKIP_VALIDATION_CHECK_IDS = [warezcdnembedMp4Scraper.id, deltaScraper.id, alphaScraper.id]; export function isValidStream(stream: Stream | undefined): boolean { if (!stream) return false;