From b6dbc538739bf3a88629ad5e3d7069f23f3154f4 Mon Sep 17 00:00:00 2001 From: aka paul <50n50@noreply.localhost> Date: Fri, 7 Nov 2025 19:06:17 +0000 Subject: [PATCH] Update mapple/mapple.js --- mapple/mapple.js | 61 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/mapple/mapple.js b/mapple/mapple.js index f06da92..1d9f6f1 100644 --- a/mapple/mapple.js +++ b/mapple/mapple.js @@ -120,8 +120,8 @@ async function extractDetails(url) { 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'}` + aliases: `If stream fails try again!`, + airdate: `If stream fails try again!` }]; console.log(JSON.stringify(transformedResults)); @@ -190,14 +190,60 @@ async function extractEpisodes(url) { } async function extractStreamUrl(ID) { - const chunkResponse = await soraFetch(atob("aHR0cHM6Ly9tYXBwbGUudWsvX25leHQvc3RhdGljL2NodW5rcy8yODk3LWE0ZTFmMDFkYmE5ZDRkMzcuanM=")); - const chunkText = await chunkResponse.text(); + const htmlResponse = await soraFetch("https://mapple.uk/watch/" + ID); + const htmlText = await htmlResponse.text(); - const actionMatch = chunkText.match(/createServerReference\)\("([a-f0-9]{40,})"[^"]*"getStreamUrl/); - const actionIdentifier = actionMatch ? actionMatch[1] : null; + const jsUrlRegex = /(?:src|href)="([^"]*\.js(?:\?[^"]*)?)"/g; + const jsUrls = []; + let match; + + while ((match = jsUrlRegex.exec(htmlText)) !== null) { + let jsUrl = match[1]; + if (jsUrl.startsWith('/_next/') || jsUrl.startsWith('/static/')) { + jsUrl = 'https://mapple.uk' + jsUrl; + } else if (!jsUrl.startsWith('http')) { + jsUrl = 'https://mapple.uk/' + jsUrl; + } + jsUrls.push(jsUrl); + } + + const uniqueJsUrls = [...new Set(jsUrls)]; + console.log("Found " + uniqueJsUrls.length + " unique JS files"); + + let actionIdentifier = null; + let foundPromiseResolver = null; + const foundPromise = new Promise((resolve) => { + foundPromiseResolver = resolve; + }); + + const searchPromises = uniqueJsUrls.map(async (url) => { + try { + if (actionIdentifier) return null; + const response = await soraFetch(url); + if (actionIdentifier) return null; + const text = await response.text(); + if (actionIdentifier) return null; + const actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"[^"]*"getStreamUrl/); + if (actionMatch && actionMatch[1] && !actionIdentifier) { + actionIdentifier = actionMatch[1]; + console.log("Found actionIdentifier in: " + url); + foundPromiseResolver(actionIdentifier); + return actionIdentifier; + } + return null; + } catch (e) { + console.log("Error fetching " + url + ": " + e); + return null; + } + }); + + await Promise.race([ + foundPromise, + Promise.all(searchPromises) + ]); if (!actionIdentifier) { - throw new Error("Failed to extract action identifier from chunk file"); + throw new Error("Failed to extract action identifier from any chunk file"); } console.log("Action Identifier: " + actionIdentifier); @@ -265,7 +311,6 @@ async function extractStreamUrl(ID) { } } - // Get English subtitles let englishSubtitleUrl = ""; try { const subResponse = await soraFetch(`https://mapple.uk/api/subtitles?id=${tmdbID}&mediaType=movie`);