epg-grabber 0.25.2 → 0.26.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
@@ -80,7 +80,7 @@ Arguments:
80
80
  - `--days`: number of days for which to grab the program (default: 1)
81
81
  - `--delay`: delay between requests (default: 3000)
82
82
  - `--timeout`: set a timeout for each request (default: 5000)
83
- - `--cache-max-age`: maximum time for storing each request in milliseconds (default: 0)
83
+ - `--cache-ttl`: maximum time for storing each request in milliseconds (default: 0)
84
84
  - `--gzip`: compress the output (default: false)
85
85
  - `--debug`: enable debug mode (default: false)
86
86
  - `--curl`: display current request as CURL (default: false)
@@ -102,12 +102,8 @@ module.exports = {
102
102
 
103
103
  method: 'GET',
104
104
  timeout: 5000,
105
- cache: { // cache options (details: https://github.com/RasCarlito/axios-cache-adapter#options)
106
- maxAge: 0,
107
- readHeaders: false,
108
- exclude: {
109
- query: false
110
- }
105
+ cache: { // cache options (details: https://axios-cache-interceptor.js.org/#/pages/per-request-configuration)
106
+ ttl: 60 * 1000 // 60s
111
107
  },
112
108
 
113
109
  /**
@@ -192,6 +188,8 @@ From each function in `config.js` you can access a `context` object containing t
192
188
  - `content`: The response data as a String
193
189
  - `buffer`: The response data as an ArrayBuffer
194
190
  - `headers`: The response headers
191
+ - `request`: The request config
192
+ - `cached`: A boolean to check whether this request was cached or not
195
193
 
196
194
  ## Channels List
197
195
 
@@ -24,7 +24,7 @@ program
24
24
  .option('--delay <delay>', 'Delay between requests (in mileseconds)', parseInteger)
25
25
  .option('--timeout <timeout>', 'Set a timeout for each request (in mileseconds)', parseInteger)
26
26
  .option(
27
- '--cache-max-age <cacheMaxAge>',
27
+ '--cache-ttl <cacheTtl>',
28
28
  'Maximum time for storing each request (in milliseconds)',
29
29
  parseInteger
30
30
  )
@@ -76,14 +76,11 @@ async function main() {
76
76
  curl: options.curl,
77
77
  lang: options.lang,
78
78
  delay: options.delay,
79
- request: {
80
- timeout: options.timeout,
81
- cache: {
82
- maxAge: options.cacheMaxAge
83
- }
84
- }
79
+ request: {}
85
80
  })
86
81
 
82
+ if (options.timeout) config.request.timeout = options.timeout
83
+ if (options.cacheTtl) config.request.cache.ttl = options.cacheTtl
87
84
  if (options.channels) config.channels = options.channels
88
85
  else if (config.channels)
89
86
  config.channels = path.join(path.dirname(options.config), config.channels)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epg-grabber",
3
- "version": "0.25.2",
3
+ "version": "0.26.0",
4
4
  "description": "Node.js CLI tool for grabbing EPG from different sites",
5
5
  "main": "src/index.js",
6
6
  "preferGlobal": true,
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "axios": "^0.21.1",
32
- "axios-cache-adapter": "^2.7.3",
32
+ "axios-cache-interceptor": "^0.10.3",
33
33
  "axios-cookiejar-support": "^1.0.1",
34
34
  "axios-mock-adapter": "^1.20.0",
35
35
  "commander": "^7.1.0",
package/src/utils.js CHANGED
@@ -3,7 +3,7 @@ const { padStart } = require('lodash')
3
3
  const path = require('path')
4
4
  const axios = require('axios').default
5
5
  const axiosCookieJarSupport = require('axios-cookiejar-support').default
6
- const axiosCacheAdapter = require('axios-cache-adapter')
6
+ const { setupCache } = require('axios-cache-interceptor')
7
7
  const tough = require('tough-cookie')
8
8
  const convert = require('xml-js')
9
9
  const { merge } = require('lodash')
@@ -41,13 +41,7 @@ utils.loadConfig = function (config) {
41
41
  withCredentials: true,
42
42
  jar: new tough.CookieJar(),
43
43
  responseType: 'arraybuffer',
44
- cache: {
45
- readHeaders: false,
46
- exclude: {
47
- query: false
48
- },
49
- maxAge: 0
50
- }
44
+ cache: false
51
45
  }
52
46
  }
53
47
 
@@ -55,7 +49,7 @@ utils.loadConfig = function (config) {
55
49
  }
56
50
 
57
51
  utils.createClient = function (config) {
58
- const client = axiosCacheAdapter.setup()
52
+ const client = setupCache(axios.create())
59
53
  client.interceptors.request.use(
60
54
  function (request) {
61
55
  if (config.debug) {
@@ -80,7 +74,7 @@ utils.createClient = function (config) {
80
74
  {
81
75
  headers: response.headers,
82
76
  data,
83
- fromCache: response.request.fromCache === true
77
+ cached: response.cached
84
78
  },
85
79
  null,
86
80
  2
@@ -220,13 +214,15 @@ utils.convertToXMLTV = function ({ channels, programs }) {
220
214
  output += '</tv>'
221
215
 
222
216
  function createXMLTVNS(s, e) {
223
- if (!s || !e) return null
217
+ if (!e) return null
218
+ s = s || 1
224
219
 
225
220
  return `${s - 1}.${e - 1}.0/1`
226
221
  }
227
222
 
228
223
  function createOnScreen(s, e) {
229
- if (!s || !e) return null
224
+ if (!e) return null
225
+ s = s || 1
230
226
 
231
227
  s = padStart(s, 2, '0')
232
228
  e = padStart(e, 2, '0')
@@ -316,20 +312,12 @@ utils.getUTCDate = function (d = null) {
316
312
  }
317
313
 
318
314
  utils.parseResponse = async (item, response, config) => {
319
- let buffer
320
- let content
321
- if (utils.isObject(response.data) || Array.isArray(response.data)) {
322
- content = JSON.stringify(response.data)
323
- buffer = Buffer.from(content, 'utf8')
324
- } else {
325
- content = response.data.toString()
326
- buffer = response.data
327
- }
328
315
  const data = merge(item, config, {
329
- content,
330
- buffer,
316
+ content: response.data.toString(),
317
+ buffer: response.data,
331
318
  headers: response.headers,
332
- request: response.request
319
+ request: response.request,
320
+ cached: response.cached
333
321
  })
334
322
 
335
323
  if (!item.channel.logo && config.logo) {
@@ -73,6 +73,50 @@ it('can convert object to xmltv string', () => {
73
73
  )
74
74
  })
75
75
 
76
+ it('can convert object to xmltv string without season number', () => {
77
+ const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
78
+ const { channels } = utils.parseChannels(file)
79
+ const programs = [
80
+ {
81
+ title: 'Program 1',
82
+ description: 'Description for Program 1',
83
+ start: 1616133600,
84
+ stop: 1616135400,
85
+ category: 'Test',
86
+ episode: 239,
87
+ icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777',
88
+ channel: '1TV.com',
89
+ lang: 'it'
90
+ }
91
+ ]
92
+ const output = utils.convertToXMLTV({ channels, programs })
93
+ expect(output).toBe(
94
+ '<?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><episode-num system="xmltv_ns">0.238.0/1</episode-num><episode-num system="onscreen">S01E239</episode-num><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/></programme>\r\n</tv>'
95
+ )
96
+ })
97
+
98
+ it('can convert object to xmltv string without episode number', () => {
99
+ const file = fs.readFileSync('./tests/input/example.com.channels.xml', { encoding: 'utf-8' })
100
+ const { channels } = utils.parseChannels(file)
101
+ const programs = [
102
+ {
103
+ title: 'Program 1',
104
+ description: 'Description for Program 1',
105
+ start: 1616133600,
106
+ stop: 1616135400,
107
+ category: 'Test',
108
+ season: 1,
109
+ icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777',
110
+ channel: '1TV.com',
111
+ lang: 'it'
112
+ }
113
+ ]
114
+ const output = utils.convertToXMLTV({ channels, programs })
115
+ expect(output).toBe(
116
+ '<?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>'
117
+ )
118
+ })
119
+
76
120
  it('can convert object to xmltv string without categories', () => {
77
121
  const channels = [
78
122
  {
@@ -149,7 +193,7 @@ it('can fetch data', () => {
149
193
  url: 'http://example.com/20210319/1tv.json',
150
194
  withCredentials: true
151
195
  }
152
- utils.fetchData(axios, request).then(jest.fn).catch(jest.fn)
196
+ utils.fetchData(mockAxios, request).then(jest.fn).catch(jest.fn)
153
197
  expect(mockAxios).toHaveBeenCalledWith(
154
198
  expect.objectContaining({
155
199
  data: { accountID: '123' },
@@ -170,37 +214,46 @@ it('can fetch data', () => {
170
214
 
171
215
  it('can build request async', done => {
172
216
  const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
173
- return utils.buildRequest({}, config).then(request => {
174
- expect(request).toMatchObject({
175
- data: { accountID: '123' },
176
- headers: {
177
- 'Content-Type': 'application/json',
178
- Cookie: 'abc=123',
179
- 'User-Agent':
180
- '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'
181
- },
182
- maxContentLength: 5242880,
183
- method: 'POST',
184
- responseType: 'arraybuffer',
185
- timeout: 5000,
186
- url: 'http://example.com/20210319/1tv.json',
187
- withCredentials: true
217
+
218
+ utils
219
+ .buildRequest({}, config)
220
+ .then(request => {
221
+ expect(request).toMatchObject({
222
+ data: { accountID: '123' },
223
+ headers: {
224
+ 'Content-Type': 'application/json',
225
+ Cookie: 'abc=123',
226
+ 'User-Agent':
227
+ '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'
228
+ },
229
+ maxContentLength: 5242880,
230
+ method: 'POST',
231
+ responseType: 'arraybuffer',
232
+ timeout: 5000,
233
+ url: 'http://example.com/20210319/1tv.json',
234
+ withCredentials: true
235
+ })
236
+ done()
188
237
  })
189
- done()
190
- })
238
+ .catch(done)
191
239
  })
192
240
 
193
241
  it('can load logo async', done => {
194
242
  const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
195
- return utils.loadLogo({}, config).then(logo => {
196
- expect(logo).toBe('http://example.com/logos/1TV.png?x=шеллы&sid=777')
197
- done()
198
- })
243
+
244
+ utils
245
+ .loadLogo({}, config)
246
+ .then(logo => {
247
+ expect(logo).toBe('http://example.com/logos/1TV.png?x=шеллы&sid=777')
248
+ done()
249
+ })
250
+ .catch(done)
199
251
  })
200
252
 
201
253
  it('can parse programs', done => {
202
254
  const config = utils.loadConfig(require(path.resolve('./tests/input/example.com.config.js')))
203
- return utils
255
+
256
+ utils
204
257
  .parsePrograms({ channel: { xmltv_id: '1tv', lang: 'en' } }, config)
205
258
  .then(programs => {
206
259
  expect(programs).toMatchObject([
@@ -218,14 +271,17 @@ it('can parse programs', done => {
218
271
  ])
219
272
  done()
220
273
  })
274
+ .catch(done)
221
275
  })
222
276
 
223
277
  it('can parse programs async', done => {
224
278
  const config = utils.loadConfig(require(path.resolve('./tests/input/async.config.js')))
225
- return utils
279
+
280
+ utils
226
281
  .parsePrograms({ channel: { xmltv_id: '1tv', lang: 'en' } }, config)
227
282
  .then(programs => {
228
283
  expect(programs.length).toBe(0)
229
284
  done()
230
285
  })
286
+ .catch(done)
231
287
  })