mirror of
https://github.com/p-stream/providers.git
synced 2026-05-18 23:02:19 +00:00
fix ee3 and promote
This commit is contained in:
parent
3f90c3d413
commit
2a77f87760
2 changed files with 84 additions and 68 deletions
|
|
@ -1,6 +1,4 @@
|
||||||
export const useAltEndpoint: boolean = false;
|
export const apiBaseUrl = 'https://borg.rips.cc';
|
||||||
|
|
||||||
export const baseUrl = useAltEndpoint ? 'https://rips.cc' : 'https://ee3.me';
|
|
||||||
|
|
||||||
export const username = '_sf_';
|
export const username = '_sf_';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,92 @@
|
||||||
import { flags } from '@/entrypoint/utils/targets';
|
|
||||||
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||||
import { Caption } from '@/providers/captions';
|
|
||||||
import { compareMedia } from '@/utils/compare';
|
|
||||||
import { MovieScrapeContext } from '@/utils/context';
|
import { MovieScrapeContext } from '@/utils/context';
|
||||||
import { makeCookieHeader } from '@/utils/cookie';
|
|
||||||
import { NotFoundError } from '@/utils/errors';
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
import { baseUrl, password, username } from './common';
|
import { apiBaseUrl, password, username } from './common';
|
||||||
import { itemDetails, renewResponse } from './types';
|
|
||||||
import { login, parseSearch } from './utils';
|
|
||||||
|
|
||||||
// this source only has movies
|
async function fetchMovie(ctx: MovieScrapeContext, ee3Auth: string): Promise<string | null> {
|
||||||
async function comboScraper(ctx: MovieScrapeContext): Promise<SourcererOutput> {
|
// Authenticate and get token
|
||||||
const pass = await login(username, password, ctx);
|
const authResp = await ctx.proxiedFetcher.full<{ token?: string }>(
|
||||||
if (!pass) throw new Error('Login failed');
|
`${apiBaseUrl}/api/collections/users/auth-with-password?expand=lists_liked`,
|
||||||
|
{
|
||||||
const search = parseSearch(
|
|
||||||
await ctx.proxiedFetcher<string>('/get', {
|
|
||||||
baseUrl,
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: new URLSearchParams({ query: ctx.media.title, action: 'search' }),
|
|
||||||
headers: {
|
headers: {
|
||||||
cookie: makeCookieHeader({ PHPSESSID: pass }),
|
Origin: 'https://ee3.me',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
}),
|
body: JSON.stringify({
|
||||||
|
identity: username,
|
||||||
|
password: ee3Auth,
|
||||||
|
}),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
if (authResp.statusCode !== 200) {
|
||||||
|
throw new Error(`Auth failed with status: ${authResp.statusCode}: ${JSON.stringify(authResp.body)}`);
|
||||||
|
}
|
||||||
|
|
||||||
const id = search.find((v) => v && compareMedia(ctx.media, v.title, v.year))?.id;
|
const jsonResponse = authResp.body;
|
||||||
if (!id) throw new NotFoundError('No watchable item found');
|
if (!jsonResponse?.token) {
|
||||||
|
throw new Error(`No token in auth response: ${JSON.stringify(jsonResponse)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = jsonResponse.token;
|
||||||
ctx.progress(20);
|
ctx.progress(20);
|
||||||
|
|
||||||
const details: itemDetails = JSON.parse(
|
// Find movie by TMDB ID
|
||||||
await ctx.proxiedFetcher<string>('/get', {
|
const movieUrl = `${apiBaseUrl}/api/collections/movies/records?page=1&perPage=48&filter=tmdb_data.id%20~%20${ctx.media.tmdbId}`;
|
||||||
baseUrl,
|
const movieResp = await ctx.proxiedFetcher.full<{ items?: Array<{ video?: string }> }>(movieUrl, {
|
||||||
method: 'POST',
|
headers: {
|
||||||
body: new URLSearchParams({ id, action: 'get_movie_info' }),
|
Authorization: `Bearer ${token}`,
|
||||||
headers: {
|
Origin: 'https://ee3.me',
|
||||||
cookie: makeCookieHeader({ PHPSESSID: pass }),
|
},
|
||||||
},
|
});
|
||||||
}),
|
|
||||||
);
|
if (movieResp.statusCode !== 200) {
|
||||||
if (!details.message.video) throw new Error('Failed to get the stream');
|
throw new Error(`Movie lookup failed with status: ${movieResp.statusCode}: ${JSON.stringify(movieResp.body)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const movieJsonResponse = movieResp.body;
|
||||||
|
if (!movieJsonResponse?.items || movieJsonResponse.items.length === 0) {
|
||||||
|
throw new NotFoundError(`No items found for TMDB ID ${ctx.media.tmdbId}: ${JSON.stringify(movieJsonResponse)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!movieJsonResponse.items[0].video) {
|
||||||
|
throw new NotFoundError(`No video field in first item: ${JSON.stringify(movieJsonResponse.items[0])}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const movieId = movieJsonResponse.items[0].video;
|
||||||
ctx.progress(40);
|
ctx.progress(40);
|
||||||
|
|
||||||
const keyParams: renewResponse = JSON.parse(
|
// Get video key
|
||||||
await ctx.proxiedFetcher<string>('/renew', {
|
const keyResp = await ctx.proxiedFetcher.full<{ key?: string }>(`${apiBaseUrl}/video/${movieId}/key`, {
|
||||||
baseUrl,
|
headers: {
|
||||||
method: 'POST',
|
Authorization: `Bearer ${token}`,
|
||||||
headers: {
|
Origin: 'https://ee3.me',
|
||||||
cookie: makeCookieHeader({ PHPSESSID: pass }),
|
},
|
||||||
},
|
});
|
||||||
}),
|
|
||||||
);
|
|
||||||
if (!keyParams.k) throw new Error('Failed to get the key');
|
|
||||||
ctx.progress(60);
|
|
||||||
|
|
||||||
const server = details.message.server === '1' ? 'https://vid.ee3.me/vid/' : 'https://vault.rips.cc/video/';
|
if (keyResp.statusCode !== 200) {
|
||||||
const k = keyParams.k;
|
throw new Error(`Key fetch failed with status: ${keyResp.statusCode}: ${JSON.stringify(keyResp.body)}`);
|
||||||
const url = `${server}${details.message.video}?${new URLSearchParams({ k })}`;
|
|
||||||
const captions: Caption[] = [];
|
|
||||||
|
|
||||||
// this how they actually deal with subtitles
|
|
||||||
if (details.message.subs?.toLowerCase() === 'yes' && details.message.imdbID) {
|
|
||||||
captions.push({
|
|
||||||
id: `https://rips.cc/subs/${details.message.imdbID}.vtt`,
|
|
||||||
url: `https://rips.cc/subs/${details.message.imdbID}.vtt`,
|
|
||||||
type: 'vtt',
|
|
||||||
hasCorsRestrictions: false,
|
|
||||||
language: 'en',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ctx.progress(90);
|
|
||||||
|
const keyJsonResponse = keyResp.body;
|
||||||
|
if (!keyJsonResponse?.key) {
|
||||||
|
throw new Error(`No key in response: ${JSON.stringify(keyJsonResponse)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.progress(60);
|
||||||
|
return `${movieId}?k=${keyJsonResponse.key}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function comboScraper(ctx: MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
|
const movData = await fetchMovie(ctx, password);
|
||||||
|
if (!movData) {
|
||||||
|
throw new NotFoundError('No watchable item found');
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.progress(80);
|
||||||
|
|
||||||
|
const videoUrl = `${apiBaseUrl}/video/${movData}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
embeds: [],
|
embeds: [],
|
||||||
|
|
@ -78,15 +94,17 @@ async function comboScraper(ctx: MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
{
|
{
|
||||||
id: 'primary',
|
id: 'primary',
|
||||||
type: 'file',
|
type: 'file',
|
||||||
flags: [flags.CORS_ALLOWED],
|
|
||||||
captions,
|
|
||||||
qualities: {
|
qualities: {
|
||||||
// should be unknown, but all the videos are 720p
|
unknown: {
|
||||||
720: {
|
|
||||||
type: 'mp4',
|
type: 'mp4',
|
||||||
url,
|
url: videoUrl,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
headers: {
|
||||||
|
Origin: 'https://ee3.me',
|
||||||
|
},
|
||||||
|
flags: [],
|
||||||
|
captions: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
@ -95,8 +113,8 @@ async function comboScraper(ctx: MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
export const ee3Scraper = makeSourcerer({
|
export const ee3Scraper = makeSourcerer({
|
||||||
id: 'ee3',
|
id: 'ee3',
|
||||||
name: 'EE3',
|
name: 'EE3',
|
||||||
rank: 120,
|
rank: 176,
|
||||||
disabled: true,
|
disabled: false,
|
||||||
flags: [flags.CORS_ALLOWED],
|
flags: [],
|
||||||
scrapeMovie: comboScraper,
|
scrapeMovie: comboScraper,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue