epg-grabber 0.17.0 → 0.20.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/README.md CHANGED
@@ -94,7 +94,6 @@ module.exports = {
94
94
  lang: 'fr', // default language for all programs (default: 'en')
95
95
  days: 3, // number of days for which to grab the program (default: 1)
96
96
  delay: 5000, // delay between requests (default: 3000)
97
- ignore: true, // skip all channels during request (default: false)
98
97
 
99
98
  request: { // request options (details: https://github.com/axios/axios#request-config)
100
99
 
@@ -79,28 +79,32 @@ async function main() {
79
79
  if (!config.channels) return logger.error('Path to [site].channels.xml is missing')
80
80
  logger.info(`Loading '${config.channels}'...`)
81
81
  const channelsXML = fs.readFileSync(path.resolve(config.channels), { encoding: 'utf-8' })
82
- const channels = utils.parseChannels(channelsXML)
82
+ const { channels } = utils.parseChannels(channelsXML)
83
83
 
84
84
  let programs = []
85
85
  let i = 1
86
86
  let days = options.days || 1
87
87
  const total = channels.length * days
88
+ const utcDate = utils.getUTCDate()
89
+ const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
88
90
  for (let channel of channels) {
89
- await grabber
90
- .grab(channel, config, (data, err) => {
91
- logger.info(
92
- `[${i}/${total}] ${config.site} - ${data.channel.xmltv_id} - ${data.date.format(
93
- 'MMM D, YYYY'
94
- )} (${data.programs.length} programs)`
95
- )
96
-
97
- if (err) logger.error(err.message)
98
-
99
- if (i < total) i++
100
- })
101
- .then(results => {
102
- programs = programs.concat(results)
103
- })
91
+ for (let date of dates) {
92
+ await grabber
93
+ .grab(channel, date, config, (data, err) => {
94
+ logger.info(
95
+ `[${i}/${total}] ${config.site} - ${data.channel.xmltv_id} - ${data.date.format(
96
+ 'MMM D, YYYY'
97
+ )} (${data.programs.length} programs)`
98
+ )
99
+
100
+ if (err) logger.error(err.message)
101
+
102
+ if (i < total) i++
103
+ })
104
+ .then(results => {
105
+ programs = programs.concat(results)
106
+ })
107
+ }
104
108
  }
105
109
 
106
110
  const xml = utils.convertToXMLTV({ config, channels, programs })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epg-grabber",
3
- "version": "0.17.0",
3
+ "version": "0.20.0",
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/index.js CHANGED
@@ -1,41 +1,29 @@
1
1
  const utils = require('./utils')
2
2
 
3
3
  module.exports = {
4
- grab: async function (channel, config, cb) {
4
+ grab: async function (channel, date, config, cb) {
5
+ date = typeof date === 'string' ? utils.getUTCDate(date) : date
5
6
  config = utils.loadConfig(config)
6
7
  channel.lang = channel.lang || config.lang || null
7
8
 
8
- const utcDate = utils.getUTCDate()
9
- const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
10
- const queue = []
11
- dates.forEach(date => {
12
- queue.push({ date, channel })
13
- })
14
-
15
9
  let programs = []
16
- for (let item of queue) {
17
- if (config.ignore) {
18
- item.programs = []
19
- cb(item, new Error('Skipped'))
20
- continue
21
- }
22
10
 
23
- await utils
24
- .buildRequest(item, config)
25
- .then(request => utils.fetchData(request))
26
- .then(response => utils.parseResponse(item, response, config))
27
- .then(results => {
28
- item.programs = results
29
- cb(item, null)
30
- programs = programs.concat(results)
31
- })
32
- .catch(err => {
33
- item.programs = []
34
- cb(item, err)
35
- })
11
+ const item = { date, channel }
12
+ await utils
13
+ .buildRequest(item, config)
14
+ .then(request => utils.fetchData(request))
15
+ .then(response => utils.parseResponse(item, response, config))
16
+ .then(results => {
17
+ item.programs = results
18
+ cb(item, null)
19
+ programs = programs.concat(results)
20
+ })
21
+ .catch(err => {
22
+ item.programs = []
23
+ cb(item, err)
24
+ })
36
25
 
37
- await utils.sleep(config.delay)
38
- }
26
+ await utils.sleep(config.delay)
39
27
 
40
28
  return programs
41
29
  },
package/src/utils.js CHANGED
@@ -65,7 +65,7 @@ utils.parseChannels = function (xml) {
65
65
  return channel
66
66
  })
67
67
 
68
- return channels
68
+ return { site, channels }
69
69
  }
70
70
 
71
71
  utils.sleep = function (ms) {
@@ -259,7 +259,9 @@ utils.getRequestUrl = async function (item, config) {
259
259
  return config.url
260
260
  }
261
261
 
262
- utils.getUTCDate = function () {
262
+ utils.getUTCDate = function (d = null) {
263
+ if (typeof d === 'string') return dayjs.utc(d).startOf('d')
264
+
263
265
  return dayjs.utc().startOf('d')
264
266
  }
265
267
 
@@ -295,6 +297,8 @@ utils.parsePrograms = async function (data, config) {
295
297
  title: program.title,
296
298
  description: program.description || null,
297
299
  category: program.category || null,
300
+ season: program.season || null,
301
+ episode: program.episode || null,
298
302
  icon: program.icon || null,
299
303
  channel: channel.xmltv_id,
300
304
  lang: program.lang || channel.lang || config.lang || 'en',
@@ -27,7 +27,7 @@ it('return "Connection timeout" error if server does not response', done => {
27
27
  lang: 'en',
28
28
  name: 'CNN'
29
29
  }
30
- grabber.grab(channel, config, (data, err) => {
30
+ grabber.grab(channel, '2022-01-01', config, (data, err) => {
31
31
  expect(err.message).toBe('Connection timeout')
32
32
  done()
33
33
  })
@@ -54,7 +54,7 @@ it('can grab single channel programs', done => {
54
54
  name: '1TV'
55
55
  }
56
56
  grabber
57
- .grab(channel, config, (data, err) => {
57
+ .grab(channel, '2022-01-01', config, (data, err) => {
58
58
  if (err) {
59
59
  console.log(` Error: ${err.message}`)
60
60
  done()
@@ -71,23 +71,3 @@ it('can grab single channel programs', done => {
71
71
  done()
72
72
  })
73
73
  })
74
-
75
- it('return "Skipped" error if ignore option in config is true', done => {
76
- const config = {
77
- site: 'example.com',
78
- ignore: true,
79
- url: `http://example.com/20210319/1tv.json`,
80
- parser: () => []
81
- }
82
- const channel = {
83
- site: 'example.com',
84
- site_id: 'cnn',
85
- xmltv_id: 'CNN.us',
86
- lang: 'en',
87
- name: 'CNN'
88
- }
89
- grabber.grab(channel, config, (data, err) => {
90
- expect(err.message).toBe('Skipped')
91
- done()
92
- })
93
- })
@@ -1,6 +1,10 @@
1
+ const dayjs = require('dayjs')
2
+ const utc = require('dayjs/plugin/utc')
3
+
4
+ dayjs.extend(utc)
5
+
1
6
  module.exports = {
2
7
  site: 'example.com',
3
- ignore: true,
4
8
  channels: 'example.com.channels.xml',
5
9
  output: 'tests/output/guide.xml',
6
10
  url: () => 'http://example.com/20210319/1tv.json',
@@ -14,6 +18,20 @@ module.exports = {
14
18
  return { accountID: '123' }
15
19
  }
16
20
  },
17
- parser: () => [],
21
+ parser: () => {
22
+ return [
23
+ {
24
+ title: 'Title',
25
+ description: 'Description',
26
+ lang: 'en',
27
+ category: ['Category1', 'Category2'],
28
+ icon: 'https://example.com/image.jpg',
29
+ season: 9,
30
+ episode: 238,
31
+ start: dayjs.utc('2022-01-01 00:00:00'),
32
+ stop: dayjs.utc('2022-01-01 01:00:00')
33
+ }
34
+ ]
35
+ },
18
36
  logo: () => 'http://example.com/logos/1TV.png?x=шеллы&sid=777'
19
37
  }
@@ -1,6 +1,5 @@
1
1
  module.exports = {
2
2
  site: 'example.com',
3
- ignore: true,
4
3
  url: 'http://example.com/20210319/1tv.json',
5
4
  parser: () => []
6
5
  }
@@ -7,7 +7,6 @@ it('can load valid config.js', () => {
7
7
  const config = utils.loadConfig(require(path.resolve('./tests/input/example.com.config.js')))
8
8
  expect(config).toMatchObject({
9
9
  days: 1,
10
- ignore: true,
11
10
  delay: 3000,
12
11
  lang: 'en',
13
12
  site: 'example.com'
@@ -29,7 +28,7 @@ it('can load valid config.js', () => {
29
28
 
30
29
  it('can parse valid channels.xml', () => {
31
30
  const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
32
- const channels = utils.parseChannels(file)
31
+ const { channels } = utils.parseChannels(file)
33
32
  expect(channels).toEqual([
34
33
  {
35
34
  name: '1 TV',
@@ -52,7 +51,7 @@ 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 channels = utils.parseChannels(file)
54
+ const { channels } = utils.parseChannels(file)
56
55
  const programs = [
57
56
  {
58
57
  title: 'Program 1',
@@ -102,7 +101,7 @@ it('can convert object to xmltv string without categories', () => {
102
101
 
103
102
  it('can convert object to xmltv string with multiple categories', () => {
104
103
  const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
105
- const channels = utils.parseChannels(file)
104
+ const { channels } = utils.parseChannels(file)
106
105
  const programs = [
107
106
  {
108
107
  title: 'Program 1',
@@ -198,6 +197,28 @@ it('can load logo async', done => {
198
197
  })
199
198
  })
200
199
 
200
+ it('can parse programs', done => {
201
+ const config = utils.loadConfig(require(path.resolve('./tests/input/example.com.config.js')))
202
+ return utils
203
+ .parsePrograms({ channel: { xmltv_id: '1tv', lang: 'en' } }, config)
204
+ .then(programs => {
205
+ expect(programs).toMatchObject([
206
+ {
207
+ title: 'Title',
208
+ description: 'Description',
209
+ lang: 'en',
210
+ category: ['Category1', 'Category2'],
211
+ icon: 'https://example.com/image.jpg',
212
+ season: 9,
213
+ episode: 238,
214
+ start: 1640995200,
215
+ stop: 1640998800
216
+ }
217
+ ])
218
+ done()
219
+ })
220
+ })
221
+
201
222
  it('can parse programs async', done => {
202
223
  const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
203
224
  return utils