CoolFace
Apppublic

mikmc5/bitsa

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
mpeer.js183 linesDownload Raw Back to root
1import fetch from 'node-fetch';2import * as cheerio from 'cheerio';3 4// ==============================5// sanitizeTitle: Clean Cyrillic & Noise6// ==============================7function sanitizeTitle(rawTitle) {8    return rawTitle9        .replace(/[\u0400-\u04FF]+/g, '')               // Remove Cyrillic10        .replace(/[^\x00-\x7F]+/g, '')                   // Remove non-ASCII remnants11        .replace(/\[\s*[\u0400-\u04FF\d]+\s*[\u0400-\u04FF]*\]/g, match => {12            const digits = match.match(/\d+/);13            return digits ? `[${digits[0]}]` : '';14        })15        .replace(/^[\s/\\]+/, '')                        // Remove leading slashes or backslashes16        .replace(/\s{2,}/g, ' ')                         // Collapse multiple spaces17        .trim();18}19 20// ==============================21// fetchMegapeerTorrents: Main Export Function22// ==============================23async function fetchMegapeerTorrents(searchQuery) {24    console.log(`\n๐Ÿ”„ Fetching Megapeer results for: ${searchQuery}`);25 26    const encodedQuery = encodeURIComponent(searchQuery);27    const searchUrl = `https://megapeer.vip/browse.php?search=${encodedQuery}&age=&cat=0&stype=0&sort=0&ascdesc=0`;28    console.log(`๐Ÿ“ก Fetching: ${searchUrl}`);29 30    try {31        const response = await fetch(searchUrl, {32            headers: {33                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/134.0.0.0 Safari/537.36',34                'Accept': 'text/html',35                'Referer': 'https://megapeer.vip/',36            },37            method: 'GET',38        });39 40        if (!response.ok) {41            throw new Error(`Failed to fetch from Megapeer: ${response.status}`);42        }43 44        const pageHtml = await response.text();45        const $ = cheerio.load(pageHtml);46        const torrents = [];47 48        $('tr.table_fon').each((_, element) => {49            const titleElement = $(element).find('a.url');50            const rawTitle = titleElement.text().trim();51            const sanitizedTitle = sanitizeTitle(rawTitle);52 53            const torrentPage = titleElement.attr('href');54            const downloadLink = $(element).find('a[href^="/download/"]').attr('href');55            const size = $(element).find('td[align="right"]').text().trim();56            const dateElement = $(element).find('td').first();57            const date = dateElement.text().trim();58 59            const seedLeechCell = $(element).find('td[align="center"]');60            const seedsMatch = seedLeechCell.html().match(/<font color="#008000"[^>]*>(\d+)<\/font>/i);61            const leechesMatch = seedLeechCell.html().match(/<font color="#8b0000"[^>]*>(\d+)<\/font>/i);62 63            const seeds = seedsMatch ? parseInt(seedsMatch[1]) : 0;64            const leeches = leechesMatch ? parseInt(leechesMatch[1]) : 0;65 66            if (!torrentPage) return;67 68            const torrentPageUrl = `https://megapeer.vip${torrentPage}`;69            const directDownloadUrl = `https://megapeer.vip${downloadLink}`;70            const quality = extractQuality(sanitizedTitle);71 72            torrents.push({73                title: sanitizedTitle,74                quality,75                size,76                date,77                seeds,78                leeches,79                torrentPageUrl,80                directDownloadUrl81            });82        });83 84        const completedTorrents = await Promise.all(85            torrents.map(async (torrent) => {86                try {87                    const magnetLink = await extractMagnetLink(torrent.torrentPageUrl);88                    return {89                        websiteTitle: torrent.title,90                        quality: torrent.quality,91                        size: torrent.size,92                        date: torrent.date,93                        seeds: torrent.seeds,94                        leeches: torrent.leeches,95                        mainFileSize: parseSizeToBytes(torrent.size),96                        torrentPageUrl: torrent.torrentPageUrl,97                        directDownloadUrl: torrent.directDownloadUrl,98                        magnetLink: magnetLink || null,99                    };100                } catch (error) {101                    console.error(`Error processing torrent ${torrent.title}:`, error);102                    return null;103                }104            })105        );106 107        const validTorrents = completedTorrents.filter(Boolean);108 109        validTorrents.sort((a, b) => {110            if (b.seeds !== a.seeds) return b.seeds - a.seeds;111 112            const qualityOrder = { '2160p': 4, '4k': 4, 'uhd': 4, '1080p': 3, '720p': 2 };113            const qualityDiff = (qualityOrder[b.quality] || 0) - (qualityOrder[a.quality] || 0);114 115            return qualityDiff === 0 ? b.mainFileSize - a.mainFileSize : qualityDiff;116        });117 118        console.log(`โœ… Processed ${validTorrents.length} valid torrents from Megapeer`);119        return validTorrents;120    } catch (error) {121        console.error('โŒ Error fetching from Megapeer:', error);122        return [];123    }124}125 126// ==============================127// extractMagnetLink: Try to find magnet links (if available)128// ==============================129async function extractMagnetLink(torrentPageUrl) {130    try {131        await new Promise(resolve => setTimeout(resolve, Math.random() * 2000 + 1000));132 133        const response = await fetch(torrentPageUrl, {134            headers: {135                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/134.0.0.0 Safari/537.36',136                'Accept': 'text/html',137                'Referer': 'https://megapeer.vip/'138            },139            method: 'GET',140        });141 142        if (!response.ok) {143            throw new Error(`Failed to fetch torrent page: ${response.status}`);144        }145 146        const pageHtml = await response.text();147        const magnetMatch = pageHtml.match(/href="(magnet:\?xt=urn:btih:[^"]+)"/);148        return magnetMatch ? magnetMatch[1] : null;149    } catch (error) {150        console.error('โŒ Error extracting magnet link:', error);151        return null;152    }153}154 155// ==============================156// parseSizeToBytes: Convert Sizes for Sorting157// ==============================158function parseSizeToBytes(size) {159    if (!size) return 0;160    const sizeMatch = size.match(/([\d.]+)\s*(MB|GB|TB)/i);161    if (!sizeMatch) return 0;162 163    const [, value, unit] = sizeMatch;164    const multiplier = unit.toUpperCase() === 'TB' ? 1024 ** 4 :165                       unit.toUpperCase() === 'GB' ? 1024 ** 3 :166                       1024 ** 2;167    return parseFloat(value) * multiplier;168}169 170// ==============================171// extractQuality: Identify Quality from Title172// ==============================173function extractQuality(title) {174    if (!title) return '';175    const qualityMatch = title.match(/\b(2160p|1080p|720p|4k|uhd)\b/i);176    return qualityMatch ? qualityMatch[1].toLowerCase() : '';177}178 179// ==============================180// Export for Server.js181// ==============================182export { fetchMegapeerTorrents };183