Skip to content

Commit

Permalink
Merge pull request #124 from movie-web/dev
Browse files Browse the repository at this point in the history
2.2.5 Primewire, updated providers
  • Loading branch information
JorrinKievit authored Mar 29, 2024
2 parents c686467 + 1024467 commit f8a5120
Show file tree
Hide file tree
Showing 32 changed files with 690 additions and 26 deletions.
11 changes: 11 additions & 0 deletions .docs/content/1.get-started/4.changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
title: 'Changelog'
---

# Version 2.2.5
- Add Primewire provider
- Improve VidSrcTo search results
- Fixed Filemoon embeds
- Fixed febbox
- Disabled non-working providers
- Reordered providers in ranking

# Version 2.2.4
- Hotfix for HDRezka provider

# Version 2.2.3
- Fix VidSrcTo
- Add HDRezka provider
Expand Down
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ module.exports = {
plugins: ['@typescript-eslint', 'import', 'prettier'],
rules: {
'no-plusplus': 'off',
'class-methods-use-this': 'off',
'no-bitwise': 'off',
'no-underscore-dangle': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'no-console': 'off',
'no-console': ['error', { allow: ['warn', 'error'] }],
'@typescript-eslint/no-this-alias': 'off',
'import/prefer-default-export': 'off',
'@typescript-eslint/no-empty-function': 'off',
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@movie-web/providers",
"version": "2.2.4",
"version": "2.2.5",
"description": "Package that contains all the providers of movie-web",
"main": "./lib/index.umd.js",
"types": "./lib/index.d.ts",
Expand Down
2 changes: 2 additions & 0 deletions src/dev-cli/logging.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { inspect } from 'node:util';

export function logDeepObject(object: Record<any, any>) {
// This is the dev cli, so we can use console.log
// eslint-disable-next-line no-console
console.log(inspect(object, { showHidden: false, depth: null, colors: true }));
}
2 changes: 2 additions & 0 deletions src/dev-cli/scraper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ async function runBrowserScraping(
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const page = await browser.newPage();
// This is the dev cli, so we can use console.log
// eslint-disable-next-line no-console
page.on('console', (message) => console.log(`${message.type().slice(0, 3).toUpperCase()} ${message.text()}`));
await page.goto(server.resolvedUrls.local[0]);
await page.waitForFunction('!!window.scrape', { timeout: 5000 });
Expand Down
8 changes: 8 additions & 0 deletions src/providers/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ import { fileMoonScraper } from './embeds/filemoon';
import { ridooScraper } from './embeds/ridoo';
import { smashyStreamDScraper } from './embeds/smashystream/dued';
import { smashyStreamFScraper } from './embeds/smashystream/video1';
import { streamtapeScraper } from './embeds/streamtape';
import { streamvidScraper } from './embeds/streamvid';
import { vidCloudScraper } from './embeds/vidcloud';
import { vidplayScraper } from './embeds/vidplay';
import { voeScraper } from './embeds/voe';
import { wootlyScraper } from './embeds/wootly';
import { goojaraScraper } from './sources/goojara';
import { hdRezkaScraper } from './sources/hdrezka';
import { nepuScraper } from './sources/nepu';
import { primewireScraper } from './sources/primewire';
import { ridooMoviesScraper } from './sources/ridomovies';
import { smashyStreamScraper } from './sources/smashystream';
import { vidSrcToScraper } from './sources/vidsrcto';
Expand All @@ -50,6 +54,7 @@ export function gatherAllSources(): Array<Sourcerer> {
nepuScraper,
goojaraScraper,
hdRezkaScraper,
primewireScraper,
];
}

Expand All @@ -74,5 +79,8 @@ export function gatherAllEmbeds(): Array<Embed> {
vidplayScraper,
wootlyScraper,
doodScraper,
streamvidScraper,
voeScraper,
streamtapeScraper,
];
}
11 changes: 8 additions & 3 deletions src/providers/embeds/dood.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@ import { customAlphabet } from 'nanoid';
import { makeEmbed } from '@/providers/base';

const nanoid = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 10);
const baseUrl = 'https://d000d.com';

