mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 00:50:09 -04:00
Update grab.js
This commit is contained in:
parent
d5a88f04d4
commit
3a4f59721a
1 changed files with 66 additions and 32 deletions
|
@ -5,57 +5,90 @@ const { db, logger, date, timer, file, parser, api, zip } = require('../../core'
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const dayjs = require('dayjs')
|
const dayjs = require('dayjs')
|
||||||
const utc = require('dayjs/plugin/utc')
|
const utc = require('dayjs/plugin/utc')
|
||||||
|
const CronJob = require('cron').CronJob
|
||||||
|
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
|
|
||||||
|
const BASE_DIR = process.env.BASE_DIR || '.'
|
||||||
|
const CURR_DATE = process.env.CURR_DATE || new Date()
|
||||||
|
|
||||||
program
|
program
|
||||||
.requiredOption('-s, --site <name>', 'Name of the site to parse')
|
.requiredOption('-s, --site <name>', 'Name of the site to parse')
|
||||||
.option('-l, --lang <code>', 'Filter channels by language (ISO 639-2 code)')
|
.option('-l, --lang <code>', 'Filter channels by language (ISO 639-2 code)')
|
||||||
.option('-o, --output <path>', 'Path to output file')
|
.option('-o, --output <path>', 'Path to output file')
|
||||||
|
.option('--cron <expression>', 'Schedule a script run')
|
||||||
.option('--gzip', 'Create a compressed version of the guide as well', false)
|
.option('--gzip', 'Create a compressed version of the guide as well', false)
|
||||||
.parse(process.argv)
|
.parse(process.argv)
|
||||||
|
|
||||||
const options = program.opts()
|
const options = program.opts()
|
||||||
const BASE_DIR = process.env.BASE_DIR || '.'
|
|
||||||
const CURR_DATE = process.env.CURR_DATE || new Date()
|
|
||||||
|
|
||||||
|
options.output = options.output || file.resolve(`${BASE_DIR}/guides/{lang}/{site}.xml`)
|
||||||
options.config = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}.config.js`)
|
options.config = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}.config.js`)
|
||||||
options.channels = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}*.channels.xml`)
|
options.channels = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}*.channels.xml`)
|
||||||
|
|
||||||
let channels = []
|
let channels = []
|
||||||
let programs = []
|
let programs = []
|
||||||
|
let runIndex = 0
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
logger.info('starting...')
|
logger.start('staring...')
|
||||||
timer.start()
|
|
||||||
|
|
||||||
let config = await loadConfig(options.config)
|
logger.info('settings:')
|
||||||
let queue = await createQueue(options.channels, config)
|
for (let prop in options) {
|
||||||
|
logger.info(` ${prop}: ${options[prop]}`)
|
||||||
|
}
|
||||||
|
|
||||||
await grab(queue, config)
|
const config = await loadConfig(options.config)
|
||||||
|
const queue = await createQueue(options.channels, config)
|
||||||
|
const outputPath = options.output
|
||||||
|
|
||||||
let outputPath = options.output || file.resolve(`${BASE_DIR}/guides/{lang}/{site}.xml`)
|
if (options.cron) {
|
||||||
|
const job = new CronJob(options.cron, function () {
|
||||||
await save(outputPath, channels, programs)
|
runJob(config, queue, outputPath)
|
||||||
|
})
|
||||||
logger.info(`done in ${timer.format('HH[h] mm[m] ss[s]')}`)
|
job.start()
|
||||||
|
} else {
|
||||||
|
await runJob(config, queue, outputPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadConfig(configPath) {
|
async function loadConfig(configPath) {
|
||||||
logger.info(`loading "${configPath}"...`)
|
|
||||||
|
|
||||||
let config = require(file.resolve(configPath))
|
let config = require(file.resolve(configPath))
|
||||||
config = _.merge(config, {
|
config = _.merge(config, {})
|
||||||
debug: options.debug,
|
config.days = config.days || 1
|
||||||
delay: options.delay,
|
|
||||||
request: {
|
logger.info('config:')
|
||||||
timeout: options.timeout
|
logConfig(config)
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function logConfig(config, level = 1) {
|
||||||
|
let padLeft = ' '.repeat(level)
|
||||||
|
for (let prop in config) {
|
||||||
|
if (typeof config[prop] === 'string' || typeof config[prop] === 'number') {
|
||||||
|
logger.info(`${padLeft}${prop}: ${config[prop]}`)
|
||||||
|
} else if (typeof config[prop] === 'object') {
|
||||||
|
level++
|
||||||
|
logger.info(`${padLeft}${prop}:`)
|
||||||
|
logConfig(config[prop], level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runJob(config, queue, outputPath) {
|
||||||
|
runIndex++
|
||||||
|
logger.info(`run #${runIndex}:`)
|
||||||
|
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
await grab(queue, config)
|
||||||
|
|
||||||
|
await save(outputPath, channels, programs)
|
||||||
|
|
||||||
|
logger.success(` done in ${timer.format('HH[h] mm[m] ss[s]')}`)
|
||||||
|
}
|
||||||
|
|
||||||
async function grab(queue, config) {
|
async function grab(queue, config) {
|
||||||
const grabber = new EPGGrabber(config)
|
const grabber = new EPGGrabber(config)
|
||||||
const total = queue.length
|
const total = queue.length
|
||||||
|
@ -75,7 +108,7 @@ async function grab(queue, config) {
|
||||||
if (i < total) i++
|
if (i < total) i++
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(` Error: ${err.message}`)
|
logger.info(` ERR: ${err.message}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(results => {
|
.then(results => {
|
||||||
|
@ -85,10 +118,10 @@ async function grab(queue, config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createQueue(channelsPath, config) {
|
async function createQueue(channelsPath, config) {
|
||||||
|
logger.info('creating queue...')
|
||||||
let queue = {}
|
let queue = {}
|
||||||
|
await api.channels.load().catch(logger.error)
|
||||||
await api.channels.load().catch(console.error)
|
const files = await file.list(channelsPath).catch(logger.error)
|
||||||
const files = await file.list(channelsPath).catch(console.error)
|
|
||||||
const utcDate = date.getUTC(CURR_DATE)
|
const utcDate = date.getUTC(CURR_DATE)
|
||||||
for (const filepath of files) {
|
for (const filepath of files) {
|
||||||
logger.info(` loading "${filepath}"...`)
|
logger.info(` loading "${filepath}"...`)
|
||||||
|
@ -96,8 +129,7 @@ async function createQueue(channelsPath, config) {
|
||||||
const dir = file.dirname(filepath)
|
const dir = file.dirname(filepath)
|
||||||
const { channels } = await parser.parseChannels(filepath)
|
const { channels } = await parser.parseChannels(filepath)
|
||||||
const filename = file.basename(filepath)
|
const filename = file.basename(filepath)
|
||||||
const days = config.days || 1
|
const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
|
||||||
const dates = Array.from({ length: days }, (_, i) => utcDate.add(i, 'd'))
|
|
||||||
for (const channel of channels) {
|
for (const channel of channels) {
|
||||||
if (!channel.site || !channel.xmltv_id) continue
|
if (!channel.site || !channel.xmltv_id) continue
|
||||||
if (options.lang && channel.lang !== options.lang) continue
|
if (options.lang && channel.lang !== options.lang) continue
|
||||||
|
@ -119,13 +151,15 @@ async function createQueue(channelsPath, config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
logger.error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queue = Object.values(queue)
|
queue = Object.values(queue)
|
||||||
|
|
||||||
|
logger.info(` added ${queue.length} items`)
|
||||||
|
|
||||||
return queue
|
return queue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,14 +203,14 @@ async function save(template, parsedChannels, programs = []) {
|
||||||
const outputPath = file.templateFormat(template, output.channels[0])
|
const outputPath = file.templateFormat(template, output.channels[0])
|
||||||
const xmlFilepath = outputPath
|
const xmlFilepath = outputPath
|
||||||
const xmltv = generateXMLTV(output)
|
const xmltv = generateXMLTV(output)
|
||||||
|
logger.info(` saving to "${xmlFilepath}"...`)
|
||||||
await file.create(xmlFilepath, xmltv)
|
await file.create(xmlFilepath, xmltv)
|
||||||
logger.info(`file "${xmlFilepath}" saved`)
|
|
||||||
|
|
||||||
if (options.gzip) {
|
if (options.gzip) {
|
||||||
const gzFilepath = `${outputPath}.gz`
|
const gzFilepath = `${outputPath}.gz`
|
||||||
const compressed = await zip.compress(xmltv)
|
const compressed = await zip.compress(xmltv)
|
||||||
|
logger.info(` saving to "${gzFilepath}"...`)
|
||||||
await file.create(gzFilepath, compressed)
|
await file.create(gzFilepath, compressed)
|
||||||
logger.info(`file "${gzFilepath}" saved`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue