const { createClient } = require('./httpClient') const streamDb = require('./streamDb') const BODY_ERROR_KEYWORDS = ['error', 'not found', '404', 'no encontrado', 'expired', 'removed'] const validatorClient = createClient({ timeout: 8000, maxRedirects: 3, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36', }, }) async function validateUrl(url) { const inicio = Date.now() try { const res = await validatorClient.get(url, { maxRedirects: 3, validateStatus: () => true, }) const responseMs = Date.now() - inicio const statusCode = res.status const body = typeof res.data === 'string' ? res.data : String(res.data || '') if (statusCode < 200 || statusCode >= 400) { return { isAlive: false, responseMs, statusCode, error: `HTTP ${statusCode}` } } const bodyLower = body.toLowerCase() for (const keyword of BODY_ERROR_KEYWORDS) { if (bodyLower.includes(keyword)) { return { isAlive: false, responseMs, statusCode, error: `Body contiene "${keyword}"` } } } return { isAlive: true, responseMs, statusCode, error: null } } catch (err) { return { isAlive: false, responseMs: Date.now() - inicio, statusCode: null, error: err.message } } } function refreshInBackground(tmdbId, oldStreams, newScrapeResults, providerName, contentType) { setImmediate(async () => { try { const oldUrls = new Set(oldStreams.map(s => s.url)) const newUrls = new Set(newScrapeResults.map(s => s.url)) // 1. Logear streams nuevos if (newScrapeResults.length > 0) { const title = newScrapeResults[0]?.title || null await streamDb.logStreams(tmdbId, providerName, contentType, newScrapeResults, title) } // 2. Links que desaparecieron del scrape → validar const disappeared = oldStreams.filter(s => !newUrls.has(s.url)) for (const stream of disappeared) { const result = await validateUrl(stream.url) await streamDb.logCheck(stream.url, result) if (result.isAlive) { await streamDb.markAlive(stream.url, stream.provider) } else { await streamDb.markDead(stream.url, stream.provider) } } // 3. Links nuevos que no estaban → validar antes de confirmar const fresh = newScrapeResults.filter(s => !oldUrls.has(s.url)) for (const stream of fresh) { const result = await validateUrl(stream.url) await streamDb.logCheck(stream.url, result) if (!result.isAlive) { await streamDb.markDead(stream.url, providerName) } } } catch (err) { console.error(`[StreamValidator] Error en refresh para ${tmdbId}:`, err.message) } }) } module.exports = { validateUrl, refreshInBackground }