epg-grabber 0.33.0 → 0.35.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/package.json +5 -5
- package/src/client.js +56 -11
- package/src/index.d.ts +11 -2
- package/src/index.js +22 -0
- package/tests/__data__/output/guide.xml +1 -1
- package/tests/index.test.js +56 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epg-grabber",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Node.js CLI tool for grabbing EPG from different sites",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"preferGlobal": true,
|
|
@@ -28,9 +28,8 @@
|
|
|
28
28
|
"node": ">=10.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"axios": "^
|
|
31
|
+
"axios": "^1.6.1",
|
|
32
32
|
"axios-cache-interceptor": "^0.10.3",
|
|
33
|
-
"axios-cookiejar-support": "^1.0.1",
|
|
34
33
|
"axios-mock-adapter": "^1.20.0",
|
|
35
34
|
"commander": "^7.1.0",
|
|
36
35
|
"curl-generator": "^0.2.0",
|
|
@@ -39,9 +38,10 @@
|
|
|
39
38
|
"epg-parser": "^0.1.6",
|
|
40
39
|
"fs-extra": "^11.1.1",
|
|
41
40
|
"glob": "^7.1.6",
|
|
41
|
+
"http-cookie-agent": "^5.0.4",
|
|
42
42
|
"lodash": "^4.17.21",
|
|
43
43
|
"node-gzip": "^1.1.2",
|
|
44
|
-
"tough-cookie": "^4.
|
|
44
|
+
"tough-cookie": "^4.1.3",
|
|
45
45
|
"winston": "^3.3.3",
|
|
46
46
|
"xml-js": "^1.6.11"
|
|
47
47
|
},
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@babel/preset-env": "^7.13.12",
|
|
51
51
|
"babel-jest": "^26.6.3",
|
|
52
52
|
"eslint": "^7.22.0",
|
|
53
|
-
"jest": "^
|
|
53
|
+
"jest": "^29.7.0",
|
|
54
54
|
"jest-mock-axios": "^4.4.1"
|
|
55
55
|
},
|
|
56
56
|
"jest": {
|
package/src/client.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const { CurlGenerator } = require('curl-generator')
|
|
2
|
-
const axios = require('axios')
|
|
3
|
-
const
|
|
2
|
+
const { default: axios } = require('axios')
|
|
3
|
+
const { CookieJar } = require('tough-cookie')
|
|
4
4
|
const { setupCache } = require('axios-cache-interceptor')
|
|
5
5
|
const { isObject, isPromise } = require('./utils')
|
|
6
|
+
const { HttpCookieAgent, HttpsCookieAgent } = require('http-cookie-agent/http')
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
const jar = new CookieJar()
|
|
8
9
|
|
|
9
10
|
module.exports.create = create
|
|
10
11
|
module.exports.buildRequest = buildRequest
|
|
@@ -13,14 +14,17 @@ module.exports.parseResponse = parseResponse
|
|
|
13
14
|
let timeout
|
|
14
15
|
|
|
15
16
|
function create(config) {
|
|
16
|
-
const client =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
const client = setupCookie(
|
|
18
|
+
setupCache(
|
|
19
|
+
axios.create({
|
|
20
|
+
jar,
|
|
21
|
+
ignoreCookieErrors: true,
|
|
22
|
+
headers: {
|
|
23
|
+
'User-Agent':
|
|
24
|
+
'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'
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
)
|
|
24
28
|
)
|
|
25
29
|
|
|
26
30
|
client.interceptors.request.use(
|
|
@@ -136,3 +140,44 @@ async function getRequestUrl({ channel, date, config }) {
|
|
|
136
140
|
}
|
|
137
141
|
return config.url
|
|
138
142
|
}
|
|
143
|
+
|
|
144
|
+
const AGENT_CREATED_BY_AXIOS_COOKIEJAR_SUPPORT = Symbol('AGENT_CREATED_BY_AXIOS_COOKIEJAR_SUPPORT')
|
|
145
|
+
|
|
146
|
+
function requestInterceptor(config) {
|
|
147
|
+
if (!config.jar) {
|
|
148
|
+
return config
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
config.httpAgent = new HttpCookieAgent({ cookies: { jar: config.jar } })
|
|
152
|
+
Object.defineProperty(config.httpAgent, AGENT_CREATED_BY_AXIOS_COOKIEJAR_SUPPORT, {
|
|
153
|
+
configurable: false,
|
|
154
|
+
enumerable: false,
|
|
155
|
+
value: true,
|
|
156
|
+
writable: false
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
config.httpsAgent = new HttpsCookieAgent({ cookies: { jar: config.jar } })
|
|
160
|
+
Object.defineProperty(config.httpsAgent, AGENT_CREATED_BY_AXIOS_COOKIEJAR_SUPPORT, {
|
|
161
|
+
configurable: false,
|
|
162
|
+
enumerable: false,
|
|
163
|
+
value: true,
|
|
164
|
+
writable: false
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
return config
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function setupCookie(axios) {
|
|
171
|
+
axios.interceptors.request.use(requestInterceptor)
|
|
172
|
+
|
|
173
|
+
if ('create' in axios) {
|
|
174
|
+
const create = axios.create
|
|
175
|
+
axios.create = (...args) => {
|
|
176
|
+
const instance = create.apply(axios, args)
|
|
177
|
+
instance.interceptors.request.use(requestInterceptor)
|
|
178
|
+
return instance
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return axios
|
|
183
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -101,10 +101,19 @@ export type GrabCallbackData = {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
export declare class EPGGrabber {
|
|
104
|
-
constructor(config:
|
|
104
|
+
constructor(config: SiteConfig)
|
|
105
105
|
grab(
|
|
106
106
|
channel: Channel,
|
|
107
107
|
date: string | dayjs.Dayjs,
|
|
108
|
-
cb: (data: GrabCallbackData, err: Error) => void
|
|
108
|
+
cb: (data: GrabCallbackData, err: Error | null) => void
|
|
109
|
+
): Promise<Program[]>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export declare class EPGGrabberMock {
|
|
113
|
+
constructor(config: SiteConfig)
|
|
114
|
+
grab(
|
|
115
|
+
channel: Channel,
|
|
116
|
+
date: string | dayjs.Dayjs,
|
|
117
|
+
cb: (data: GrabCallbackData, err: Error | null) => void
|
|
109
118
|
): Promise<Program[]>
|
|
110
119
|
}
|
package/src/index.js
CHANGED
|
@@ -53,4 +53,26 @@ class EPGGrabber {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
class EPGGrabberMock {
|
|
57
|
+
constructor(config) {
|
|
58
|
+
this.config = config
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async grab(channel, date, cb) {
|
|
62
|
+
let _date = getUTCDate(date)
|
|
63
|
+
let _programs = await this.config.parser({ channel, date: _date })
|
|
64
|
+
let programs = _programs.map(data => new Program(data, channel))
|
|
65
|
+
|
|
66
|
+
if (this.config.request?.timeout !== undefined && this.config.request.timeout < 1) {
|
|
67
|
+
cb({ programs: [], date: _date, channel }, new Error('Connection timeout'))
|
|
68
|
+
return []
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
cb({ programs, date: _date, channel }, null)
|
|
72
|
+
|
|
73
|
+
return programs
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
56
77
|
module.exports.EPGGrabber = EPGGrabber
|
|
78
|
+
module.exports.EPGGrabberMock = EPGGrabberMock
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8" ?><tv date="
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?><tv date="20231116">
|
|
2
2
|
<channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>
|
|
3
3
|
<channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&sid=777"/><url>https://example.com</url></channel>
|
|
4
4
|
<channel id="3TV.com"><display-name>3 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&sid=777"/><url>https://example2.com</url></channel>
|
package/tests/index.test.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @jest-environment node
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { EPGGrabber, Channel } from '../src/index'
|
|
5
|
+
import { EPGGrabber, EPGGrabberMock, Channel } from '../src/index'
|
|
6
6
|
import axios from 'axios'
|
|
7
7
|
|
|
8
8
|
jest.mock('axios')
|
|
@@ -66,3 +66,58 @@ it('can grab single channel programs', done => {
|
|
|
66
66
|
done()
|
|
67
67
|
})
|
|
68
68
|
})
|
|
69
|
+
|
|
70
|
+
it('can mock epg grabber', done => {
|
|
71
|
+
const config = {
|
|
72
|
+
site: 'example.com',
|
|
73
|
+
url: 'http://example.com/20210319/1tv.json',
|
|
74
|
+
parser: ({ channel, date }) => [
|
|
75
|
+
{ title: `Test (${channel.name})`, start: '2021-03-19T04:30:00.000Z' }
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
const channel = new Channel({
|
|
79
|
+
site: 'example.com',
|
|
80
|
+
site_id: '1',
|
|
81
|
+
xmltv_id: '1TV.fr',
|
|
82
|
+
lang: 'fr',
|
|
83
|
+
name: '1TV'
|
|
84
|
+
})
|
|
85
|
+
const grabber = new EPGGrabberMock(config)
|
|
86
|
+
grabber
|
|
87
|
+
.grab(channel, '2022-01-01', (data, err) => {
|
|
88
|
+
if (err) {
|
|
89
|
+
done()
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.then(programs => {
|
|
93
|
+
expect(programs.length).toBe(1)
|
|
94
|
+
expect(programs).toEqual([
|
|
95
|
+
{
|
|
96
|
+
site: 'example.com',
|
|
97
|
+
channel: '1TV.fr',
|
|
98
|
+
titles: [{ value: 'Test (1TV)', lang: 'fr' }],
|
|
99
|
+
sub_titles: [],
|
|
100
|
+
descriptions: [],
|
|
101
|
+
icon: { src: '' },
|
|
102
|
+
episodeNumbers: [],
|
|
103
|
+
date: null,
|
|
104
|
+
start: 1616128200000,
|
|
105
|
+
stop: null,
|
|
106
|
+
urls: [],
|
|
107
|
+
ratings: [],
|
|
108
|
+
categories: [],
|
|
109
|
+
directors: [],
|
|
110
|
+
actors: [],
|
|
111
|
+
writers: [],
|
|
112
|
+
adapters: [],
|
|
113
|
+
producers: [],
|
|
114
|
+
composers: [],
|
|
115
|
+
editors: [],
|
|
116
|
+
presenters: [],
|
|
117
|
+
commentators: [],
|
|
118
|
+
guests: []
|
|
119
|
+
}
|
|
120
|
+
])
|
|
121
|
+
done()
|
|
122
|
+
})
|
|
123
|
+
})
|