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);