export const doodScraper = makeEmbed({
id: 'dood',
name: 'dood',
rank: 173,
async scrape(ctx) {
const baseUrl = 'https://d0000d.com';
let url = ctx.url;
if (ctx.url.includes('primewire')) {
const request = await ctx.proxiedFetcher.full(ctx.url);
url = request.finalUrl;
}

const id = ctx.url.split('/d/')[1] || ctx.url.split('/e/')[1];
const id = url.split('/d/')[1] || url.split('/e/')[1];

const doodData = await ctx.proxiedFetcher<string>(`/e/${id}`, {
method: 'GET',
Expand Down Expand Up @@ -46,7 +51,7 @@ export const doodScraper = makeEmbed({
},
},
headers: {
Referer: 'https://d0000d.com/',
Referer: baseUrl,
},
},
],
Expand Down
17 changes: 16 additions & 1 deletion src/providers/embeds/febbox/qualities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ function mapToQuality(quality: FebboxQuality): FebboxQuality | null {
};
}

function removeBadUrlParams(url: string): string {
const urlObject = new URL(url);

const urlSearchParams = new URLSearchParams(urlObject.search);

const keysToKeep = ['KEY1', 'KEY2'];
for (const key of Array.from(urlSearchParams.keys())) {
if (!keysToKeep.includes(key)) {
urlSearchParams.delete(key);
}
}

return `${urlObject.origin}${urlObject.pathname}?${urlSearchParams.toString()}`;
}

export async function getStreamQualities(ctx: ScrapeContext, apiQuery: object) {
const mediaRes: { list: FebboxQuality[] } = (await sendRequest(ctx, apiQuery)).data;

Expand All @@ -32,7 +47,7 @@ export async function getStreamQualities(ctx: ScrapeContext, apiQuery: object) {
if (foundQuality) {
qualities[quality] = {
type: 'mp4',
url: foundQuality.path,
url: removeBadUrlParams(foundQuality.path),
};
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/providers/embeds/filemoon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const fileMoonScraper = makeEmbed({
referer: ctx.url,
},
});
const evalCode = evalCodeRegex.exec(embedRes);
const evalCode = embedRes.match(evalCodeRegex);
if (!evalCode) throw new Error('Failed to find eval code');
const unpacked = unpack(evalCode[1]);
const file = fileRegex.exec(unpacked);
Expand Down
39 changes: 39 additions & 0 deletions src/providers/embeds/streamtape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { flags } from '@/entrypoint/utils/targets';
import { makeEmbed } from '@/providers/base';

export const streamtapeScraper = makeEmbed({
id: 'streamtape',
name: 'Streamtape',
rank: 160,
async scrape(ctx) {
const embed = await ctx.proxiedFetcher<string>(ctx.url);

const match = embed.match(/robotlink'\).innerHTML = (.*)'/);
if (!match) throw new Error('No match found');

const [fh, sh] = match?.[1]?.split("+ ('") ?? [];
if (!fh || !sh) throw new Error('No match found');

const url = `https:${fh?.replace(/'/g, '').trim()}${sh?.substring(3).trim()}`;

return {
stream: [
{
id: 'primary',
type: 'file',
flags: [flags.CORS_ALLOWED, flags.IP_LOCKED],
captions: [],
qualities: {
unknown: {
type: 'mp4',
url,
},
},
headers: {
Referer: 'https://streamtape.com',
},
},
],
};
},
});
36 changes: 36 additions & 0 deletions src/providers/embeds/streamvid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as unpacker from 'unpacker';

import { flags } from '@/entrypoint/utils/targets';
import { makeEmbed } from '@/providers/base';

const packedRegex = /(eval\(function\(p,a,c,k,e,d\).*\)\)\))/;
const linkRegex = /src:"(https:\/\/[^"]+)"/;

export const streamvidScraper = makeEmbed({
id: 'streamvid',
name: 'Streamvid',
rank: 215,
async scrape(ctx) {
// Example url: https://streamvid.net/fu1jaf96vofx
const streamRes = await ctx.proxiedFetcher<string>(ctx.url);
const packed = streamRes.match(packedRegex);

if (!packed) throw new Error('streamvid packed not found');

const unpacked = unpacker.unpack(packed[1]);
const link = unpacked.match(linkRegex);

if (!link) throw new Error('streamvid link not found');
return {
stream: [
{
type: 'hls',
id: 'primary',
playlist: link[1],
flags: [flags.CORS_ALLOWED],
captions: [],
},
],
};
},
});
33 changes: 33 additions & 0 deletions src/providers/embeds/voe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { flags } from '@/entrypoint/utils/targets';
import { makeEmbed } from '@/providers/base';

const linkRegex = /'hls': ?'(http.*?)',/;

