epg-grabber 0.13.0 → 0.15.2

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/README.md CHANGED
@@ -56,6 +56,7 @@ module.exports = {
56
56
  <tv>
57
57
  <channel id="CNN.us">
58
58
  <display-name>CNN</display-name>
59
+ <url>https://example.com</url>
59
60
  </channel>
60
61
  <programme start="20211116040000 +0000" stop="20211116050000 +0000" channel="CNN.us">
61
62
  <title lang="en">News at 10PM</title>
@@ -78,6 +79,7 @@ Arguments:
78
79
  - `--lang`: set default language for all programs (default: 'en')
79
80
  - `--days`: number of days for which to grab the program (default: 1)
80
81
  - `--delay`: delay between requests (default: 3000)
82
+ - `--timeout`: set a timeout for each request (default: 5000)
81
83
  - `--debug`: enable debug mode (default: false)
82
84
  - `--log`: path to log file (optional)
83
85
  - `--log-level`: set the log level (default: 'info')
@@ -21,6 +21,7 @@ program
21
21
  .option('--lang <lang>', 'Set default language for all programs')
22
22
  .option('--days <days>', 'Number of days for which to grab the program', parseInteger, 1)
23
23
  .option('--delay <delay>', 'Delay between requests (in mileseconds)', parseInteger)
24
+ .option('--timeout <timeout>', 'Set a timeout for each request (in mileseconds)', parseInteger)
24
25
  .option('--debug', 'Enable debug mode', false)
25
26
  .option('--log <log>', 'Path to log file')
26
27
  .option('--log-level <level>', 'Set log level', 'info')
@@ -60,7 +61,15 @@ async function main() {
60
61
 
61
62
  logger.info(`Loading '${options.config}'...`)
62
63
  let config = require(path.resolve(options.config))
63
- config = merge(config, options)
64
+ config = merge(config, {
65
+ days: options.days,
66
+ debug: options.debug,
67
+ lang: options.lang,
68
+ delay: options.delay,
69
+ request: {
70
+ timeout: options.timeout
71
+ }
72
+ })
64
73
 
65
74
  if (options.channels) config.channels = options.channels
66
75
  else if (config.channels)
@@ -70,8 +79,7 @@ async function main() {
70
79
  if (!config.channels) return logger.error('Path to [site].channels.xml is missing')
71
80
  logger.info(`Loading '${config.channels}'...`)
72
81
  const channelsXML = fs.readFileSync(path.resolve(config.channels), { encoding: 'utf-8' })
73
- const parsed = utils.parseChannels(channelsXML)
74
- const channels = parsed.channels || []
82
+ const channels = utils.parseChannels(channelsXML)
75
83
 
76
84
  let programs = []
77
85
  let i = 1
@@ -96,7 +104,7 @@ async function main() {
96
104
  }
97
105
 
98
106
  const xml = utils.convertToXMLTV({ config, channels, programs })
99
- const outputPath = config.output || 'guide.xml'
107
+ const outputPath = options.output || config.output || 'guide.xml'
100
108
  utils.writeToFile(outputPath, xml)
101
109
 
102
110
  logger.info(`File '${outputPath}' successfully saved`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epg-grabber",
3
- "version": "0.13.0",
3
+ "version": "0.15.2",
4
4
  "description": "Node.js CLI tool for grabbing EPG from different sites",
5
5
  "main": "src/index.js",
6
6
  "preferGlobal": true,
package/src/utils.js CHANGED
@@ -59,11 +59,12 @@ utils.parseChannels = function (xml) {
59
59
  const channel = el.attributes
60
60
  if (!el.elements) throw new Error(`Channel '${channel.xmltv_id}' has no valid name`)
61
61
  channel.name = el.elements.find(el => el.type === 'text').text
62
+ channel.site = channel.site || site
62
63
 
63
64
  return channel
64
65
  })
65
66
 
66
- return { site, channels }
67
+ return channels
67
68
  }
68
69
 
69
70
  utils.sleep = function (ms) {
@@ -122,8 +123,8 @@ utils.convertToXMLTV = function ({ channels, programs }) {
122
123
  const title = utils.escapeString(program.title)
123
124
  const description = utils.escapeString(program.description)
124
125
  const categories = Array.isArray(program.category) ? program.category : [program.category]
125
- const start = program.start ? dayjs.utc(program.start).format('YYYYMMDDHHmmss ZZ') : ''
126
- const stop = program.stop ? dayjs.utc(program.stop).format('YYYYMMDDHHmmss ZZ') : ''
126
+ const start = program.start ? dayjs.unix(program.start).utc().format('YYYYMMDDHHmmss ZZ') : ''
127
+ const stop = program.stop ? dayjs.unix(program.stop).utc().format('YYYYMMDDHHmmss ZZ') : ''
127
128
  const lang = program.lang || 'en'
128
129
  const icon = utils.escapeString(program.icon)
129
130
 
@@ -243,7 +244,7 @@ utils.parseResponse = async (item, response, config) => {
243
244
  })
244
245
 
245
246
  if (!item.channel.logo && config.logo) {
246
- item.channel.logo = await utils.loadLogo(data, config)
247
+ data.channel.logo = await utils.loadLogo(data, config)
247
248
  }
248
249
 
249
250
  return await utils.parsePrograms(data, config)
@@ -264,9 +265,16 @@ utils.parsePrograms = async function (data, config) {
264
265
  return programs
265
266
  .filter(i => i)
266
267
  .map(program => {
267
- program.channel = channel.xmltv_id
268
- program.lang = program.lang || channel.lang || config.lang || 'en'
269
- return program
268
+ return {
269
+ title: program.title,
270
+ description: program.description || null,
271
+ category: program.category || null,
272
+ icon: program.icon || null,
273
+ channel: channel.xmltv_id,
274
+ lang: program.lang || channel.lang || config.lang || 'en',
275
+ start: program.start ? dayjs(program.start).unix() : null,
276
+ stop: program.stop ? dayjs(program.stop).unix() : null
277
+ }
270
278
  })
271
279
  }
272
280
 
package/tests/bin.test.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const { execSync } = require('child_process')
2
2
  const pwd = `${__dirname}/..`
3
+ import axios from 'axios'
4
+
5
+ jest.mock('axios')
3
6
 
4
7
  function stdoutResultTester(stdout) {
5
8
  return [`Finish`].every(val => {
@@ -19,6 +22,8 @@ it('can load config', () => {
19
22
  })
20
23
 
21
24
  it('can load mini config', () => {
25
+ axios.mockImplementation(() => Promise.resolve({ data: '' }))
26
+
22
27
  const result = execSync(
23
28
  `node ${pwd}/bin/epg-grabber.js \
24
29
  --config=tests/input/mini.config.js \
@@ -26,7 +31,8 @@ it('can load mini config', () => {
26
31
  --output=tests/output/mini.guide.xml \
27
32
  --lang=fr \
28
33
  --days=3 \
29
- --delay=0`,
34
+ --delay=0 \
35
+ --timeout=10000`,
30
36
  {
31
37
  encoding: 'utf8'
32
38
  }
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <site site="example.com">
3
3
  <channels>
4
- <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="1TV.com" site_id="1" lang="fr" logo="https://example.com/logos/1TV.png">1 TV</channel>
5
5
  <channel xmltv_id="2TV.com" site="example.com" site_id="2">2 TV</channel>
6
6
  </channels>
7
7
  </site>
@@ -28,9 +28,8 @@ it('can load valid config.js', () => {
28
28
 
29
29
  it('can parse valid channels.xml', () => {
30
30
  const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
31
- const parsed = utils.parseChannels(file)
32
- expect(parsed.site).toBe('example.com')
33
- expect(parsed.channels).toEqual([
31
+ const channels = utils.parseChannels(file)
32
+ expect(channels).toEqual([
34
33
  {
35
34
  name: '1 TV',
36
35
  xmltv_id: '1TV.com',
@@ -52,22 +51,20 @@ it('can parse valid channels.xml', () => {
52
51
 
53
52
  it('can convert object to xmltv string', () => {
54
53
  const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
55
- const parsed = utils.parseChannels(file)
56
- const channels = parsed.channels
54
+ const channels = utils.parseChannels(file)
57
55
  const programs = [
58
56
  {
59
57
  title: 'Program 1',
60
58
  description: 'Description for Program 1',
61
- start: '2021-03-19 06:00:00 +0000',
62
- stop: '2021-03-19 06:30:00 +0000',
59
+ start: 1616133600,
60
+ stop: 1616135400,
63
61
  category: 'Test',
64
62
  icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777',
65
63
  channel: '1TV.com',
66
64
  lang: 'it'
67
65
  }
68
66
  ]
69
- const config = { site: 'example.com' }
70
- const output = utils.convertToXMLTV({ config, channels, programs })
67
+ const output = utils.convertToXMLTV({ channels, programs })
71
68
  expect(output).toBe(
72
69
  '<?xml version="1.0" encoding="UTF-8" ?><tv>\r\n<channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>\r\n<channel id="2TV.com"><display-name>2 TV</display-name><url>https://example.com</url></channel>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="1TV.com"><title lang="it">Program 1</title><desc lang="it">Description for Program 1</desc><category lang="it">Test</category><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/></programme>\r\n</tv>'
73
70
  )
@@ -87,8 +84,8 @@ it('can convert object to xmltv string without categories', () => {
87
84
  const programs = [
88
85
  {
89
86
  title: 'Program 1',
90
- start: '2021-03-19 06:00:00 +0000',
91
- stop: '2021-03-19 06:30:00 +0000',
87
+ start: 1616133600,
88
+ stop: 1616135400,
92
89
  channel: '1TV.com',
93
90
  lang: 'it'
94
91
  }
@@ -102,22 +99,20 @@ it('can convert object to xmltv string without categories', () => {
102
99
 
103
100
  it('can convert object to xmltv string with multiple categories', () => {
104
101
  const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
105
- const parsed = utils.parseChannels(file)
106
- const channels = parsed.channels
102
+ const channels = utils.parseChannels(file)
107
103
  const programs = [
108
104
  {
109
105
  title: 'Program 1',
110
106
  description: 'Description for Program 1',
111
- start: '2021-03-19 06:00:00 +0000',
112
- stop: '2021-03-19 06:30:00 +0000',
107
+ start: 1616133600,
108
+ stop: 1616135400,
113
109
  category: ['Test1', 'Test2'],
114
110
  icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777',
115
111
  channel: '1TV.com',
116
112
  lang: 'it'
117
113
  }
118
114
  ]
119
- const config = { site: 'example.com' }
120
- const output = utils.convertToXMLTV({ config, channels, programs })
115
+ const output = utils.convertToXMLTV({ channels, programs })
121
116
  expect(output).toBe(
122
117
  '<?xml version="1.0" encoding="UTF-8" ?><tv>\r\n<channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>\r\n<channel id="2TV.com"><display-name>2 TV</display-name><url>https://example.com</url></channel>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="1TV.com"><title lang="it">Program 1</title><desc lang="it">Description for Program 1</desc><category lang="it">Test1</category><category lang="it">Test2</category><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/></programme>\r\n</tv>'
123
118
  )