const { file, parser, logger, checker, m3u } = require('../../core') const { program } = require('commander') program .argument('[filepath]', 'Path to file to validate') .option('-t, --timeout ', 'Set timeout for each request', parser.parseNumber, 60000) .option('-d, --delay ', 'Set delay for each request', parser.parseNumber, 0) .option('--debug', 'Enable debug mode') .parse(process.argv) const options = program.opts() async function main() { const files = program.args.length ? program.args : await file.list('streams/*.m3u') for (const filepath of files) { if (!filepath.endsWith('.m3u')) continue logger.info(`${filepath}`) const playlist = await parser.parsePlaylist(filepath) const before = playlist.items.length for (const stream of playlist.items) { if (options.debug) logger.info(stream.url) const [_, status] = stream.raw.match(/status="([a-z]+)"/) || [null, null] stream.status = status if (status === 'error' && /^(http|https)/.test(stream.url)) { const result = await checkStream(stream) const newStatus = parseStatus(result.error) if (status === newStatus) { stream.remove = true logger.info(`removed "${stream.name}"`) } } } const items = playlist.items .filter(i => !i.remove) .map(item => ({ attrs: { 'tvg-id': item.tvg.id, status: item.status, 'user-agent': item.http['user-agent'] || undefined }, title: item.name, url: item.url, vlcOpts: { 'http-referrer': item.http.referrer || undefined, 'http-user-agent': item.http['user-agent'] || undefined } })) if (before !== items.length) { const output = m3u.create(items) await file.create(filepath, output) logger.info(`saved`) } } } main() async function checkStream(item) { const config = { timeout: options.timeout, delay: options.delay, debug: options.debug } const request = { url: item.url, http: { referrer: item.http.referrer, 'user-agent': item.http['user-agent'] } } return checker.check(request, config) } function parseStatus(error) { if (!error) return 'online' switch (error) { case 'Operation timed out': return 'timeout' case 'Server returned 403 Forbidden (access denied)': return 'blocked' default: return 'error' } }