const fs = require('fs') const path = require('path') const axios = require('axios') const axiosCookieJarSupport = require('axios-cookiejar-support').default const tough = require('tough-cookie') const convert = require('xml-js') const dayjs = require('dayjs') const utc = require('dayjs/plugin/utc') dayjs.extend(utc) axiosCookieJarSupport(axios) const utils = {} utils.loadConfig = function (file) { if (!file) throw new Error('Path to [site].config.js is missing') console.log(`Loading '${file}'...`) const configPath = path.resolve(process.cwd(), file) const config = require(configPath) const channelsPath = path.resolve(this.getDirectory(configPath), `${config.site}.channels.xml`) return Object.assign( {}, { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71', days: 1, cookie: '', lang: 'en', channels: channelsPath, delay: 3000 }, config ) } utils.parseChannels = function (file) { if (!file) throw new Error('Path to [site].channels.xml is missing') console.log(`Loading '${file}'...`) const xml = fs.readFileSync(path.resolve(__dirname, file), { encoding: 'utf-8' }) const result = convert.xml2js(xml) const site = result.elements.find(el => el.name === 'site') const channels = site.elements.find(el => el.name === 'channels') return channels.elements .filter(el => el.name === 'channel') .map(el => { const channel = el.attributes channel.name = el.elements.find(el => el.type === 'text').text channel.site = channel.site || site.attributes.site return channel }) } utils.sleep = function (ms) { return function (x) { return new Promise(resolve => setTimeout(() => resolve(x), ms)) } } utils.escapeString = function (string, defaultValue = '') { if (!string) return defaultValue return string .toString() .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, ''') .replace(/\n|\r/g, ' ') .replace(/ +/g, ' ') .trim() } utils.convertToXMLTV = function ({ config, channels, programs }) { let output = `\r\n` for (let channel of channels) { const id = this.escapeString(channel['xmltv_id']) const displayName = this.escapeString(channel.name) output += `${displayName}\r\n` } for (let program of programs) { if (!program) continue const channel = this.escapeString(program.channel) const title = this.escapeString(program.title) const description = this.escapeString(program.description) const category = this.escapeString(program.category) const start = program.start ? dayjs.utc(program.start).format('YYYYMMDDHHmmss ZZ') : '' const stop = program.stop ? dayjs.utc(program.stop).format('YYYYMMDDHHmmss ZZ') : '' const lang = program.lang || config.lang if (start && title) { output += `${title}` if (description) { output += `${description}` } if (category) { output += `${category}` } output += '\r\n' } } output += '' return output } utils.getDirectory = function (file) { return path.dirname(file) } utils.createDir = function (dir) { if (!fs.existsSync(path.resolve(dir))) { fs.mkdirSync(path.resolve(dir)) } } utils.writeToFile = function (filename, data) { fs.writeFileSync(path.resolve(filename), data) } utils.createHttpClient = function (config) { return axios.create({ headers: { 'User-Agent': config.userAgent, Cookie: config.cookie }, withCredentials: true, jar: new tough.CookieJar() }) } utils.getUTCDate = function () { return dayjs.utc() } module.exports = utils