Add moviplus source

This commit is contained in:
TPN 2024-07-17 12:35:03 +01:00
parent ea1e9c7695
commit 5735b4cd87
No known key found for this signature in database
GPG key ID: 40AE091637892B91
2 changed files with 96 additions and 0 deletions

View file

@ -22,6 +22,7 @@ import { goMoviesScraper } from '@/providers/sources/gomovies/index';
import { insertunitScraper } from '@/providers/sources/insertunit';
import { kissAsianScraper } from '@/providers/sources/kissasian/index';
import { lookmovieScraper } from '@/providers/sources/lookmovie';
import { moviplusScraper } from '@/providers/sources/moviplus';
import { nsbxScraper } from '@/providers/sources/nsbx';
import { remotestreamScraper } from '@/providers/sources/remotestream';
import { showboxScraper } from '@/providers/sources/showbox/index';
@ -95,6 +96,7 @@ export function gatherAllSources(): Array<Sourcerer> {
autoembedScraper,
tugaflixScraper,
ee3Scraper,
moviplusScraper,
whvxScraper,
];
}

View file

@ -0,0 +1,94 @@
// todo: tv shows
// I just forgot about tv shows
// and they are gonna need a lot of season and episode parsing
// and i dont feel like doing that now
import { load } from 'cheerio';
import { SourcererEmbed, SourcererOutput, makeSourcerer } from '@/providers/base';
import { compareMedia } from '@/utils/compare';
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
import { NotFoundError } from '@/utils/errors';
const baseUrl = 'https://moviplus.net';
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
const searchPage = await ctx.proxiedFetcher('/', {
baseUrl,
query: {
s: ctx.media.title,
},
});
const search$ = load(searchPage);
const searchResults: { title: string; year?: number; id: string }[] = [];
search$('.item-box').each((_, element) => {
const [, title, year] =
search$(element)
.find('a')
.attr('title')
?.match(/^(.*?)\s*(?:\(?\s*(\d{4})(?:\s*-\s*\d{0,4})?\s*\)?)?\s*$/) || [];
const id = search$(element).find('span').first().attr('data-itemid');
if (!title || !id) return;
searchResults.push({ title, year: year ? Number(year) : undefined, id });
});
const id = searchResults.find((x) => x && compareMedia(ctx.media, x.title, x.year))?.id;
if (!id) throw new NotFoundError('No watchable item found');
const apiRes: { embed_url: string } = await ctx.proxiedFetcher('/wp-admin/admin-ajax.php', {
baseUrl,
method: 'POST',
body: new URLSearchParams({
action: 'zeta_player_ajax',
post: id,
nume: '1',
type: 'mv',
}),
});
if (!apiRes.embed_url) throw new Error('No sources found');
const iframeUrl = load(apiRes.embed_url)('iframe').attr('src');
if (!iframeUrl) throw new Error('iFrame Url not found');
const iframePage$ = load(await ctx.proxiedFetcher(iframeUrl));
const links: string[] = [];
iframePage$('.dropdown-item').each((_, element) => {
const link = iframePage$(element).attr('href');
if (link?.startsWith('https:')) links.push(link);
});
const embeds: SourcererEmbed[] = [];
for (const url of links) {
if (links.includes(url)) {
const origin = new URL(url).hostname;
let embedId;
switch (origin) {
case 'vidker.com':
embedId = 'vidker';
break;
default:
embedId = undefined;
}
if (!embedId) continue;
embeds.push({ embedId, url });
}
}
return {
embeds,
};
}
export const moviplusScraper = makeSourcerer({
id: 'moviplus',
name: 'MoviPlus',
rank: 92,
flags: [],
scrapeMovie: comboScraper,
});