Files
epg/scripts/commands/workers/load.ts
2026-05-04 18:01:51 +03:00

123 lines
3.7 KiB
TypeScript

import epgGrabber, { EPGGrabber } from 'epg-grabber'
import { DATA_DIR, ROOT_DIR } from '../../constants'
import AxiosMockAdapter from 'axios-mock-adapter'
import { Storage } from '@freearhey/storage-js'
import { Channel, Worker } from '../../models'
import { Collection } from '@freearhey/core'
import { Logger } from '@freearhey/core'
import epgParser from 'epg-parser'
import axios from 'axios'
import path from 'path'
async function main() {
const logger = new Logger({ level: process.env.NODE_ENV === 'test' ? -999 : 3 })
const rootStorage = new Storage(ROOT_DIR)
const workers = new Map<string, Worker>()
logger.info('loading workers.txt...')
const workersTxt = await rootStorage.load('workers.txt')
const hosts = workersTxt.split('\r\n')
hosts.forEach((host: string) => {
if (!host) return
const worker = new Worker({ host })
workers.set(host, worker)
})
for (const worker of workers.values()) {
logger.info(`processing "${worker.host}"...`)
const client = axios.create({
baseURL: worker.getBaseUrl(),
timeout: 60000
})
if (process.env.NODE_ENV === 'test') {
const mock = new AxiosMockAdapter(client)
if (worker.host === 'example.com') {
mock.onGet('worker.json').reply(404)
} else {
const testStorage = new Storage('tests/__data__/input/workers_load')
mock.onGet('worker.json').reply(200, await testStorage.load('worker.json'))
mock.onGet('channels.xml').reply(200, await testStorage.load('channels.xml'))
mock.onGet('guide.xml').reply(200, await testStorage.load('guide.xml'))
}
}
const workerConfig = await client
.get('worker.json')
.then(res => res.data)
.catch(err => {
worker.setStatus(err.status)
logger.error(err.message)
})
if (!workerConfig) {
worker.setStatus('MISSING_WORKER_CONFIG')
logger.error('Unable to load "workers.json"')
continue
}
worker
.setChannelsPath(workerConfig.channels)
.setGuideXmlPath(
typeof workerConfig.guide === 'string' ? workerConfig.guide : workerConfig?.guide?.xml
)
.setGuideGzipPath(workerConfig?.guide?.gzip)
.setGuideJsonPath(workerConfig?.guide?.json)
if (!worker.channelsPath) {
worker.setStatus('MISSING_CHANNELS_PATH')
logger.error('The "channels" property is missing from the workers config')
continue
}
if (!worker.guideXmlPath) {
worker.setStatus('MISSING_GUIDE_XML_PATH')
logger.error('The "guide" property is missing from the workers config')
continue
}
const channelsXml = await client
.get(worker.channelsPath)
.then(res => res.data)
.catch(err => {
worker.status = err.status
logger.error(err.message)
})
if (!channelsXml) continue
const parsedChannels = EPGGrabber.parseChannelsXML(channelsXml)
worker.channels = new Collection(parsedChannels).map(
(channel: epgGrabber.Channel) => new Channel(channel.toObject())
)
const guideXml = await client
.get(worker.guideXmlPath)
.then(res => res.data)
.catch(err => {
worker.setStatus(err.status)
logger.error(err.message)
})
if (!guideXml) continue
const parsedGuide = epgParser.parse(guideXml)
worker.lastUpdated = parsedGuide.date
worker.setStatus('OK')
}
const output = [...workers.values()]
const dataStorage = new Storage(DATA_DIR)
const outputFilename = 'workers.json'
await dataStorage.save(outputFilename, JSON.stringify(output))
logger.info(`saved to "${path.join(DATA_DIR, outputFilename)}"`)
}
main()