epg-grabber/src/utils.js

165 lines
4.7 KiB
JavaScript
Raw Normal View History

2021-03-13 13:11:33 +01:00
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 = {}
2021-03-13 14:17:50 +01:00
2021-03-13 13:11:33 +01:00
utils.loadConfig = function (file) {
if (!file) throw new Error('Path to [site].config.js is missing')
console.log(`Loading '${file}'...`)
2021-03-13 14:17:50 +01:00
const configPath = path.resolve(file)
2021-03-13 13:11:33 +01:00
const config = require(configPath)
2021-03-13 14:42:18 +01:00
if (!config.site) throw new Error("The required 'site' property is missing")
if (!config.channels) throw new Error("The required 'channels' property is missing")
if (!config.url) throw new Error("The required 'url' property is missing")
if (typeof config.url !== 'function')
throw new Error("The 'url' property should return the function")
if (!config.parser) throw new Error("The required 'parser' function is missing")
if (typeof config.parser !== 'function')
throw new Error("The 'parser' property should return the function")
2021-03-19 19:26:32 +01:00
if (config.logo && typeof config.logo !== 'function')
throw new Error("The 'logo' property should return the function")
2021-03-13 14:42:18 +01:00
2021-03-19 20:22:58 +01:00
config.channels = path.join(path.dirname(file), config.channels)
2021-03-13 13:11:33 +01:00
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',
2021-03-13 14:42:18 +01:00
delay: 3000,
output: 'guide.xml'
2021-03-13 13:11:33 +01:00
},
config
)
}
2021-03-19 20:22:58 +01:00
utils.parseChannels = function (filename) {
if (!filename) throw new Error('Path to [site].channels.xml is missing')
console.log(`Loading '${filename}'...`)
2021-03-13 13:11:33 +01:00
2021-03-19 20:22:58 +01:00
const xml = fs.readFileSync(path.resolve(filename), { encoding: 'utf-8' })
2021-03-13 13:11:33 +01:00
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, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&apos;')
.replace(/\n|\r/g, ' ')
.replace(/ +/g, ' ')
.trim()
}
utils.convertToXMLTV = function ({ config, channels, programs }) {
let output = `<?xml version="1.0" encoding="UTF-8" ?><tv>\r\n`
for (let channel of channels) {
const id = this.escapeString(channel['xmltv_id'])
const displayName = this.escapeString(channel.name)
2021-03-19 19:26:32 +01:00
output += `<channel id="${id}"><display-name>${displayName}</display-name>`
if (channel.logo) {
output += `<icon src="${channel.logo}" />`
}
output += `</channel>\r\n`
2021-03-13 13:11:33 +01:00
}
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 += `<programme start="${start}"`
if (stop) {
output += ` stop="${stop}"`
}
output += ` channel="${channel}"><title lang="${lang}">${title}</title>`
if (description) {
output += `<desc lang="${lang}">${description}</desc>`
}
if (category) {
output += `<category lang="${lang}">${category}</category>`
}
output += '</programme>\r\n'
}
}
output += '</tv>'
return output
}
2021-03-13 14:17:50 +01:00
utils.writeToFile = function (filename, data) {
const dir = path.resolve(path.dirname(filename))
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true })
2021-03-13 13:11:33 +01:00
}
2021-03-13 13:49:04 +01:00
fs.writeFileSync(path.resolve(filename), data)
2021-03-13 13:11:33 +01:00
}
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