Files
Films/script.js
2026-02-24 19:44:22 +03:00

265 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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=',
'https://api.codetabs.com/v1/proxy?quest=',
'https://thingproxy.freeboard.io/fetch/',
'https://cors-anywhere.herokuapp.com/',
'https://corsproxy.ca/',
'https://proxy.t vot.pw/',
];
// Кеш страниц фильмов и постеров
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 = [
'<a[^>]+href="(/news/[^"#]+)"[^>]*>\\s*<img[^>]+src="([^"]+)"',
'<img[^>]+src="([^"]+)"[^>]*>\\s*<a[^>]+href="(/news/[^"#]+)"',
'class="kino-h"[^>]*title="[^"]*"[^>]*>[\\s\\S]*?<img[^>]+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('<img[^>]+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('<img[^>]+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);