const targetUrl = 'https://coldfilm.ink'; let currentFilmName = ''; let availableTorrents = []; // Публичные CORS-прокси const PROXIES = [ 'https://corsproxy.io/?', 'https://api.allorigins.win/raw?url=', 'https://proxy.cors.sh/', 'https://corsproxy.org/?', 'https://allorigins.win/raw?url=' ]; // Кеш страниц фильмов и постеров const filmData = new Map(); async function fetchWithProxy(url) { for (const proxy of PROXIES) { try { const response = await fetch(proxy + encodeURIComponent(url), { timeout: 15000 }); if (response.ok) return await response.text(); } catch (e) {} } throw new Error('Все прокси недоступны'); } function parseColdfilm(html) { const films = []; // Сначала соберём все ссылки на фильмы с названиями // Сразу исключаем Telegram const linksMap = new Map(); let match; const linkRegex = new RegExp('href="(/news/[^"#]+)"[^>]*class="kino-h"[^>]*title="([^"]+)\\[Смотреть Онлайн\\]"', 'gi'); while ((match = linkRegex.exec(html)) !== null) { const title = match[2].trim(); if (title.toLowerCase().includes('telegram')) continue; linksMap.set(match[1], title); } console.log('linksMap:', linksMap.size); // Пробуем разные паттерны для поиска постеров const patterns = [ ']+href="(/news/[^"#]+)"[^>]*>\\s*]+src="([^"]+)"', ']+src="([^"]+)"[^>]*>\\s*]+href="(/news/[^"#]+)"', 'class="kino-h"[^>]*title="[^"]*"[^>]*>[\\s\\S]*?]+src="([^"]+)"' ]; for (const pat of patterns) { const regex = new RegExp(pat, 'gi'); let count = 0; while ((match = regex.exec(html)) !== null) { count++; } console.log('Pattern:', pat.substring(0, 50), 'matches:', count); } // Ищем постеры по alt/title - там есть название фильма const posterMap = new Map(); const posterRegex = new RegExp(']+src="([^"]+)"[^>]+alt="([^"]*\\[Смотреть Онлайн\\])"[^>]*>', 'gi'); while ((match = posterRegex.exec(html)) !== null) { const poster = match[1]; const alt = match[2].replace('[Смотреть Онлайн]', '').trim(); let fullPoster = poster; if (!fullPoster.startsWith('http')) { fullPoster = targetUrl + poster; } posterMap.set(alt, fullPoster); } // Альтернативно - title вместо alt const posterRegex2 = new RegExp(']+src="([^"]+)"[^>]+title="([^"]*\\[Смотреть Онлайн\\])"[^>]*>', 'gi'); while ((match = posterRegex2.exec(html)) !== null) { const poster = match[1]; const title = match[2].replace('[Смотреть Онлайн]', '').trim(); if (!posterMap.has(title)) { let fullPoster = poster; if (!fullPoster.startsWith('http')) { fullPoster = targetUrl + poster; } posterMap.set(title, fullPoster); } } console.log('Найдено постеров:', posterMap.size); // Собираем фильмы и ищем постер по названию const urls = Array.from(linksMap.keys()); const titles = Array.from(linksMap.values()); console.log('URLs:', urls.length, 'Posters:', posterMap.size); for (let i = 0; i < titles.length; i++) { const url = urls[i]; const title = titles[i]; const poster = posterMap.get(title) || ''; films.push({ title, url, poster }); filmData.set(title, { url, poster }); } console.log('Фильмов с постерами:', films.length); return films.slice(0, 30); } async function loadFilms() { const status = document.getElementById('status'); const list = document.getElementById('films'); try { status.textContent = '🌐 Загружаем...'; const html = await fetchWithProxy(targetUrl); status.textContent = '🔍 Парсим...'; const films = parseColdfilm(html); if (films.length > 0) { status.className = 'status success'; status.textContent = `✅ Найдено ${films.length} релизов!`; list.innerHTML = ''; films.forEach((film, i) => { const li = document.createElement('li'); li.className = 'film-item'; // Постер const img = document.createElement('img'); img.className = 'film-poster'; img.src = film.poster; img.alt = film.title; img.onerror = () => { img.style.display = 'none'; }; // Инфо const info = document.createElement('div'); info.className = 'film-info'; const span = document.createElement('span'); span.className = 'film-title'; span.textContent = `${i + 1}. ${film.title}`; const btn = document.createElement('button'); btn.className = 'btn'; btn.textContent = '📥 Скачать'; btn.onclick = () => showQualityModal(film.title); info.appendChild(span); info.appendChild(btn); li.appendChild(img); li.appendChild(info); list.appendChild(li); }); } else { status.textContent = '❌ Фильмы не найдены'; status.className = 'status error'; } } catch (e) { status.textContent = `❌ Ошибка: ${e.message}`; status.className = 'status error'; } } async function showQualityModal(filmName) { const status = document.getElementById('status'); const modal = document.getElementById('qualityModal'); const options = document.getElementById('qualityOptions'); currentFilmName = filmName; availableTorrents = []; options.innerHTML = ''; try { status.className = 'status downloading'; status.textContent = `🔍 Ищем торренты для ${filmName}...`; const filmInfo = filmData.get(filmName); if (!filmInfo) throw new Error('Ссылка не найдена'); const filmUrl = filmInfo.url; const filmPageHtml = await fetchWithProxy(targetUrl + filmUrl); // Ищем все торренты на странице let match; const torrentRegex = /href="(\/t\d+\/[^"]+\.torrent)"/gi; while ((match = torrentRegex.exec(filmPageHtml)) !== null) { let url = match[1]; if (!url.startsWith('http')) { url = targetUrl + url; } // Определяем качество из названия файла const filename = url.toLowerCase(); let quality = 'Стандарт'; if (filename.includes('720p') || filename.includes('hd720')) quality = '720p'; else if (filename.includes('1080p') || filename.includes('hd1080')) quality = '1080p'; else if (filename.includes('4k') || filename.includes('2160p')) quality = '4K'; // Проверяем, не добавляли ли уже if (!availableTorrents.find(t => t.url === url)) { availableTorrents.push({ url, quality }); } } // Ищем magnet const magnetRegex = /href="(magnet:[^"]+)"/gi; while ((match = magnetRegex.exec(filmPageHtml)) !== null) { if (!availableTorrents.find(t => t.url === match[1])) { availableTorrents.push({ url: match[1], quality: 'Magnet' }); } } if (availableTorrents.length === 0) { throw new Error('Торренты не найдены'); } // Сортируем: 4K, 1080p, 720p, STD, Magnet const sortOrder = { '4K': 1, '1080p': 2, '720p': 3, 'Стандарт': 4, 'Magnet': 5 }; availableTorrents.sort((a, b) => (sortOrder[a.quality] || 99) - (sortOrder[b.quality] || 99)); // Создаём кнопки availableTorrents.forEach(t => { const btn = document.createElement('button'); btn.className = 'quality-btn'; btn.textContent = `📥 ${t.quality}`; btn.onclick = () => downloadTorrent(t.url); options.appendChild(btn); }); modal.classList.add('active'); status.textContent = `✅ Найдено ${availableTorrents.length} торрентов`; } catch (e) { status.className = 'status error'; status.textContent = `❌ Ошибка: ${e.message}`; } } function closeModal() { document.getElementById('qualityModal').classList.remove('active'); } function downloadTorrent(url) { const status = document.getElementById('status'); status.textContent = '⬇️ Открываем торрент...'; window.open(url, '_blank'); status.className = 'status success'; status.textContent = `✅ Торрент открыт!`; closeModal(); } // Запуск при загрузке loadFilms(); setInterval(loadFilms, 15 * 60 * 1000);