epg-grabber 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/epg-grabber.js +70 -0
- package/package.json +7 -3
- package/src/index.js +29 -66
- package/src/utils.js +32 -51
- package/tests/bin.test.js +37 -0
- package/tests/index.test.js +39 -28
- package/tests/input/example.com.channels.xml +4 -6
- package/tests/input/mini.config.js +1 -1
- package/tests/utils.test.js +5 -6
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Command } = require('commander')
|
|
4
|
+
const program = new Command()
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const grabber = require('../src/index')
|
|
7
|
+
const utils = require('../src/utils')
|
|
8
|
+
const { name, version, description } = require('../package.json')
|
|
9
|
+
const merge = require('lodash.merge')
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name(name)
|
|
13
|
+
.version(version, '-v, --version')
|
|
14
|
+
.description(description)
|
|
15
|
+
.requiredOption('-c, --config <config>', 'Path to [site].config.js file')
|
|
16
|
+
.option('-o, --output <output>', 'Path to output file')
|
|
17
|
+
.option('--channels <channels>', 'Path to channels.xml file')
|
|
18
|
+
.option('--lang <lang>', 'Set default language for all programs')
|
|
19
|
+
.option('--days <days>', 'Number of days for which to grab the program', parseInteger)
|
|
20
|
+
.option('--delay <delay>', 'Delay between requests (in mileseconds)', parseInteger)
|
|
21
|
+
.option('--debug', 'Enable debug mode', false)
|
|
22
|
+
.parse(process.argv)
|
|
23
|
+
|
|
24
|
+
const options = program.opts()
|
|
25
|
+
|
|
26
|
+
async function main() {
|
|
27
|
+
console.log('\r\nStarting...')
|
|
28
|
+
|
|
29
|
+
console.log(`Loading '${options.config}'...`)
|
|
30
|
+
let config = require(path.resolve(options.config))
|
|
31
|
+
config = merge(config, options)
|
|
32
|
+
|
|
33
|
+
if (options.channels) config.channels = options.channels
|
|
34
|
+
else if (config.channels)
|
|
35
|
+
config.channels = path.join(path.dirname(options.config), config.channels)
|
|
36
|
+
else throw new Error("The required 'channels' property is missing")
|
|
37
|
+
|
|
38
|
+
console.log('Parsing:')
|
|
39
|
+
let programs = []
|
|
40
|
+
const channels = utils.parseChannels(config.channels)
|
|
41
|
+
for (let channel of channels) {
|
|
42
|
+
await grabber
|
|
43
|
+
.grab(channel, config, (data, err) => {
|
|
44
|
+
console.log(
|
|
45
|
+
` ${config.site} - ${data.channel.xmltv_id} - ${data.date.format('MMM D, YYYY')} (${
|
|
46
|
+
data.programs.length
|
|
47
|
+
} programs)`
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if (err) {
|
|
51
|
+
console.log(` Error: ${err.message}`)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.then(results => {
|
|
55
|
+
programs = programs.concat(results)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const xml = utils.convertToXMLTV({ config, channels, programs })
|
|
60
|
+
utils.writeToFile(config.output, xml)
|
|
61
|
+
|
|
62
|
+
console.log(`File '${config.output}' successfully saved`)
|
|
63
|
+
console.log('Finish')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
main()
|
|
67
|
+
|
|
68
|
+
function parseInteger(val) {
|
|
69
|
+
return val ? parseInt(val) : null
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epg-grabber",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Node.js CLI tool for grabbing EPG from different sites",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"preferGlobal": true,
|
|
7
7
|
"bin": {
|
|
8
|
-
"epg-grabber": "
|
|
8
|
+
"epg-grabber": "bin/epg-grabber.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"lint": "npx eslint ./src/**/*.js",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"axios": "^0.21.1",
|
|
32
32
|
"axios-cookiejar-support": "^1.0.1",
|
|
33
|
+
"axios-mock-adapter": "^1.20.0",
|
|
33
34
|
"commander": "^7.1.0",
|
|
34
35
|
"dayjs": "^1.10.4",
|
|
35
36
|
"glob": "^7.1.6",
|
|
@@ -43,6 +44,9 @@
|
|
|
43
44
|
"babel-jest": "^26.6.3",
|
|
44
45
|
"eslint": "^7.22.0",
|
|
45
46
|
"jest": "^26.6.3",
|
|
46
|
-
"jest-mock-axios": "^4.
|
|
47
|
+
"jest-mock-axios": "^4.4.1"
|
|
48
|
+
},
|
|
49
|
+
"jest": {
|
|
50
|
+
"testEnvironment": "node"
|
|
47
51
|
}
|
|
48
52
|
}
|
package/src/index.js
CHANGED
|
@@ -1,74 +1,37 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { Command } = require('commander')
|
|
4
|
-
const program = new Command()
|
|
5
1
|
const utils = require('./utils')
|
|
6
|
-
const { name, version, description } = require('../package.json')
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
.name(name)
|
|
10
|
-
.version(version, '-v, --version')
|
|
11
|
-
.description(description)
|
|
12
|
-
.option('-c, --config <config>', 'Path to [site].config.js file')
|
|
13
|
-
.option('-o, --output <output>', 'Path to output file', 'guide.xml')
|
|
14
|
-
.option('--channels <channels>', 'Path to channels.xml file')
|
|
15
|
-
.option('--lang <lang>', 'Set default language for all programs', 'en')
|
|
16
|
-
.option('--days <days>', 'Number of days for which to grab the program', 1)
|
|
17
|
-
.option('--delay <delay>', 'Delay between requests (in mileseconds)', 3000)
|
|
18
|
-
.option('--debug', 'Enable debug mode', false)
|
|
19
|
-
.parse(process.argv)
|
|
20
|
-
|
|
21
|
-
const options = program.opts()
|
|
22
|
-
const config = utils.loadConfig(options)
|
|
23
|
-
|
|
24
|
-
async function main() {
|
|
25
|
-
console.log('\r\nStarting...')
|
|
26
2
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
3
|
+
module.exports = {
|
|
4
|
+
grab: async function (channel, config, cb) {
|
|
5
|
+
config = utils.loadConfig(config)
|
|
6
|
+
channel.lang = channel.lang || config.lang || null
|
|
30
7
|
|
|
31
|
-
|
|
32
|
-
|
|
8
|
+
const utcDate = utils.getUTCDate()
|
|
9
|
+
const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
|
|
10
|
+
const queue = []
|
|
33
11
|
dates.forEach(date => {
|
|
34
12
|
queue.push({ date, channel })
|
|
35
13
|
})
|
|
36
|
-
})
|
|
37
14
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (options.debug) {
|
|
61
|
-
console.timeEnd(' Response Time')
|
|
62
|
-
console.timeEnd(' Parsing Time')
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const xml = utils.convertToXMLTV({ config, channels, programs })
|
|
68
|
-
utils.writeToFile(config.output, xml)
|
|
69
|
-
|
|
70
|
-
console.log(`File '${config.output}' successfully saved`)
|
|
71
|
-
console.log('Finish')
|
|
15
|
+
let programs = []
|
|
16
|
+
for (let item of queue) {
|
|
17
|
+
await utils
|
|
18
|
+
.buildRequest(item, config)
|
|
19
|
+
.then(request => utils.fetchData(request))
|
|
20
|
+
.then(response => utils.parseResponse(item, response, config))
|
|
21
|
+
.then(results => {
|
|
22
|
+
item.programs = results
|
|
23
|
+
cb(item, null)
|
|
24
|
+
programs = programs.concat(results)
|
|
25
|
+
})
|
|
26
|
+
.catch(err => {
|
|
27
|
+
item.programs = []
|
|
28
|
+
cb(item, err)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
await utils.sleep(config.delay)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return programs
|
|
35
|
+
},
|
|
36
|
+
convertToXMLTV: utils.convertToXMLTV
|
|
72
37
|
}
|
|
73
|
-
|
|
74
|
-
main()
|
package/src/utils.js
CHANGED
|
@@ -14,18 +14,7 @@ const utils = {}
|
|
|
14
14
|
const defaultUserAgent =
|
|
15
15
|
'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'
|
|
16
16
|
|
|
17
|
-
utils.loadConfig = function (
|
|
18
|
-
const file = options.config
|
|
19
|
-
if (!file) throw new Error('Path to [site].config.js is missing')
|
|
20
|
-
console.log(`Loading '${file}'...`)
|
|
21
|
-
|
|
22
|
-
const configPath = path.resolve(file)
|
|
23
|
-
const config = require(configPath)
|
|
24
|
-
|
|
25
|
-
if (options.channels) config.channels = options.channels
|
|
26
|
-
else if (config.channels) config.channels = path.join(path.dirname(file), config.channels)
|
|
27
|
-
else throw new Error("The required 'channels' property is missing")
|
|
28
|
-
|
|
17
|
+
utils.loadConfig = function (config) {
|
|
29
18
|
if (!config.site) throw new Error("The required 'site' property is missing")
|
|
30
19
|
if (!config.url) throw new Error("The required 'url' property is missing")
|
|
31
20
|
if (typeof config.url !== 'function' && typeof config.url !== 'string')
|
|
@@ -37,10 +26,10 @@ utils.loadConfig = function (options) {
|
|
|
37
26
|
throw new Error("The 'logo' property should return the function")
|
|
38
27
|
|
|
39
28
|
const defaultConfig = {
|
|
40
|
-
days:
|
|
41
|
-
lang:
|
|
42
|
-
delay:
|
|
43
|
-
output:
|
|
29
|
+
days: 1,
|
|
30
|
+
lang: 'en',
|
|
31
|
+
delay: 3000,
|
|
32
|
+
output: 'guide.xml',
|
|
44
33
|
request: {
|
|
45
34
|
method: 'GET',
|
|
46
35
|
maxContentLength: 5 * 1024 * 1024,
|
|
@@ -60,8 +49,7 @@ utils.parseChannels = function (filename) {
|
|
|
60
49
|
|
|
61
50
|
const xml = fs.readFileSync(path.resolve(filename), { encoding: 'utf-8' })
|
|
62
51
|
const result = convert.xml2js(xml)
|
|
63
|
-
const
|
|
64
|
-
const channels = site.elements.find(el => el.name === 'channels')
|
|
52
|
+
const channels = result.elements.find(el => el.name === 'channels')
|
|
65
53
|
|
|
66
54
|
return channels.elements
|
|
67
55
|
.filter(el => el.name === 'channel')
|
|
@@ -69,16 +57,13 @@ utils.parseChannels = function (filename) {
|
|
|
69
57
|
const channel = el.attributes
|
|
70
58
|
if (!el.elements) throw new Error(`Channel '${channel.xmltv_id}' has no valid name`)
|
|
71
59
|
channel.name = el.elements.find(el => el.type === 'text').text
|
|
72
|
-
channel.site = channel.site || site.attributes.site
|
|
73
60
|
|
|
74
61
|
return channel
|
|
75
62
|
})
|
|
76
63
|
}
|
|
77
64
|
|
|
78
65
|
utils.sleep = function (ms) {
|
|
79
|
-
return
|
|
80
|
-
return new Promise(resolve => setTimeout(() => resolve(x), ms))
|
|
81
|
-
}
|
|
66
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
82
67
|
}
|
|
83
68
|
|
|
84
69
|
utils.escapeString = function (string, defaultValue = '') {
|
|
@@ -109,18 +94,18 @@ utils.escapeString = function (string, defaultValue = '') {
|
|
|
109
94
|
.trim()
|
|
110
95
|
}
|
|
111
96
|
|
|
112
|
-
utils.convertToXMLTV = function ({
|
|
113
|
-
const url = config.site ? 'https://' + config.site : null
|
|
97
|
+
utils.convertToXMLTV = function ({ channels, programs }) {
|
|
114
98
|
let output = `<?xml version="1.0" encoding="UTF-8" ?><tv>\r\n`
|
|
115
99
|
for (let channel of channels) {
|
|
116
|
-
const id =
|
|
117
|
-
const displayName =
|
|
100
|
+
const id = utils.escapeString(channel['xmltv_id'])
|
|
101
|
+
const displayName = utils.escapeString(channel.name)
|
|
118
102
|
output += `<channel id="${id}"><display-name>${displayName}</display-name>`
|
|
119
103
|
if (channel.logo) {
|
|
120
|
-
const logo =
|
|
104
|
+
const logo = utils.escapeString(channel.logo)
|
|
121
105
|
output += `<icon src="${logo}"/>`
|
|
122
106
|
}
|
|
123
|
-
if (
|
|
107
|
+
if (channel.site) {
|
|
108
|
+
const url = channel.site ? 'https://' + channel.site : null
|
|
124
109
|
output += `<url>${url}</url>`
|
|
125
110
|
}
|
|
126
111
|
output += `</channel>\r\n`
|
|
@@ -129,14 +114,14 @@ utils.convertToXMLTV = function ({ config, channels, programs }) {
|
|
|
129
114
|
for (let program of programs) {
|
|
130
115
|
if (!program) continue
|
|
131
116
|
|
|
132
|
-
const channel =
|
|
133
|
-
const title =
|
|
134
|
-
const description =
|
|
135
|
-
const category =
|
|
117
|
+
const channel = utils.escapeString(program.channel)
|
|
118
|
+
const title = utils.escapeString(program.title)
|
|
119
|
+
const description = utils.escapeString(program.description)
|
|
120
|
+
const category = utils.escapeString(program.category)
|
|
136
121
|
const start = program.start ? dayjs.utc(program.start).format('YYYYMMDDHHmmss ZZ') : ''
|
|
137
122
|
const stop = program.stop ? dayjs.utc(program.stop).format('YYYYMMDDHHmmss ZZ') : ''
|
|
138
|
-
const lang = program.lang ||
|
|
139
|
-
const icon =
|
|
123
|
+
const lang = program.lang || 'en'
|
|
124
|
+
const icon = utils.escapeString(program.icon)
|
|
140
125
|
|
|
141
126
|
if (start && title) {
|
|
142
127
|
output += `<programme start="${start}"`
|
|
@@ -184,6 +169,10 @@ utils.buildRequest = async function (item, config) {
|
|
|
184
169
|
request.url = await utils.getRequestUrl(item, config)
|
|
185
170
|
request.data = await utils.getRequestData(item, config)
|
|
186
171
|
|
|
172
|
+
if (config.debug) {
|
|
173
|
+
console.log('Request:', JSON.stringify(request, null, 2))
|
|
174
|
+
}
|
|
175
|
+
|
|
187
176
|
return request
|
|
188
177
|
}
|
|
189
178
|
|
|
@@ -199,7 +188,7 @@ utils.getRequestHeaders = async function (item, config) {
|
|
|
199
188
|
}
|
|
200
189
|
return headers
|
|
201
190
|
}
|
|
202
|
-
return config.request.headers
|
|
191
|
+
return config.request.headers || null
|
|
203
192
|
}
|
|
204
193
|
|
|
205
194
|
utils.getRequestData = async function (item, config) {
|
|
@@ -210,7 +199,7 @@ utils.getRequestData = async function (item, config) {
|
|
|
210
199
|
}
|
|
211
200
|
return data
|
|
212
201
|
}
|
|
213
|
-
return config.request.data
|
|
202
|
+
return config.request.data || null
|
|
214
203
|
}
|
|
215
204
|
|
|
216
205
|
utils.getRequestUrl = async function (item, config) {
|
|
@@ -229,28 +218,20 @@ utils.getUTCDate = function () {
|
|
|
229
218
|
}
|
|
230
219
|
|
|
231
220
|
utils.parseResponse = async (item, response, config) => {
|
|
232
|
-
const
|
|
221
|
+
const data = merge(item, config, {
|
|
233
222
|
content: response.data.toString(),
|
|
234
223
|
buffer: response.data
|
|
235
224
|
})
|
|
236
225
|
|
|
237
226
|
if (!item.channel.logo && config.logo) {
|
|
238
|
-
item.channel.logo = await utils.loadLogo(
|
|
227
|
+
item.channel.logo = await utils.loadLogo(data, config)
|
|
239
228
|
}
|
|
240
229
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
console.log(
|
|
244
|
-
` ${config.site} - ${item.channel.xmltv_id} - ${item.date.format('MMM D, YYYY')} (${
|
|
245
|
-
parsed.length
|
|
246
|
-
} programs)`
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
return parsed
|
|
230
|
+
return await utils.parsePrograms(data, config)
|
|
250
231
|
}
|
|
251
232
|
|
|
252
|
-
utils.parsePrograms = async function (
|
|
253
|
-
let programs = config.parser(
|
|
233
|
+
utils.parsePrograms = async function (data, config) {
|
|
234
|
+
let programs = config.parser(data)
|
|
254
235
|
|
|
255
236
|
if (this.isPromise(programs)) {
|
|
256
237
|
programs = await programs
|
|
@@ -260,12 +241,12 @@ utils.parsePrograms = async function (options, config) {
|
|
|
260
241
|
throw new Error('Parser should return an array')
|
|
261
242
|
}
|
|
262
243
|
|
|
263
|
-
const channel =
|
|
244
|
+
const channel = data.channel
|
|
264
245
|
return programs
|
|
265
246
|
.filter(i => i)
|
|
266
247
|
.map(program => {
|
|
267
248
|
program.channel = channel.xmltv_id
|
|
268
|
-
program.lang = program.lang || channel.lang ||
|
|
249
|
+
program.lang = program.lang || channel.lang || config.lang || 'en'
|
|
269
250
|
return program
|
|
270
251
|
})
|
|
271
252
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const { execSync } = require('child_process')
|
|
2
|
+
const pwd = `${__dirname}/..`
|
|
3
|
+
|
|
4
|
+
function stdoutResultTester(stdout) {
|
|
5
|
+
return [`Finish`].every(val => {
|
|
6
|
+
return RegExp(val).test(stdout)
|
|
7
|
+
})
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
it('can load config', () => {
|
|
11
|
+
const result = execSync(
|
|
12
|
+
`node ${pwd}/bin/epg-grabber.js --config=tests/input/example.com.config.js`,
|
|
13
|
+
{
|
|
14
|
+
encoding: 'utf8'
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
expect(stdoutResultTester(result)).toBe(true)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('can load mini config', () => {
|
|
22
|
+
const result = execSync(
|
|
23
|
+
`node ${pwd}/bin/epg-grabber.js \
|
|
24
|
+
--config=tests/input/mini.config.js \
|
|
25
|
+
--channels=tests/input/example.com.channels.xml \
|
|
26
|
+
--output=tests/output/mini.guide.xml \
|
|
27
|
+
--lang=fr \
|
|
28
|
+
--days=3 \
|
|
29
|
+
--delay=5000`,
|
|
30
|
+
{
|
|
31
|
+
encoding: 'utf8'
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expect(stdoutResultTester(result)).toBe(true)
|
|
36
|
+
expect(result.includes("File 'tests/output/mini.guide.xml' successfully saved")).toBe(true)
|
|
37
|
+
})
|
package/tests/index.test.js
CHANGED
|
@@ -1,34 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment node
|
|
3
|
+
*/
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
import grabber from '../src/index'
|
|
6
|
+
import utils from '../src/utils'
|
|
7
|
+
import axios from 'axios'
|
|
8
|
+
import path from 'path'
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const result = execSync(`node ${pwd}/src/index.js --config=tests/input/example.com.config.js`, {
|
|
12
|
-
encoding: 'utf8'
|
|
13
|
-
})
|
|
10
|
+
jest.mock('axios')
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const result = execSync(
|
|
20
|
-
`node ${pwd}/src/index.js \
|
|
21
|
-
--config=tests/input/mini.config.js \
|
|
22
|
-
--channels=tests/input/example.com.channels.xml \
|
|
23
|
-
--output=tests/output/mini.guide.xml \
|
|
24
|
-
--lang=fr \
|
|
25
|
-
--days=3 \
|
|
26
|
-
--delay=5000`,
|
|
27
|
-
{
|
|
28
|
-
encoding: 'utf8'
|
|
12
|
+
it('can grab single channel programs', done => {
|
|
13
|
+
const data = {
|
|
14
|
+
data: {
|
|
15
|
+
toString: () => 'string'
|
|
29
16
|
}
|
|
30
|
-
|
|
17
|
+
}
|
|
18
|
+
axios.mockImplementation(() => Promise.resolve(data))
|
|
31
19
|
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
const config = utils.loadConfig(require(path.resolve('./tests/input/mini.config.js')))
|
|
21
|
+
const channel = {
|
|
22
|
+
site: 'example.com',
|
|
23
|
+
site_id: '1',
|
|
24
|
+
xmltv_id: '1TV.fr',
|
|
25
|
+
lang: 'fr',
|
|
26
|
+
name: '1TV'
|
|
27
|
+
}
|
|
28
|
+
grabber
|
|
29
|
+
.grab(channel, config, (data, err) => {
|
|
30
|
+
if (err) {
|
|
31
|
+
console.log(` Error: ${err.message}`)
|
|
32
|
+
done()
|
|
33
|
+
} else {
|
|
34
|
+
console.log(
|
|
35
|
+
` ${data.channel.site} - ${data.channel.xmltv_id} - ${data.date.format(
|
|
36
|
+
'MMM D, YYYY'
|
|
37
|
+
)} (${data.programs.length} programs)`
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
.then(programs => {
|
|
42
|
+
expect(programs.length).toBe(0)
|
|
43
|
+
done()
|
|
44
|
+
})
|
|
34
45
|
})
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
</channels>
|
|
7
|
-
</site>
|
|
2
|
+
<channels>
|
|
3
|
+
<channel xmltv_id="1TV.com" site="example.com" site_id="1" lang="fr" logo="https://example.com/logos/1TV.png">1 TV</channel>
|
|
4
|
+
<channel xmltv_id="2TV.com" site="example.com" site_id="2">2 TV</channel>
|
|
5
|
+
</channels>
|
package/tests/utils.test.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import mockAxios from 'jest-mock-axios'
|
|
2
2
|
import utils from '../src/utils'
|
|
3
|
+
import path from 'path'
|
|
3
4
|
|
|
4
5
|
it('can load valid config.js', () => {
|
|
5
|
-
const config = utils.loadConfig(
|
|
6
|
+
const config = utils.loadConfig(require(path.resolve('./tests/input/example.com.config.js')))
|
|
6
7
|
expect(config).toMatchObject({
|
|
7
|
-
channels: 'tests/input/example.com.channels.xml',
|
|
8
8
|
days: 1,
|
|
9
9
|
delay: 3000,
|
|
10
10
|
lang: 'en',
|
|
11
|
-
output: 'tests/output/guide.xml',
|
|
12
11
|
site: 'example.com'
|
|
13
12
|
})
|
|
14
13
|
expect(config.request).toMatchObject({
|
|
@@ -116,7 +115,7 @@ it('can fetch data', async () => {
|
|
|
116
115
|
})
|
|
117
116
|
|
|
118
117
|
it('can build request async', async () => {
|
|
119
|
-
const config = utils.loadConfig(
|
|
118
|
+
const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
|
|
120
119
|
return utils.buildRequest({}, config).then(request => {
|
|
121
120
|
expect(request).toMatchObject({
|
|
122
121
|
data: { accountID: '123' },
|
|
@@ -137,14 +136,14 @@ it('can build request async', async () => {
|
|
|
137
136
|
})
|
|
138
137
|
|
|
139
138
|
it('can load logo async', async () => {
|
|
140
|
-
const config = utils.loadConfig(
|
|
139
|
+
const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
|
|
141
140
|
return utils.loadLogo({}, config).then(logo => {
|
|
142
141
|
expect(logo).toBe('http://example.com/logos/1TV.png?x=шеллы&sid=777')
|
|
143
142
|
})
|
|
144
143
|
})
|
|
145
144
|
|
|
146
145
|
it('can parse programs async', async () => {
|
|
147
|
-
const config = utils.loadConfig(
|
|
146
|
+
const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
|
|
148
147
|
return utils
|
|
149
148
|
.parsePrograms({ channel: { xmltv_id: '1tv', lang: 'en' } }, config)
|
|
150
149
|
.then(programs => {
|