export const voeScraper = makeEmbed({
id: 'voe',
name: 'voe.sx',
rank: 180,
async scrape(ctx) {
const embed = await ctx.proxiedFetcher<string>(ctx.url);

const playerSrc = embed.match(linkRegex) ?? [];

const streamUrl = playerSrc[1];
if (!streamUrl) throw new Error('Stream url not found in embed code');

return {
stream: [
{
type: 'hls',
id: 'primary',
playlist: streamUrl,
flags: [flags.CORS_ALLOWED],
captions: [],
headers: {
Referer: 'https://voe.sx',
},
},
],
};
},
});
3 changes: 2 additions & 1 deletion src/providers/sources/flixhq/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { NotFoundError } from '@/utils/errors';
export const flixhqScraper = makeSourcerer({
id: 'flixhq',
name: 'FlixHQ',
rank: 100,
rank: 61,
flags: [flags.CORS_ALLOWED],
disabled: true,
async scrapeMovie(ctx) {
const id = await getFlixhqId(ctx, ctx.media);
if (!id) throw new NotFoundError('no search results match');
Expand Down
3 changes: 2 additions & 1 deletion src/providers/sources/gomovies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ export const gomoviesBase = `https://gomovies.sx`;
export const goMoviesScraper = makeSourcerer({
id: 'gomovies',
name: 'GOmovies',
rank: 110,
rank: 60,
flags: [flags.CORS_ALLOWED],
disabled: true,
async scrapeShow(ctx) {
const search = await ctx.proxiedFetcher<string>(`/ajax/search`, {
method: 'POST',
Expand Down
3 changes: 2 additions & 1 deletion src/providers/sources/goojara/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ async function universalScraper(ctx: ShowScrapeContext | MovieScrapeContext): Pr
export const goojaraScraper = makeSourcerer({
id: 'goojara',
name: 'Goojara',
rank: 225,
rank: 70,
flags: [],
disabled: true,
scrapeShow: universalScraper,
scrapeMovie: universalScraper,
});
2 changes: 1 addition & 1 deletion src/providers/sources/hdrezka/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const universalScraper = async (ctx: ShowScrapeContext | MovieScrapeContext): Pr
export const hdRezkaScraper = makeSourcerer({
id: 'hdrezka',
name: 'HDRezka',
rank: 195,
rank: 120,
flags: [flags.CORS_ALLOWED, flags.IP_LOCKED],
scrapeShow: universalScraper,
scrapeMovie: universalScraper,
Expand Down
2 changes: 1 addition & 1 deletion src/providers/sources/kissasian/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { search } from './search';
export const kissAsianScraper = makeSourcerer({
id: 'kissasian',
name: 'KissAsian',
rank: 130,
rank: 40,
flags: [flags.CORS_ALLOWED],
disabled: true,

Expand Down
2 changes: 1 addition & 1 deletion src/providers/sources/lookmovie/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const lookmovieScraper = makeSourcerer({
id: 'lookmovie',
name: 'LookMovie',
disabled: true,
rank: 700,
rank: 50,
flags: [flags.IP_LOCKED],
scrapeShow: universalScraper,
scrapeMovie: universalScraper,
Expand Down
3 changes: 2 additions & 1 deletion src/providers/sources/nepu/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ const universalScraper = async (ctx: MovieScrapeContext | ShowScrapeContext) =>
export const nepuScraper = makeSourcerer({
id: 'nepu',
name: 'Nepu',
rank: 111,
rank: 80,
flags: [],
disabled: true,
scrapeMovie: universalScraper,
scrapeShow: universalScraper,
});
2 changes: 2 additions & 0 deletions src/providers/sources/primewire/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const primewireBase = 'https://www.primewire.tf';
export const primewireApiKey = atob('bHpRUHNYU0tjRw==');
7 changes: 7 additions & 0 deletions src/providers/sources/primewire/decryption/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Maintaining decryption

This folder contains the decryption logic for the primewire provider

The code in `blowfish.ts` is a de-obfuscated version of the original code that is used to decrypt the video links. You can find original the code [in this JavaScript file](https://www.primewire.tf/js/app-21205005105979fb964d17bf03570023.js?vsn=d]) by searching for the keyword "sBox0".

The code is minified, so use prettier to deobfuscate it. In the case that the URL changes, you can find it used in the [primewire homepage](https://www.primewire.tf/).
Loading

0 comments on commit f8a5120

Please sign in to comment.