/** * filmpalast.js * A module for Sora that provides watch functionality for filmpalast.to. * @module filmpalast * @author JMcrafte26 * @license MIT * @version 1.1.3 * @mirror https://api.jm26.net/sora-modules/filmpalast/filmpalast.json */ /** * Searches for films on filmpalast.to based on a keyword. * @param {string} keyword - The search keyword. * @returns {Promise} - A JSON string of search results. */ async function searchResults(keyword) { try { const encodedKeyword = encodeURIComponent(keyword); const html = await fetch( `https://filmpalast.to/search/title/${encodedKeyword}` ); const filmListRegex = /
/g; const items = html.match(filmListRegex) || []; const results = []; items.forEach((itemHtml, index) => { const titleMatch = itemHtml.match( /]*>([^<]+)<\/a>/ ); let title = titleMatch ? titleMatch[3] : ""; const hrefMatch = itemHtml.match( /]*>/ ); const href = hrefMatch ? `https://filmpalast.to/stream/${hrefMatch[1]}` : ""; const imageMatch = itemHtml.match( /]+src="([^"]+)"[^>]+class="cover-opacity"[^>]*>/ ); const image = "https://filmpalast.to" + (imageMatch ? imageMatch[1] : ""); title = cleanTitle(title); if (title && href) { results.push({ title, image, href, }); } }); return JSON.stringify(results); } catch (error) { console.log("Fetch error:", error); return JSON.stringify([{ title: "Error", image: "", href: "" }]); } } /** * Cleans the title by replacing HTML entities with their corresponding characters. * @param {string} title - The title to clean. * @returns {string} - The cleaned title. */ function cleanTitle(title) { return title .replace(/&/g, "&") .replace(/"/g, '"') .replace(/'/g, "'") .replace(/</g, "<") .replace(/>/g, ">"); } /** * Extracts details from a film's page. * @param {string} url - The URL of the film's page. * @returns {Promise} - A JSON string of the film's details. */ async function extractDetails(url) { try { const html = await fetch(url); const descriptionMatch = html.match( /([^<]+)<\/span>/ ); const description = descriptionMatch ? descriptionMatch[1] : "Error loading description"; const durationMatch = html.match(/
Spielzeit: ([^<]+)<\/em>/); const duration = durationMatch ? durationMatch[1] : "Unknown"; const airedMatch = html.match(/
Veröffentlicht: (\d{4})/); const aired = airedMatch ? airedMatch[1] : "Unknown"; const transformedResults = [ { description, aliases: `Duration: ${duration}`, airdate: `Aired: ${aired}`, }, ]; return JSON.stringify(transformedResults); } catch (error) { console.log("Details error:", error); return JSON.stringify([ { description: "Error loading description", aliases: "Duration: Unknown", airdate: "Aired: Unknown", }, ]); } } /** * Extracts episodes from a film's page. * @param {string} url - The URL of the film's page. * @returns {Promise} - A JSON string of the episodes. */ async function extractEpisodes(url) { try { const match = url.match(/https:\/\/filmpalast\.to\/stream\/(.+)$/); if (!match) { return JSON.stringify([{ number: "0", href: "" }]); } return JSON.stringify([{ number: "1", href: url }]); } catch (error) { console.log("Fetch error:", error); } } /** * Extracts the stream URL from a film's page. * @param {string} url - The URL of the film's page. * @returns {Promise} - The stream URL or null if not found. * */ async function extractStreamUrl(url) { try { const response = await fetch(url); const html = await response.text ? response.text() : response; let streamUrl = null; try { streamUrl = await voeExtract(html); } catch (error) { console.log('VOE HD extraction error:', error); } console.log('Voe Stream URL: ' + streamUrl); if (streamUrl && streamUrl !== false && streamUrl !== null) { return streamUrl; } console.log('using alternative extraction method'); try { streamUrl = await bigWarpExtract(html); } catch (error) { console.log('BigWarp HD extraction error:', error); } console.log('BigWarp Stream URL: ' + streamUrl); if (streamUrl && streamUrl !== false && streamUrl !== null) { return streamUrl; } console.log('No stream URL found'); return null; } catch (error) { console.log("Fetch error:", error); return null; } } /** * Extracts the stream URL from a film's page. * @param {string} url - The URL of the film's page. * @returns {Promise} - The stream URL or null if not found. * Thanks to @Hamzo for the Voe extraction code. */ async function voeExtract(html) { console.log('VOE HD extraction method'); const voeRegex = /