Merge pull request #102 from movie-web/dev

Version 2.2.2
This commit is contained in:
William Oldham
2024-02-29 23:09:11 +00:00
committed by GitHub
15 changed files with 62 additions and 45 deletions

View File

@@ -2,7 +2,7 @@
## What is `@movie-web/providers`? ## What is `@movie-web/providers`?
`@movie-web/providers` is the soul of [movie-web.app](https://movie-web.app). It's a collection of scrapers of various streaming sites. It extracts the raw streams from those sites, so you can watch them without any extra fluff from the original sites. `@movie-web/providers` is the soul of [movie-web](https://github.com/movie-web/movie-web). It's a collection of scrapers of various streaming sites. It extracts the raw streams from those sites, so you can watch them without any extra fluff from the original sites.
## What can I use this on? ## What can I use this on?

View File

@@ -2,6 +2,12 @@
title: 'Changelog' title: 'Changelog'
--- ---
# Version 2.2.2
- Fix subtitles not appearing if the name of the subtitle is in its native tongue.
- Remove references to the old domain
- Fixed ridomovies not working for some shows and movies
- Fixed Showbox not working in react-native.
# Version 2.2.1 # Version 2.2.1
- Fixed Closeload scraper - Fixed Closeload scraper

View File

@@ -17,7 +17,7 @@ import { makeProviders, makeStandardFetcher, targets } from '@movie-web/provider
const providers = makeProviders({ const providers = makeProviders({
fetcher: makeStandardFetcher(fetch), fetcher: makeStandardFetcher(fetch),
target: chooseYourself, // check out https://providers.docs.movie-web.app/essentials/targets target: chooseYourself, // check out https://movie-web.github.io/providers/essentials/targets
}) })
``` ```

2
.github/SECURITY.md vendored
View File

@@ -11,4 +11,4 @@ Support is not provided for any forks or mirrors of movie-web.
There are two ways you can contact the movie-web maintainers to report a vulnerability: There are two ways you can contact the movie-web maintainers to report a vulnerability:
- Email [security@movie-web.app](mailto:security@movie-web.app) - Email [security@movie-web.app](mailto:security@movie-web.app)
- Report the vulnerability in the [movie-web Discord server](https://discord.movie-web.app) - Report the vulnerability in the [movie-web Discord server](https://movie-web.github.io/links/discord)

View File

@@ -7,8 +7,8 @@ features:
- scrape popular streaming websites - scrape popular streaming websites
- works in both browser and server-side - works in both browser and server-side
Visit documentation here: https://providers.docs.movie-web.app/ Visit documentation here: https://movie-web.github.io/providers/
## How to run locally or test my changes ## How to run locally or test my changes
These topics are also covered in the documentation, [read about it here](https://providers.docs.movie-web.app/extra-topics/development). These topics are also covered in the documentation, [read about it here](https://movie-web.github.io/providers/extra-topics/development).

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "@movie-web/providers", "name": "@movie-web/providers",
"version": "2.2.0", "version": "2.2.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@movie-web/providers", "name": "@movie-web/providers",
"version": "2.2.0", "version": "2.2.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@movie-web/providers", "name": "@movie-web/providers",
"version": "2.2.1", "version": "2.2.2",
"description": "Package that contains all the providers of movie-web", "description": "Package that contains all the providers of movie-web",
"main": "./lib/index.umd.js", "main": "./lib/index.umd.js",
"types": "./lib/index.d.ts", "types": "./lib/index.d.ts",
@@ -32,7 +32,7 @@
"bugs": { "bugs": {
"url": "https://github.com/movie-web/providers/issues" "url": "https://github.com/movie-web/providers/issues"
}, },
"homepage": "https://providers.docs.movie-web.app/", "homepage": "https://movie-web.github.io/providers/",
"scripts": { "scripts": {
"build": "vite build && tsc --noEmit", "build": "vite build && tsc --noEmit",
"cli": "ts-node ./src/dev-cli/index.ts", "cli": "ts-node ./src/dev-cli/index.ts",

View File

@@ -1,6 +1,7 @@
import FormData from 'form-data'; import FormData from 'form-data';
import { FetcherOptions } from '@/fetchers/types'; import { FetcherOptions } from '@/fetchers/types';
import { isReactNative } from '@/utils/native';
export interface SeralizedBody { export interface SeralizedBody {
headers: Record<string, string>; headers: Record<string, string>;
@@ -8,11 +9,20 @@ export interface SeralizedBody {
} }
export function serializeBody(body: FetcherOptions['body']): SeralizedBody { export function serializeBody(body: FetcherOptions['body']): SeralizedBody {
if (body === undefined || typeof body === 'string' || body instanceof URLSearchParams || body instanceof FormData) if (body === undefined || typeof body === 'string' || body instanceof URLSearchParams || body instanceof FormData) {
if (body instanceof URLSearchParams && isReactNative()) {
return {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: body.toString(),
};
}
return { return {
headers: {}, headers: {},
body, body,
}; };
}
// serialize as JSON // serialize as JSON
return { return {

View File

@@ -9,7 +9,7 @@ export const doodScraper = makeEmbed({
name: 'dood', name: 'dood',
rank: 173, rank: 173,
async scrape(ctx) { async scrape(ctx) {
const baseUrl = 'https://do0od.com'; const baseUrl = 'https://d0000d.com';
const id = ctx.url.split('/d/')[1] || ctx.url.split('/e/')[1]; const id = ctx.url.split('/d/')[1] || ctx.url.split('/e/')[1];
@@ -18,18 +18,17 @@ export const doodScraper = makeEmbed({
baseUrl, baseUrl,
}); });
const dataForLater = doodData.match(/a\+"\?token=([^"]+)/)?.[1]; const dataForLater = doodData.match(/\?token=([^&]+)&expiry=/)?.[1];
const path = doodData.match(/\$\.get\('\/pass_md5([^']+)/)?.[1]; const path = doodData.match(/\$\.get\('\/pass_md5([^']+)/)?.[1];
const doodPage = await ctx.proxiedFetcher<string>(`/pass_md5/${path}`, { const doodPage = await ctx.proxiedFetcher<string>(`/pass_md5${path}`, {
headers: { headers: {
referer: `${baseUrl}/e/${id}`, Referer: `${baseUrl}/e/${id}`,
}, },
method: 'GET', method: 'GET',
baseUrl, baseUrl,
}); });
const downloadURL = `${doodPage}${nanoid()}?token=${dataForLater}&expiry=${Date.now()}`;
const downloadURL = `${doodPage}${nanoid()}?token=${dataForLater}${Date.now()}`;
return { return {
stream: [ stream: [
@@ -42,11 +41,11 @@ export const doodScraper = makeEmbed({
unknown: { unknown: {
type: 'mp4', type: 'mp4',
url: downloadURL, url: downloadURL,
headers: {
referer: 'https://do0od.com/',
},
}, },
}, },
headers: {
Referer: 'https://d0000d.com/',
},
}, },
], ],
}; };

View File

@@ -110,7 +110,7 @@ export const upcloudScraper = makeEmbed({
if (track.kind !== 'captions') return; if (track.kind !== 'captions') return;
const type = getCaptionTypeFromUrl(track.file); const type = getCaptionTypeFromUrl(track.file);
if (!type) return; if (!type) return;
const language = labelToLanguageCode(track.label); const language = labelToLanguageCode(track.label.split(' ')[0]);
if (!language) return; if (!language) return;
captions.push({ captions.push({
id: track.file, id: track.file,

View File

@@ -10,18 +10,28 @@ export async function getEmbeds(ctx: ScrapeContext, id: string): Promise<EmbedsR
baseUrl: baseUrl2, baseUrl: baseUrl2,
headers: { headers: {
Referer: baseUrl, Referer: baseUrl,
cookie: '',
}, },
readHeaders: ['Set-Cookie'], readHeaders: ['Set-Cookie'],
method: 'GET', method: 'GET',
}); });
const cookies = parseSetCookie(data.headers.get('Set-Cookie') || ''); const cookies = parseSetCookie(data.headers.get('Set-Cookie') || '');
const aGoozCookie = cookies.aGooz.value;
const $ = load(data.body);
const RandomCookieName = data.body.split(`_3chk('`)[1].split(`'`)[0]; const RandomCookieName = data.body.split(`_3chk('`)[1].split(`'`)[0];
const RandomCookieValue = data.body.split(`_3chk('`)[1].split(`'`)[2]; const RandomCookieValue = data.body.split(`_3chk('`)[1].split(`'`)[2];
let aGoozCookie = '';
let cookie = '';
if (cookies && cookies.aGooz && RandomCookieName && RandomCookieValue) {
aGoozCookie = cookies.aGooz.value;
cookie = makeCookieHeader({
aGooz: aGoozCookie,
[RandomCookieName]: RandomCookieValue,
});
}
const $ = load(data.body);
const embedRedirectURLs = $('a') const embedRedirectURLs = $('a')
.map((index, element) => $(element).attr('href')) .map((index, element) => $(element).attr('href'))
.get() .get()
@@ -33,10 +43,7 @@ export async function getEmbeds(ctx: ScrapeContext, id: string): Promise<EmbedsR
ctx.fetcher ctx.fetcher
.full(url, { .full(url, {
headers: { headers: {
cookie: makeCookieHeader({ cookie,
aGooz: aGoozCookie,
[RandomCookieName]: RandomCookieValue,
}),
Referer: baseUrl2, Referer: baseUrl2,
}, },
method: 'GET', method: 'GET',

View File

@@ -21,7 +21,7 @@ async function universalScraper(ctx: ShowScrapeContext | MovieScrapeContext): Pr
export const goojaraScraper = makeSourcerer({ export const goojaraScraper = makeSourcerer({
id: 'goojara', id: 'goojara',
name: 'goojara', name: 'Goojara',
rank: 225, rank: 225,
flags: [], flags: [],
scrapeShow: universalScraper, scrapeShow: universalScraper,

View File

@@ -49,7 +49,6 @@ export async function searchAndFindMedia(
}); });
const result = results.find((res: Result) => compareMedia(media, res.title, Number(res.year))); const result = results.find((res: Result) => compareMedia(media, res.title, Number(res.year)));
return result; return result;
} }
@@ -67,19 +66,7 @@ export async function scrapeIds(
baseUrl, baseUrl,
headers: headersData, headers: headersData,
method: 'GET', method: 'GET',
}); query: { s: media.season.number.toString() },
const $1 = load(data);
const dataId = $1('#seon').attr('data-id');
if (!dataId) throw new NotFoundError('Not found');
data = await ctx.fetcher<string>(`/xhrc.php`, {
baseUrl,
headers: headersData,
method: 'POST',
body: new URLSearchParams({ s: media.season.number.toString(), t: dataId }),
}); });
let episodeId = ''; let episodeId = '';
@@ -89,7 +76,6 @@ export async function scrapeIds(
$2('.seho').each((index, element) => { $2('.seho').each((index, element) => {
// Extracting the episode number as a string // Extracting the episode number as a string
const episodeNumber = $2(element).find('.seep .sea').text().trim(); const episodeNumber = $2(element).find('.seep .sea').text().trim();
// Comparing with the desired episode number as a string // Comparing with the desired episode number as a string
if (parseInt(episodeNumber, 10) === media.episode.number) { if (parseInt(episodeNumber, 10) === media.episode.number) {
const href = $2(element).find('.snfo h1 a').attr('href'); const href = $2(element).find('.snfo h1 a').attr('href');

View File

@@ -28,9 +28,9 @@ const universalScraper = async (ctx: MovieScrapeContext | ShowScrapeContext) =>
const showPageResult = await ctx.proxiedFetcher<string>(`/${show.fullSlug}`, { const showPageResult = await ctx.proxiedFetcher<string>(`/${show.fullSlug}`, {
baseUrl: ridoMoviesBase, baseUrl: ridoMoviesBase,
}); });
const fullEpisodeSlug = `${show.fullSlug}/season-${ctx.media.season.number}/episode-${ctx.media.episode.number}`; const fullEpisodeSlug = `season-${ctx.media.season.number}/episode-${ctx.media.episode.number}`;
const regexPattern = new RegExp( const regexPattern = new RegExp(
`\\\\"id\\\\":\\\\"(\\d+)\\\\"(?=.*?\\\\\\"fullSlug\\\\\\":\\\\\\"${fullEpisodeSlug}\\\\\\")`, `\\\\"id\\\\":\\\\"(\\d+)\\\\"(?=.*?\\\\\\"fullSlug\\\\\\":\\\\\\"[^"]*${fullEpisodeSlug}[^"]*\\\\\\")`,
'g', 'g',
); );
const matches = [...showPageResult.matchAll(regexPattern)]; const matches = [...showPageResult.matchAll(regexPattern)];

9
src/utils/native.ts Normal file
View File

@@ -0,0 +1,9 @@
export const isReactNative = () => {
try {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
require('react-native');
return true;
} catch (e) {
return false;
}
};