Add hollymoviehd/hollymoviehd.js

This commit is contained in:
aka paul 2026-01-01 14:41:30 +00:00
parent 5f64c89c7a
commit dc420790e6

View file

@ -0,0 +1,347 @@
async function searchResults(keyword) {
try {
let transformedResults = [];
const keywordGroups = {
trending: ["!trending", "!hot", "!tr", "!!"],
topRatedMovie: ["!top-rated-movie", "!topmovie", "!tm", "??"],
topRatedTV: ["!top-rated-tv", "!toptv", "!tt", "::"],
popularMovie: ["!popular-movie", "!popmovie", "!pm", ";;"],
popularTV: ["!popular-tv", "!poptv", "!pt", "++"],
};
const skipTitleFilter = Object.values(keywordGroups).flat();
const shouldFilter = !matchesKeyword(keyword, skipTitleFilter);
const encodedKeyword = encodeURIComponent(keyword);
let baseUrlTemplate = null;
if (matchesKeyword(keyword, keywordGroups.trending)) {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/trending/all/week?api_key=9801b6b0548ad57581d111ea690c85c8&include_adult=false&page=${page}`)}&simple=true`;
} else if (matchesKeyword(keyword, keywordGroups.topRatedMovie)) {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/movie/top_rated?api_key=9801b6b0548ad57581d111ea690c85c8&include_adult=false&page=${page}`)}&simple=true`;
} else if (matchesKeyword(keyword, keywordGroups.topRatedTV)) {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/top_rated?api_key=9801b6b0548ad57581d111ea690c85c8&include_adult=false&page=${page}`)}&simple=true`;
} else if (matchesKeyword(keyword, keywordGroups.popularMovie)) {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/movie/popular?api_key=9801b6b0548ad57581d111ea690c85c8&include_adult=false&page=${page}`)}&simple=true`;
} else if (matchesKeyword(keyword, keywordGroups.popularTV)) {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/popular?api_key=9801b6b0548ad57581d111ea690c85c8&include_adult=false&page=${page}`)}&simple=true`;
} else {
baseUrlTemplate = (page) => `https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/search/multi?api_key=9801b6b0548ad57581d111ea690c85c8&query=${encodedKeyword}&include_adult=false&page=${page}`)}&simple=true`;
}
let dataResults = [];
if (baseUrlTemplate) {
const pagePromises = Array.from({ length: 5 }, (_, i) =>
soraFetch(baseUrlTemplate(i + 1)).then(r => r.json())
);
const pages = await Promise.all(pagePromises);
dataResults = pages.flatMap(p => p.results || []);
}
if (dataResults.length > 0) {
transformedResults = transformedResults.concat(
dataResults
.map(result => {
if (result.media_type === "movie" || result.title) {
return {
title: result.title || result.name || result.original_title || result.original_name || "Untitled",
image: result.poster_path ? `https://image.tmdb.org/t/p/w500${result.poster_path}` : "",
href: `movie/${result.id}`,
};
} else if (result.media_type === "tv" || result.name) {
return {
title: result.name || result.title || result.original_name || result.original_title || "Untitled",
image: result.poster_path ? `https://image.tmdb.org/t/p/w500${result.poster_path}` : "",
href: `tv/${result.id}/1/1`,
};
}
})
.filter(Boolean)
.filter(r => !shouldFilter || r.title.toLowerCase().includes(keyword.toLowerCase()))
);
}
console.log("Transformed Results: " + JSON.stringify(transformedResults));
return JSON.stringify(transformedResults);
} catch (error) {
console.log("Fetch error in searchResults: " + error);
return JSON.stringify([{ title: "Error", image: "", href: "" }]);
}
}
function matchesKeyword(keyword, commands) {
const lower = keyword.toLowerCase();
return commands.some(cmd => lower.startsWith(cmd.toLowerCase()));
}
async function extractDetails(url) {
try {
if(url.includes('movie')) {
const match = url.match(/movie\/([^\/]+)/);
if (!match) throw new Error("Invalid URL format");
const movieId = match[1];
const responseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/movie/${movieId}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const data = await responseText.json();
const transformedResults = [{
description: data.overview || 'No description available',
aliases: `Duration: ${data.runtime ? data.runtime + " minutes" : 'Unknown'}`,
airdate: `Released: ${data.release_date ? data.release_date : 'Unknown'}`
}];
return JSON.stringify(transformedResults);
} else if(url.includes('tv')) {
const match = url.match(/tv\/([^\/]+)/);
if (!match) throw new Error("Invalid URL format");
const showId = match[1];
const responseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/${showId}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const data = await responseText.json();
const transformedResults = [{
description: data.overview || 'No description available',
aliases: `Duration: ${data.episode_run_time && data.episode_run_time.length ? data.episode_run_time.join(', ') + " minutes" : 'Unknown'}`,
airdate: `Aired: ${data.first_air_date ? data.first_air_date : 'Unknown'}`
}];
console.log(JSON.stringify(transformedResults));
return JSON.stringify(transformedResults);
} else {
throw new Error("Invalid URL format");
}
} catch (error) {
console.log('Details error: ' + error);
return JSON.stringify([{
description: 'Error loading description',
aliases: 'Duration: Unknown',
airdate: 'Aired/Released: Unknown'
}]);
}
}
async function extractEpisodes(url) {
try {
if(url.includes('movie')) {
const match = url.match(/movie\/([^\/]+)/);
if (!match) throw new Error("Invalid URL format");
const movieId = match[1];
const movie = [
{ href: `/movie/${movieId}`, number: 1, title: "Full Movie" }
];
console.log(movie);
return JSON.stringify(movie);
} else if(url.includes('tv')) {
const match = url.match(/tv\/([^\/]+)\/([^\/]+)\/([^\/]+)/);
if (!match) throw new Error("Invalid URL format");
const showId = match[1];
const showResponseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/${showId}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const showData = await showResponseText.json();
let allEpisodes = [];
for (const season of showData.seasons) {
const seasonNumber = season.season_number;
if(seasonNumber === 0) continue;
const seasonResponseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/${showId}/season/${seasonNumber}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const seasonData = await seasonResponseText.json();
if (seasonData.episodes && seasonData.episodes.length) {
const episodes = seasonData.episodes.map(episode => ({
href: `/tv/${showId}/${seasonNumber}/${episode.episode_number}`,
number: episode.episode_number,
title: episode.name || ""
}));
allEpisodes = allEpisodes.concat(episodes);
}
}
console.log(allEpisodes);
return JSON.stringify(allEpisodes);
} else {
throw new Error("Invalid URL format");
}
} catch (error) {
console.log('Fetch error in extractEpisodes: ' + error);
return JSON.stringify([]);
}
}
async function extractStreamUrl(ID) {
if (ID.includes('movie')) {
const tmdbID = ID.replace('/movie/', '');
const responseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/movie/${tmdbID}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const data = await responseText.json();
const slug = data.title.toLowerCase().replace(/\s+/g, '-') + '-' + data.release_date.split('-')[0];
const url = `https://hollymoviehd.cc/${slug}/`;
console.log(url);
const responseTwo = await soraFetch(url);
const pageText = await responseTwo.text();
const streamkeyMatch = pageText.match(/data-streamkey="([^"]*)"/);
const nonceMatch = pageText.match(/data-wpnonce="([^"]*)"/);
if (streamkeyMatch && nonceMatch) {
const streamkey = streamkeyMatch[1];
const nonce = nonceMatch[1];
const ajaxParams = `action=ajax_getlinkstream&streamkey=${streamkey}&nonce=${nonce}&imdbid=&tmdbid=${tmdbID}`;
console.log(ajaxParams);
const headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://hollymoviehd.cc",
"Origin": "https://hollymoviehd.cc"
};
const apiResponse = await fetchv2("https://hollymoviehd.cc/wp-admin/admin-ajax.php", headers, "POST", ajaxParams);
const apiData = await apiResponse.json();
const serverUrl = apiData.servers_iframe.streamsvr;
console.log(serverUrl);
const serverResponse = await soraFetch(serverUrl);
const serverText = await serverResponse.text();
const csrfMatch = serverText.match(/id="csrf_token" value="([^"]*)"/);
if (csrfMatch) {
const csrfToken = csrfMatch[1];
const boundary = '----geckoformboundary7183c2c77a4fd6afe70224d86261ff15';
const body = `--${boundary}\r\nContent-Disposition: form-data; name="token"\r\n\r\n\r\n--${boundary}\r\nContent-Disposition: form-data; name="csrf_token"\r\n\r\n${csrfToken}\r\n--${boundary}--`;
const headers = {
'Referer': 'https://flashstream.cc/',
'Content-Type': `multipart/form-data; boundary=${boundary}`,
'Origin': 'https://flashstream.cc'
};
const postResponse = await soraFetch(serverUrl, {
method: 'POST',
headers: headers,
body: body
});
const postText = await postResponse.text();
console.log(postText);
const data = JSON.parse(postText);
const sources = data.sources;
const hlsSource = sources.find(s => s.type === 'hls' && s.file.startsWith('/streamsvr/'));
if (hlsSource) {
const streamUrl = 'https://flashstream.cc' + hlsSource.file;
const result = {
streams: [
{
title: "default",
streamUrl: streamUrl,
headers: {
"Referer": "https://flashstream.cc/",
"Origin": "https://flashstream.cc/"
}
}
],
subtitle: ""
};
return JSON.stringify(result);
}
}
}
} else if (ID.includes('tv')) {
const parts = ID.split('/');
const tmdbID = parts[2];
const seasonNumber = parts[3];
const episodeNumber = parts[4];
const responseText = await soraFetch(`https://post-eosin.vercel.app/api/proxy?url=${encodeURIComponent(`https://api.themoviedb.org/3/tv/${tmdbID}?api_key=ad301b7cc82ffe19273e55e4d4206885`)}&simple=true`);
const data = await responseText.json();
const slug = data.name.toLowerCase().replace(/\s+/g, '-') + '-season-' + seasonNumber + '-episode-' + episodeNumber;
const url = `https://hollymoviehd.cc/episode/${slug}/`;
console.log(url);
const responseTwo = await soraFetch(url);
const pageText = await responseTwo.text();
const streamkeyMatch = pageText.match(/data-streamkey="([^"]*)"/);
const nonceMatch = pageText.match(/data-wpnonce="([^"]*)"/);
if (streamkeyMatch && nonceMatch) {
const streamkey = streamkeyMatch[1];
const nonce = nonceMatch[1];
const ajaxParams = `action=ajax_getlinkstream&streamkey=${streamkey}&nonce=${nonce}&imdbid=&tmdbid=${tmdbID}`;
console.log(ajaxParams);
const headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://hollymoviehd.cc",
"Origin": "https://hollymoviehd.cc"
};
const apiResponse = await fetchv2("https://hollymoviehd.cc/wp-admin/admin-ajax.php", headers, "POST", ajaxParams);
const apiData = await apiResponse.json();
const serverUrl = apiData.servers_iframe.streamsvr;
console.log(serverUrl);
const serverResponse = await soraFetch(serverUrl);
const serverText = await serverResponse.text();
const csrfMatch = serverText.match(/id="csrf_token" value="([^"]*)"/);
if (csrfMatch) {
const csrfToken = csrfMatch[1];
const boundary = '----geckoformboundary7183c2c77a4fd6afe70224d86261ff15';
const body = `--${boundary}\r\nContent-Disposition: form-data; name="token"\r\n\r\n\r\n--${boundary}\r\nContent-Disposition: form-data; name="csrf_token"\r\n\r\n${csrfToken}\r\n--${boundary}--`;
const headers = {
'Referer': 'https://flashstream.cc/',
'Content-Type': `multipart/form-data; boundary=${boundary}`,
'Origin': 'https://flashstream.cc'
};
const postResponse = await soraFetch(serverUrl, {
method: 'POST',
headers: headers,
body: body
});
const postText = await postResponse.text();
console.log(postText);
const data = JSON.parse(postText);
const sources = data.sources;
const hlsSource = sources.find(s => s.type === 'hls' && s.file.startsWith('/streamsvr/'));
if (hlsSource) {
const streamUrl = 'https://flashstream.cc' + hlsSource.file;
const result = {
streams: [
{
title: "default",
streamUrl: streamUrl,
headers: {
"Referer": "https://flashstream.cc/",
"Origin": "https://flashstream.cc/"
}
}
],
subtitle: ""
};
return JSON.stringify(result);
}
}
}
}
}
async function soraFetch(url, options = { headers: {}, method: 'GET', body: null, encoding: 'utf-8' }) {
try {
return await fetchv2(
url,
options.headers ?? {},
options.method ?? 'GET',
options.body ?? null,
true,
options.encoding ?? 'utf-8'
);
} catch(e) {
try {
return await fetch(url, options);
} catch(error) {
return null;
}
}
}