From 447ffe4a69bca8969aceaa54b46de8852bb58325 Mon Sep 17 00:00:00 2001 From: James Hawkins <jhawki2005@gmail.com> Date: Thu, 30 Dec 2021 19:23:15 +0000 Subject: [PATCH] Add new source! --- .env | 2 +- src/components/VideoElement.js | 4 +- src/lib/index.js | 85 +++++++------- src/lib/scraper/gdriveplayer.js.disabled | 111 ++++++++++++++++++ .../{gomostream.js => gomostream.js.disabled} | 2 + src/lib/scraper/theflix.js | 70 +++++++++++ src/lib/scraper/vmovee.js.disabled | 84 +++++++++++++ 7 files changed, 312 insertions(+), 46 deletions(-) create mode 100644 src/lib/scraper/gdriveplayer.js.disabled rename src/lib/scraper/{gomostream.js => gomostream.js.disabled} (96%) create mode 100644 src/lib/scraper/theflix.js create mode 100644 src/lib/scraper/vmovee.js.disabled diff --git a/.env b/.env index 73026647..c4a4738f 100644 --- a/.env +++ b/.env @@ -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= diff --git a/src/components/VideoElement.js b/src/components/VideoElement.js index da4dc0e8..4a08fbe6 100644 --- a/src/components/VideoElement.js +++ b/src/components/VideoElement.js @@ -18,7 +18,7 @@ export function VideoElement({ streamUrl, loading, setProgress, videoRef, startT } React.useEffect(() => { - if (!streamUrl.endsWith('.mp4')) { + if (!streamUrl.includes('.mp4')) { setError(false) 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) return <VideoPlaceholder>No video selected</VideoPlaceholder> - if (!streamUrl.endsWith('.mp4')) { + if (!streamUrl.includes('.mp4')) { return ( <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}` } />) } diff --git a/src/lib/index.js b/src/lib/index.js index 3174c2bd..f9adfc4d 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -1,44 +1,43 @@ -import lookMovie from './scraper/lookmovie'; -import gomostream from './scraper/gomostream'; - -async function findContent(searchTerm, type) { - const results = { options: []}; - const content = await Promise.all([ - lookMovie.findContent(searchTerm, type), - gomostream.findContent(searchTerm, type) - ]); - - content.forEach((o) => { - if (!o || !o.options) return; - - o.options.forEach((i) => { - if (!i) return; - results.options.push(i) - }) - }); - - return results; -} - -async function getStreamUrl(slug, type, source, season, episode) { - switch (source) { - case 'lookmovie': - return await lookMovie.getStreamUrl(slug, type, season, episode); - case 'gomostream': - return await gomostream.getStreamUrl(slug, type, season, episode); - default: - return; - } -} - -async function getEpisodes(slug, source) { - switch (source) { - case 'lookmovie': - return await lookMovie.getEpisodes(slug); - case 'gomostream': - default: - return; - } -} - +import lookmovie from './scraper/lookmovie'; +import theflix from './scraper/theflix'; + +async function findContent(searchTerm, type) { + const results = { options: []}; + const content = await Promise.all([ + lookmovie.findContent(searchTerm, type), + theflix.findContent(searchTerm, type) + ]); + + content.forEach((o) => { + if (!o || !o.options) return; + + o.options.forEach((i) => { + if (!i) return; + results.options.push(i) + }) + }); + + return results; +} + +async function getStreamUrl(slug, type, source, season, episode) { + switch (source) { + case 'lookmovie': + return await lookmovie.getStreamUrl(slug, type, season, episode); + case 'theflix': + return await theflix.getStreamUrl(slug, type, season, episode); + default: + return; + } +} + +async function getEpisodes(slug, source) { + switch (source) { + case 'lookmovie': + return await lookmovie.getEpisodes(slug); + default: + return; + } +} + export { findContent, getStreamUrl, getEpisodes } \ No newline at end of file diff --git a/src/lib/scraper/gdriveplayer.js.disabled b/src/lib/scraper/gdriveplayer.js.disabled new file mode 100644 index 00000000..0c206844 --- /dev/null +++ b/src/lib/scraper/gdriveplayer.js.disabled @@ -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; \ No newline at end of file diff --git a/src/lib/scraper/gomostream.js b/src/lib/scraper/gomostream.js.disabled similarity index 96% rename from src/lib/scraper/gomostream.js rename to src/lib/scraper/gomostream.js.disabled index f93eb171..6be4ec04 100644 --- a/src/lib/scraper/gomostream.js +++ b/src/lib/scraper/gomostream.js.disabled @@ -1,3 +1,5 @@ +// THIS SCRAPER DOES NOT CURRENTLY WORK AND IS NOT IN USE + import { unpack } from '../util/unpacker'; const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://gomo.to`; diff --git a/src/lib/scraper/theflix.js b/src/lib/scraper/theflix.js new file mode 100644 index 00000000..a27dc05c --- /dev/null +++ b/src/lib/scraper/theflix.js @@ -0,0 +1,70 @@ +const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://www.theflix.to`; + +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; + } + + const title = node.querySelector('div.details > div.wrapper > div.title > div > a').textContent; + const year = node.querySelector('div.details > div.wrapper > div.title > span').textContent.trim().split(' ')[2]; + const slug = node.querySelector('div.details > div.wrapper > div.title > div > a').getAttribute('href').split('/')[2]; + + 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 getStreamUrl(slug, type, season, episode) { + if (type !== 'movie') return; + + const res = await fetch(`${BASE_URL}/${type}/${slug}?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 } +export default theflix; \ No newline at end of file diff --git a/src/lib/scraper/vmovee.js.disabled b/src/lib/scraper/vmovee.js.disabled new file mode 100644 index 00000000..41039ea6 --- /dev/null +++ b/src/lib/scraper/vmovee.js.disabled @@ -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; \ No newline at end of file