Merge pull request #48 from JamesHawkinss/source/theflix

Add source: theflix
This commit is contained in:
James Hawkins 2021-12-30 20:55:04 +00:00 committed by GitHub
commit 54a619a945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 346 additions and 46 deletions

2
.env
View File

@ -1 +1 @@
REACT_APP_CORS_PROXY_URL=https://proxy-1.movie-web.workers.dev?destination= REACT_APP_CORS_PROXY_URL=https://proxy-1.movie-web.workers.dev/?destination=

View File

@ -18,7 +18,7 @@ export function VideoElement({ streamUrl, loading, setProgress, videoRef, startT
} }
React.useEffect(() => { React.useEffect(() => {
if (!streamUrl.endsWith('.mp4')) { if (!streamUrl.includes('.mp4')) {
setError(false) setError(false)
if (!videoRef || !videoRef.current || !streamUrl || streamUrl.length === 0 || loading) return; if (!videoRef || !videoRef.current || !streamUrl || streamUrl.length === 0 || loading) return;
@ -46,7 +46,7 @@ export function VideoElement({ streamUrl, loading, setProgress, videoRef, startT
if (!streamUrl || streamUrl.length === 0) if (!streamUrl || streamUrl.length === 0)
return <VideoPlaceholder>No video selected</VideoPlaceholder> return <VideoPlaceholder>No video selected</VideoPlaceholder>
if (!streamUrl.endsWith('.mp4')) { if (!streamUrl.includes('.mp4')) {
return ( return (
<video crossOrigin="anonymous" className="videoElement" ref={videoRef} controls autoPlay onProgress={setProgress} onLoadedData={onLoad}> <video crossOrigin="anonymous" className="videoElement" ref={videoRef} controls autoPlay onProgress={setProgress} onLoadedData={onLoad}>
{ streamData.subtitles && streamData.subtitles.map((sub, index) => <track key={index} kind="captions" label={sub.language} src={`${process.env.REACT_APP_CORS_PROXY_URL}https://lookmovie.io${sub.file}` } />) } { streamData.subtitles && streamData.subtitles.map((sub, index) => <track key={index} kind="captions" label={sub.language} src={`${process.env.REACT_APP_CORS_PROXY_URL}https://lookmovie.io${sub.file}` } />) }

View File

@ -1,11 +1,11 @@
import lookMovie from './scraper/lookmovie'; import lookmovie from './scraper/lookmovie';
import gomostream from './scraper/gomostream'; import theflix from './scraper/theflix';
async function findContent(searchTerm, type) { async function findContent(searchTerm, type) {
const results = { options: []}; const results = { options: []};
const content = await Promise.all([ const content = await Promise.all([
lookMovie.findContent(searchTerm, type), lookmovie.findContent(searchTerm, type),
gomostream.findContent(searchTerm, type) theflix.findContent(searchTerm, type)
]); ]);
content.forEach((o) => { content.forEach((o) => {
@ -23,9 +23,9 @@ async function findContent(searchTerm, type) {
async function getStreamUrl(slug, type, source, season, episode) { async function getStreamUrl(slug, type, source, season, episode) {
switch (source) { switch (source) {
case 'lookmovie': case 'lookmovie':
return await lookMovie.getStreamUrl(slug, type, season, episode); return await lookmovie.getStreamUrl(slug, type, season, episode);
case 'gomostream': case 'theflix':
return await gomostream.getStreamUrl(slug, type, season, episode); return await theflix.getStreamUrl(slug, type, season, episode);
default: default:
return; return;
} }
@ -34,8 +34,9 @@ async function getStreamUrl(slug, type, source, season, episode) {
async function getEpisodes(slug, source) { async function getEpisodes(slug, source) {
switch (source) { switch (source) {
case 'lookmovie': case 'lookmovie':
return await lookMovie.getEpisodes(slug); return await lookmovie.getEpisodes(slug);
case 'gomostream': case 'theflix':
return await theflix.getEpisodes(slug);
default: default:
return; return;
} }

View File

@ -0,0 +1,111 @@
// THIS SCRAPER DOES NOT CURRENTLY WORK AND IS NOT IN USE
const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://database.gdriveplayer.us`;
const MOVIE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://database.gdriveplayer.us/player.php`;
const SHOW_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://series.databasegdriveplayer.co/player.php`;
async function findContent(searchTerm, type) {
try {
if (type !== 'movie') return;
const term = searchTerm.toLowerCase()
const tmdbRes = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}https://www.themoviedb.org/search?query=${term}`).then(d => d.text());
const doc = new DOMParser().parseFromString(tmdbRes, 'text/html');
const nodes = Array.from(doc.querySelectorAll('div.results > div > div.wrapper'));
const results = nodes.slice(0, 10).map((node) => {
let type = node.querySelector('div.details > div.wrapper > div.title > div > a').getAttribute('data-media-type');
switch (type) {
case 'movie':
type = 'movie';
break;
case 'tv':
type = 'show';
// eslint-disable-next-line array-callback-return
return;
case 'collection':
// eslint-disable-next-line array-callback-return
return;
default:
break;
}
return {
type: type,
title: node.querySelector('div.details > div.wrapper > div.title > div > a').textContent,
year: node.querySelector('div.details > div.wrapper > div.title > span').textContent.trim().split(' ')[2],
slug: node.querySelector('div.details > div.wrapper > div.title > div > a').href.split('/')[4],
source: 'gdriveplayer'
}
});
if (results.length > 1) {
return { options: results };
} else {
return { options: [ results[0] ] }
}
} catch (err) {
console.error(err);
throw new Error(err)
}
}
async function getStreamUrl(slug, type, season, episode) {
if (type !== 'movie') return;
// const tmdbRes = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}https://www.themoviedb.org/search?query=${term}`).then(d => d.text());
console.log(`${MOVIE_URL}?tmdb=${slug}`)
const res = await fetch(`${MOVIE_URL}?tmdb=${slug}`).then(d => d.text());
const embed = Array.from(new DOMParser().parseFromString(res, 'text/html').querySelectorAll('.list-server-items a'))
.find((e) => e.textContent.includes("Mirror"))
if (embed && embed.getAttribute('href')) {
let href = embed.getAttribute('href');
if (href.startsWith('//')) href = `https:${href}`;
const res1 = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}${href}`.replace('streaming.php', 'download')).then(d => d.text());
const sb = Array.from(new DOMParser().parseFromString(res1, 'text/html').querySelectorAll('a'))
.find((a) => a.textContent.includes("StreamSB"));
console.log(sb);
if (sb && sb.getAttribute('href')) {
console.log(sb.getAttribute('href'))
const src = await sbPlayGetLink(sb.getAttribute('href'));
if (src) return { url: src };
}
}
return { url: '' }
}
async function sbPlayGetLink(href) {
if (href.startsWith("//")) href = `https:${href}`;
const res = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}${href}`).then(d => d.text());
const a = new DOMParser().parseFromString(res, 'text/html').querySelector('table tbody tr a');
if (a && a.getAttribute('onclick')) {
let match = a.getAttribute("onclick").match(/'([^']+)'/gm);
console.log(a.getAttribute("onclick"));
if (match) {
let [code, mode, hash] = match;
const url = `https://sbplay2.com/dl?op=download_orig&id=${code.replace(/'/gm, "")}&mode=${mode.replace(/'/gm, "")}&hash=${hash.replace(/'/gm, "")}`;
// https://sbplay2.com/dl?op=download_orig&id=glr78kyk21kd&mode=n&hash=1890245-0-0-1640889479-95e144cdfdbe0e9104a67b8e3eee0c2d
// https://sbplay2.com/dl?op=download_orig&id=0hh6mxf5qqn0&mode=h&hash=2473604-78-149-1640889782-797bc207a16b2934c21ea6fdb1e97352
// https://proxy-1.movie-web.workers.dev/?destination=https://sbplay2.com/dl?op=download_orig&id=glr78kyk21kd&mode=n&hash=1890245-0-0-1640889479-95e144cdfdbe0e9104a67b8e3eee0c2d
const text = await fetch(url).then((e) => e.text());
const a = new DOMParser().parseFromString(text, 'text/html').querySelector(".contentbox span a");
if (a && a.getAttribute("href")) return a.getAttribute("href");
}
}
}
const gdriveplayer = { findContent, getStreamUrl }
export default gdriveplayer;

View File

@ -1,3 +1,5 @@
// THIS SCRAPER DOES NOT CURRENTLY WORK AND IS NOT IN USE
import { unpack } from '../util/unpacker'; import { unpack } from '../util/unpacker';
const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://gomo.to`; const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://gomo.to`;

102
src/lib/scraper/theflix.js Normal file
View File

@ -0,0 +1,102 @@
const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://www.theflix.to`;
async function findContent(searchTerm, type) {
try {
const term = searchTerm.toLowerCase()
const tmdbRes = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}https://www.themoviedb.org/search/${type === 'show' ? 'tv' : type}?query=${term}`).then(d => d.text());
const doc = new DOMParser().parseFromString(tmdbRes, 'text/html');
const nodes = Array.from(doc.querySelectorAll('div.results > div > div.wrapper'));
const results = nodes.slice(0, 10).map((node) => {
let type = node.querySelector('div.details > div.wrapper > div.title > div > a').getAttribute('data-media-type');
type = type === 'tv' ? 'show' : type;
let title;
let year;
let slug;
if (type === 'movie') {
try {
title = node.querySelector('div.details > div.wrapper > div.title > div > a').textContent;
year = node.querySelector('div.details > div.wrapper > div.title > span').textContent.trim().split(' ')[2];
slug = node.querySelector('div.details > div.wrapper > div.title > div > a').getAttribute('href').split('/')[2];
} catch (e) {
// eslint-disable-next-line array-callback-return
return;
}
} else if (type === 'show') {
try {
title = node.querySelector('div.details > div.wrapper > div.title > div > a > h2').textContent;
year = node.querySelector('div.details > div.wrapper > div.title > span').textContent.trim().split(' ')[2];
slug = node.querySelector('div.details > div.wrapper > div.title > div > a').getAttribute('href').split('/')[2];
} catch (e) {
// eslint-disable-next-line array-callback-return
return;
}
}
return {
type: type,
title: title,
year: year,
slug: slug + '-' + title.replace(/[^a-z0-9]+|\s+/gmi, " ").replace(/\s+/g, '-').toLowerCase(),
source: 'theflix'
}
});
if (results.length > 1) {
return { options: results };
} else {
return { options: [ results[0] ] }
}
} catch (err) {
console.error(err);
throw new Error(err)
}
}
async function getEpisodes(slug) {
const tmdbRes = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}https://www.themoviedb.org/tv/${slug}/seasons`).then(d => d.text());
const sNodes = Array.from(new DOMParser().parseFromString(tmdbRes, 'text/html').querySelectorAll('div.column_wrapper > div.flex > div'));
let seasons = [];
let episodes = [];
for (let i = 0; i < sNodes.length; i++) {
const text = sNodes[i].querySelector('div > section > div > div > div > h2 > a').textContent;
if (!text.includes('Season')) return;
const season = text.split(' ')[1];
if (!seasons.includes(season)) {
seasons.push(season);
}
if (!episodes[season]) {
episodes[season] = [];
}
const epRes = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}https://www.themoviedb.org/tv/${slug}/season/${season}`).then(d => d.text());
const epNodes = Array.from(new DOMParser().parseFromString(epRes, 'text/html').querySelectorAll('div.episode_list > div.card'));
epNodes.forEach((e, i) => episodes[season].push(++i));
}
return { seasons, episodes };
}
async function getStreamUrl(slug, type, season, episode) {
const res = await fetch(`${BASE_URL}/${type === 'show' ? 'tv-show' : type}/${slug}/${type === 'show' ? `season-${season}/episode-${episode}` : ""}${ type === 'movie' ? 'movieInfo=' + slug : '' }`).then(d => d.text());
const scripts = Array.from(new DOMParser().parseFromString(res, "text/html").querySelectorAll('script'));
const prop = scripts.find((e) => e.textContent.includes("theflixvd.b-cdn"));
if (prop) {
const data = JSON.parse(prop.textContent);
return { url: data.props.pageProps.videoUrl };
}
return { url: '' }
}
const theflix = { findContent, getStreamUrl, getEpisodes }
export default theflix;

View File

@ -0,0 +1,84 @@
// THIS SCRAPER DOES NOT CURRENTLY WORK AND IS NOT IN USE
import { unpack } from '../util/unpacker';
const BASE_URL = `https://www.vmovee.watch`;
const CORS_URL = `${process.env.REACT_APP_CORS_PROXY_URL}${BASE_URL}`;
const SHOW_URL = `${CORS_URL}/series`
const MOVIE_URL = `${CORS_URL}/movies`
const MOVIE_URL_NO_CORS = `${BASE_URL}/movies`
async function findContent(searchTerm, type) {
try {
if (type !== 'movie') return;
const searchUrl = `${CORS_URL}/?s=${encodeURIComponent(searchTerm)}`;
const searchRes = await fetch(searchUrl).then((d) => d.text());
const parser = new DOMParser();
const doc = parser.parseFromString(searchRes, "text/html");
const nodes = Array.from(doc.querySelectorAll('div.search-page > div.result-item > article'));
const results = nodes.map(node => {
const imgHolder = node.querySelector('div.image > div.thumbnail > a');
const titleHolder = node.querySelector('div.title > a');
return {
type: imgHolder.querySelector('span').textContent === 'TV' ? 'show' : 'movie',
title: titleHolder.textContent,
year: node.querySelector('div.details > div.meta > span.year').textContent,
slug: titleHolder.href.split('/')[4],
source: 'vmovee'
}
});
if (results.length > 1) {
return { options: results };
} else {
return { options: [ results[0] ] }
}
} catch (err) {
throw new Error(err)
}
}
async function getStreamUrl(slug, type, season, episode) {
let url = '';
if (type === 'movie') {
url = `${MOVIE_URL}/${slug}`;
} else if (type === 'show') {
url = `${SHOW_URL}/${slug}`;
}
const res1 = await fetch(url, { headers: new Headers().append('referer', `${BASE_URL}/dashboard/admin-ajax.php`) });
const id = res1.headers.get('link').split('>')[0].split('?p=')[1];
const res2Headers = new Headers().append('referer', `${BASE_URL}/dashboard/admin-ajax.php`);
const form = new FormData();
form.append('action', 'doo_player_ajax')
form.append('post', id)
form.append('nume', '2')
form.append('type', type)
const res2 = await fetch(`${CORS_URL}/dashboard/admin-ajax.php`, {
method: 'POST',
headers: res2Headers,
body: form
}).then((res) => res.json());
let realUrl = res2.embed_url;
console.log(res2)
if (realUrl.startsWith('//')) {
realUrl = `https:${realUrl}`;
}
const res3 = await fetch(`${process.env.REACT_APP_CORS_PROXY_URL}${realUrl}`);
res3.headers.forEach(console.log)
return { url: '' }
}
const vmovee = { findContent, getStreamUrl }
export default vmovee;