2021-07-14 00:31:37 +02:00
|
|
|
import Fuse from 'fuse.js'
|
|
|
|
import JSON5 from 'json5'
|
|
|
|
|
2021-08-30 12:46:39 +02:00
|
|
|
const BASE_URL = `${process.env.REACT_APP_CORS_PROXY_URL}https://lookmovie.io`;
|
2021-07-26 19:17:27 +02:00
|
|
|
|
|
|
|
async function findContent(searchTerm, type) {
|
|
|
|
const searchUrl = `${BASE_URL}/${type}s/search/?q=${encodeURIComponent(searchTerm)}`;
|
|
|
|
const searchRes = await fetch(searchUrl).then((d) => d.text());
|
|
|
|
|
|
|
|
// Parse DOM to find search results on full search page
|
|
|
|
const parser = new DOMParser();
|
|
|
|
const doc = parser.parseFromString(searchRes, "text/html");
|
|
|
|
const nodes = Array.from(doc.querySelectorAll('.movie-item-style-1'));
|
|
|
|
const results = nodes.map(node => {
|
|
|
|
return {
|
|
|
|
type,
|
|
|
|
title: node.querySelector('h6 a').innerText.trim(),
|
|
|
|
year: node.querySelector('.year').innerText.trim(),
|
|
|
|
slug: node.querySelector('a').href.split('/').pop(),
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const fuse = new Fuse(results, { threshold: 0.3, distance: 200, keys: ["title"] });
|
|
|
|
const matchedResults = fuse
|
|
|
|
.search(searchTerm.toString())
|
|
|
|
.map((result) => result.item);
|
|
|
|
|
|
|
|
if (matchedResults.length === 0) {
|
|
|
|
return { options: [] }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (matchedResults.length > 1) {
|
|
|
|
const res = { options: [] };
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-26 19:17:27 +02:00
|
|
|
matchedResults.forEach((r) => res.options.push({
|
|
|
|
title: r.title,
|
|
|
|
slug: r.slug,
|
|
|
|
type: r.type,
|
|
|
|
year: r.year,
|
|
|
|
source: 'lookmovie'
|
|
|
|
}));
|
|
|
|
|
|
|
|
return res;
|
|
|
|
} else {
|
|
|
|
const { title, slug, type, year } = matchedResults[0];
|
|
|
|
|
|
|
|
return {
|
|
|
|
options: [{ title, slug, type, year, source: 'lookmovie' }]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-13 17:45:44 +02:00
|
|
|
async function getVideoUrl(config) {
|
2021-09-13 22:26:29 +02:00
|
|
|
const { subtitles, token: accessToken } = await getAccessInfo(config);
|
2021-07-13 17:45:44 +02:00
|
|
|
const now = Math.floor(Date.now() / 1e3);
|
|
|
|
|
2021-09-13 20:25:29 +02:00
|
|
|
let subs;
|
|
|
|
|
|
|
|
if (config.type === "show") {
|
2021-09-13 22:26:29 +02:00
|
|
|
subs = await getEpisodeSubs(config);
|
2021-09-13 20:25:29 +02:00
|
|
|
} else if (config.type === "movie") {
|
2021-09-13 22:26:29 +02:00
|
|
|
subs = subtitles;
|
2021-09-13 20:25:29 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 18:31:35 +02:00
|
|
|
let url = '';
|
|
|
|
|
|
|
|
if (config.type === 'movie') {
|
2021-07-26 19:17:27 +02:00
|
|
|
url = `${BASE_URL}/manifests/movies/json/${config.id}/${now}/${accessToken}/master.m3u8`;
|
2021-07-14 18:31:35 +02:00
|
|
|
} else if (config.type === 'show') {
|
2021-07-26 19:17:27 +02:00
|
|
|
url = `${BASE_URL}/manifests/shows/json/${accessToken}/${now}/${config.id}/master.m3u8`;
|
2021-07-14 18:31:35 +02:00
|
|
|
}
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-21 00:49:33 +02:00
|
|
|
const videoOpts = await fetch(url).then((d) => d.json());
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-21 00:49:33 +02:00
|
|
|
// Find video URL and return it (with a check for a full url if needed)
|
|
|
|
const opts = ["1080p", "1080", "720p", "720", "480p", "480", "auto"]
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-21 00:49:33 +02:00
|
|
|
let videoUrl = "";
|
|
|
|
for (let res of opts) {
|
|
|
|
if (videoOpts[res] && !videoOpts[res].includes('dummy') && !videoOpts[res].includes('earth-1984') && !videoUrl) {
|
|
|
|
videoUrl = videoOpts[res]
|
2021-07-13 17:45:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-13 22:26:29 +02:00
|
|
|
return {
|
|
|
|
videoUrl: videoUrl.startsWith("/") ? `${BASE_URL}${videoUrl}` : videoUrl,
|
|
|
|
subs,
|
|
|
|
};
|
2021-09-13 20:25:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getEpisodeSubs (config) {
|
|
|
|
return await fetch(`${BASE_URL}/api/v1/shows/episode-subtitles/?id_episode=${config.id}`).then(res => res.json());
|
2021-07-13 17:45:44 +02:00
|
|
|
}
|
|
|
|
|
2021-09-13 22:26:29 +02:00
|
|
|
async function getAccessInfo(config) {
|
2021-07-14 18:31:35 +02:00
|
|
|
let url = '';
|
|
|
|
|
|
|
|
if (config.type === 'movie') {
|
2021-07-26 19:17:27 +02:00
|
|
|
url = `${BASE_URL}/api/v1/security/movie-access?id_movie=${config.id}&token=1&sk=&step=1`;
|
2021-07-14 18:31:35 +02:00
|
|
|
} else if (config.type === 'show') {
|
2021-07-26 19:17:27 +02:00
|
|
|
url = `${BASE_URL}/api/v1/security/show-access?slug=${config.slug}&token=&step=2`;
|
2021-07-14 18:31:35 +02:00
|
|
|
}
|
2021-07-13 17:45:44 +02:00
|
|
|
|
|
|
|
const data = await fetch(url).then((d) => d.json());
|
2021-09-13 22:26:29 +02:00
|
|
|
|
2021-07-13 17:45:44 +02:00
|
|
|
const token = data?.data?.accessToken;
|
2021-09-13 22:26:29 +02:00
|
|
|
const subtitles = data?.data?.subtitles;
|
2021-09-13 20:25:29 +02:00
|
|
|
|
2021-09-13 22:26:29 +02:00
|
|
|
if (token) return { token, subtitles };
|
2021-07-13 17:45:44 +02:00
|
|
|
|
|
|
|
return "Invalid type provided in config";
|
|
|
|
}
|
|
|
|
|
2021-07-15 00:09:42 +02:00
|
|
|
async function getEpisodes(slug) {
|
2021-07-26 19:17:27 +02:00
|
|
|
const url = `${BASE_URL}/shows/view/${slug}`;
|
2021-07-15 00:09:42 +02:00
|
|
|
const pageReq = await fetch(url).then((d) => d.text());
|
|
|
|
|
|
|
|
const data = JSON5.parse("{" +
|
|
|
|
pageReq
|
|
|
|
.slice(pageReq.indexOf(`show_storage`))
|
|
|
|
.split("};")[0]
|
|
|
|
.split("= {")[1]
|
|
|
|
.trim() +
|
|
|
|
"}"
|
|
|
|
);
|
|
|
|
|
2021-07-20 12:20:56 +02:00
|
|
|
let seasons = [];
|
|
|
|
let episodes = [];
|
|
|
|
data.seasons.forEach((e) => {
|
2021-07-19 16:32:40 +02:00
|
|
|
if (!seasons.includes(e.season))
|
|
|
|
seasons.push(e.season);
|
2021-07-20 12:20:56 +02:00
|
|
|
|
2021-07-19 16:32:40 +02:00
|
|
|
if (!episodes[e.season])
|
|
|
|
episodes[e.season] = []
|
|
|
|
episodes[e.season].push(e.episode)
|
|
|
|
})
|
|
|
|
|
|
|
|
return { seasons, episodes }
|
2021-07-15 00:09:42 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 18:31:35 +02:00
|
|
|
async function getStreamUrl(slug, type, season, episode) {
|
2021-07-26 19:17:27 +02:00
|
|
|
const url = `${BASE_URL}/${type}s/view/${slug}`;
|
2021-07-13 17:45:44 +02:00
|
|
|
const pageReq = await fetch(url).then((d) => d.text());
|
|
|
|
|
2021-07-13 19:15:56 +02:00
|
|
|
const data = JSON5.parse("{" +
|
2021-07-13 17:45:44 +02:00
|
|
|
pageReq
|
2021-07-14 00:31:37 +02:00
|
|
|
.slice(pageReq.indexOf(`${type}_storage`))
|
2021-07-13 17:45:44 +02:00
|
|
|
.split("};")[0]
|
|
|
|
.split("= {")[1]
|
|
|
|
.trim() +
|
2021-07-13 19:15:56 +02:00
|
|
|
"}"
|
|
|
|
);
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-14 18:31:35 +02:00
|
|
|
let id = '';
|
|
|
|
|
|
|
|
if (type === "movie") {
|
2021-07-20 12:20:56 +02:00
|
|
|
id = data.id_movie;
|
|
|
|
} else if (type === "show") {
|
|
|
|
const episodeObj = data.seasons.find((v) => { return v.season === season && v.episode === episode; });
|
2021-07-15 00:09:42 +02:00
|
|
|
|
2021-07-14 18:31:35 +02:00
|
|
|
if (episodeObj) {
|
2021-07-20 12:20:56 +02:00
|
|
|
id = episodeObj.id_episode;
|
|
|
|
}
|
|
|
|
}
|
2021-07-14 18:31:35 +02:00
|
|
|
|
2021-07-14 19:03:10 +02:00
|
|
|
if (id === '') {
|
|
|
|
return { url: '' }
|
|
|
|
}
|
|
|
|
|
2021-07-13 19:15:56 +02:00
|
|
|
const videoUrl = await getVideoUrl({
|
2021-07-14 00:31:37 +02:00
|
|
|
slug: slug,
|
2021-07-14 18:31:35 +02:00
|
|
|
id: id,
|
2021-07-14 10:43:45 +02:00
|
|
|
type: type,
|
2021-09-13 20:25:29 +02:00
|
|
|
});
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-09-13 20:25:29 +02:00
|
|
|
return { url: videoUrl.videoUrl, subtitles: videoUrl.subs };
|
2021-07-13 19:15:56 +02:00
|
|
|
}
|
2021-07-13 17:45:44 +02:00
|
|
|
|
2021-07-14 00:31:37 +02:00
|
|
|
|
2021-07-20 12:20:56 +02:00
|
|
|
const lookMovie = { findContent, getStreamUrl, getEpisodes };
|
2021-09-13 20:25:29 +02:00
|
|
|
export default lookMovie;
|