epg-grabber/bin/epg-grabber.js

135 lines
4.1 KiB
JavaScript
Raw Normal View History

2021-10-05 23:36:28 +02:00
#! /usr/bin/env node
const { Command } = require('commander')
const program = new Command()
2021-10-14 23:09:36 +02:00
const fs = require('fs')
2021-10-05 23:36:28 +02:00
const path = require('path')
const grabber = require('../src/index')
const utils = require('../src/utils')
const { name, version, description } = require('../package.json')
2022-01-19 13:54:42 +01:00
const { merge } = require('lodash')
2022-03-15 12:52:59 +01:00
const { gzip } = require('node-gzip')
2021-11-16 15:59:26 +01:00
const { createLogger, format, transports } = require('winston')
const { combine, timestamp, printf } = format
2021-10-05 23:36:28 +02:00
program
.name(name)
.version(version, '-v, --version')
.description(description)
2021-10-06 02:02:06 +02:00
.requiredOption('-c, --config <config>', 'Path to [site].config.js file')
2021-10-06 02:52:34 +02:00
.option('-o, --output <output>', 'Path to output file')
2021-10-05 23:36:28 +02:00
.option('--channels <channels>', 'Path to channels.xml file')
2021-10-06 02:52:34 +02:00
.option('--lang <lang>', 'Set default language for all programs')
2021-11-16 15:59:26 +01:00
.option('--days <days>', 'Number of days for which to grab the program', parseInteger, 1)
2021-10-06 02:52:34 +02:00
.option('--delay <delay>', 'Delay between requests (in mileseconds)', parseInteger)
2021-11-18 15:31:47 +01:00
.option('--timeout <timeout>', 'Set a timeout for each request (in mileseconds)', parseInteger)
2022-03-15 12:52:59 +01:00
.option('--gzip', 'Compress the output', false)
2021-10-05 23:36:28 +02:00
.option('--debug', 'Enable debug mode', false)
2022-03-06 14:18:05 +01:00
.option('--curl', 'Display request as CURL', false)
2021-11-16 15:59:26 +01:00
.option('--log <log>', 'Path to log file')
.option('--log-level <level>', 'Set log level', 'info')
2021-10-05 23:36:28 +02:00
.parse(process.argv)
const options = program.opts()
2021-11-16 15:59:26 +01:00
const fileFormat = printf(({ level, message, timestamp }) => {
return `[${timestamp}] ${level.toUpperCase()}: ${message}`
})
const consoleFormat = printf(({ level, message, timestamp }) => {
if (level === 'error') return ` Error: ${message}`
return message
})
const t = [new transports.Console({ format: consoleFormat })]
if (options.log) {
t.push(
new transports.File({
filename: path.resolve(options.log),
format: combine(timestamp(), fileFormat),
options: { flags: 'w' }
})
)
}
const logger = createLogger({
level: options.logLevel,
transports: t
})
2021-10-05 23:36:28 +02:00
async function main() {
2021-11-16 15:59:26 +01:00
logger.info('Starting...')
2021-10-05 23:36:28 +02:00
2021-11-16 15:59:26 +01:00
logger.info(`Loading '${options.config}'...`)
2021-10-06 02:43:10 +02:00
let config = require(path.resolve(options.config))
2021-11-18 15:31:47 +01:00
config = merge(config, {
days: options.days,
debug: options.debug,
2022-03-15 12:52:59 +01:00
gzip: options.gzip,
2022-03-06 14:18:05 +01:00
curl: options.curl,
2021-11-18 15:31:47 +01:00
lang: options.lang,
delay: options.delay,
request: {
timeout: options.timeout
}
})
2021-10-06 02:02:06 +02:00
2021-10-05 23:36:28 +02:00
if (options.channels) config.channels = options.channels
else if (config.channels)
config.channels = path.join(path.dirname(options.config), config.channels)
else throw new Error("The required 'channels' property is missing")
2021-11-16 15:59:26 +01:00
if (!config.channels) return logger.error('Path to [site].channels.xml is missing')
logger.info(`Loading '${config.channels}'...`)
2021-10-14 23:09:36 +02:00
const channelsXML = fs.readFileSync(path.resolve(config.channels), { encoding: 'utf-8' })
2022-01-25 15:51:23 +01:00
const { channels } = utils.parseChannels(channelsXML)
2021-10-14 23:09:36 +02:00
2021-10-05 23:36:28 +02:00
let programs = []
2021-11-16 15:59:26 +01:00
let i = 1
let days = options.days || 1
const total = channels.length * days
2022-01-31 03:48:01 +01:00
const utcDate = utils.getUTCDate()
const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
2021-10-05 23:36:28 +02:00
for (let channel of channels) {
2022-01-31 03:48:01 +01:00
for (let date of dates) {
await grabber
.grab(channel, date, config, (data, err) => {
logger.info(
`[${i}/${total}] ${config.site} - ${data.channel.xmltv_id} - ${data.date.format(
'MMM D, YYYY'
)} (${data.programs.length} programs)`
)
if (err) logger.error(err.message)
if (i < total) i++
})
.then(results => {
programs = programs.concat(results)
})
}
2021-10-05 23:36:28 +02:00
}
const xml = utils.convertToXMLTV({ config, channels, programs })
2022-03-15 12:52:59 +01:00
let outputPath = options.output || config.output
if (options.gzip) {
outputPath = outputPath || 'guide.xml.gz'
const compressed = await gzip(xml)
utils.writeToFile(outputPath, compressed)
} else {
outputPath = outputPath || 'guide.xml'
utils.writeToFile(outputPath, xml)
}
2021-10-05 23:36:28 +02:00
2021-11-16 15:59:26 +01:00
logger.info(`File '${outputPath}' successfully saved`)
logger.info('Finish')
2021-10-05 23:36:28 +02:00
}
main()
2021-10-06 02:43:10 +02:00
function parseInteger(val) {
return val ? parseInt(val) : null
}