iptv-checker 0.20.0 → 0.22.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/iptv-checker.js +0 -2
- package/package.json +1 -1
- package/src/helper.js +54 -21
- package/src/index.js +5 -8
- package/test/bin.test.js +12 -0
- package/test/index.test.js +2 -1
- package/test/input/timeout.m3u +3 -0
package/bin/iptv-checker.js
CHANGED
package/package.json
CHANGED
package/src/helper.js
CHANGED
|
@@ -48,25 +48,54 @@ async function parsePlaylist(input) {
|
|
|
48
48
|
return parse(data)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function
|
|
51
|
+
function parseError(output, item) {
|
|
52
52
|
const url = item.url
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
if (arr.length === 0) return
|
|
56
|
-
|
|
57
|
-
const line = arr.find(l => {
|
|
53
|
+
const line = output.split('\n').find(l => {
|
|
58
54
|
return l.indexOf(url) === 0
|
|
59
55
|
})
|
|
60
56
|
|
|
61
57
|
if (!line) {
|
|
62
|
-
|
|
63
|
-
return 'Operation timed out'
|
|
64
|
-
}
|
|
58
|
+
return 'Operation timed out'
|
|
65
59
|
}
|
|
66
60
|
|
|
67
61
|
return line.replace(`${url}: `, '')
|
|
68
62
|
}
|
|
69
63
|
|
|
64
|
+
function parseStderr(stderr) {
|
|
65
|
+
const requests = stderr
|
|
66
|
+
.split('\r\n\n')
|
|
67
|
+
.map(parseRequest)
|
|
68
|
+
.filter(l => l)
|
|
69
|
+
|
|
70
|
+
return { requests }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function parseRequest(string) {
|
|
74
|
+
const urlMatch = string.match(/Opening '(.*)' for reading/)
|
|
75
|
+
const url = urlMatch ? urlMatch[1] : null
|
|
76
|
+
if (!url) return null
|
|
77
|
+
const requestMatch = string.match(/request: (.|[\r\n])+/gm)
|
|
78
|
+
const request = requestMatch ? requestMatch[0] : null
|
|
79
|
+
if (!request) return null
|
|
80
|
+
const arr = request
|
|
81
|
+
.split('\n')
|
|
82
|
+
.map(l => l.trim())
|
|
83
|
+
.filter(l => l)
|
|
84
|
+
const methodMatch = arr[0].match(/request: (GET|POST)/)
|
|
85
|
+
const method = methodMatch ? methodMatch[1] : null
|
|
86
|
+
arr.shift()
|
|
87
|
+
if (!arr) return null
|
|
88
|
+
const headers = {}
|
|
89
|
+
arr.forEach(line => {
|
|
90
|
+
const parts = line.split(': ')
|
|
91
|
+
if (parts && parts[1]) {
|
|
92
|
+
headers[parts[0]] = parts[1]
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
return { method, url, headers }
|
|
97
|
+
}
|
|
98
|
+
|
|
70
99
|
function checkItem(item) {
|
|
71
100
|
const { config, logger } = this
|
|
72
101
|
|
|
@@ -75,12 +104,14 @@ function checkItem(item) {
|
|
|
75
104
|
logger.debug(`EXECUTING: "${command}"`)
|
|
76
105
|
|
|
77
106
|
return execAsync(command, { timeout: config.timeout })
|
|
78
|
-
.then(({ stdout }) => {
|
|
79
|
-
if (stdout && isJSON(stdout)) {
|
|
107
|
+
.then(({ stdout, stderr }) => {
|
|
108
|
+
if (stdout && isJSON(stdout) && stderr) {
|
|
80
109
|
const metadata = JSON.parse(stdout)
|
|
81
110
|
if (!metadata.streams.length) {
|
|
82
|
-
return { ok: false, reason: 'No
|
|
111
|
+
return { ok: false, reason: 'No streams found' }
|
|
83
112
|
}
|
|
113
|
+
const results = parseStderr(stderr)
|
|
114
|
+
metadata.requests = results.requests
|
|
84
115
|
|
|
85
116
|
return { ok: true, metadata }
|
|
86
117
|
}
|
|
@@ -88,34 +119,36 @@ function checkItem(item) {
|
|
|
88
119
|
return { ok: false, reason: 'Parsing error' }
|
|
89
120
|
})
|
|
90
121
|
.catch(err => {
|
|
91
|
-
const reason =
|
|
122
|
+
const reason = parseError(err.message, item)
|
|
92
123
|
|
|
93
124
|
return { ok: false, reason }
|
|
94
125
|
})
|
|
95
126
|
}
|
|
96
127
|
|
|
97
128
|
function buildCommand(item, config) {
|
|
98
|
-
const
|
|
99
|
-
const { referrer = ``, 'user-agent': itemUserAgent = `` } = http
|
|
100
|
-
const userAgent = itemUserAgent.length ? itemUserAgent : config.userAgent
|
|
101
|
-
|
|
129
|
+
const userAgent = item.http['user-agent'] || config.userAgent
|
|
102
130
|
let args = [
|
|
103
131
|
`ffprobe`,
|
|
104
132
|
`-of json`,
|
|
105
|
-
`-v
|
|
133
|
+
`-v debug`,
|
|
106
134
|
`-hide_banner`,
|
|
107
135
|
`-show_streams`,
|
|
136
|
+
`-show_format`,
|
|
108
137
|
]
|
|
109
138
|
|
|
110
|
-
if (
|
|
111
|
-
args.push(`-
|
|
139
|
+
if (config.timeout) {
|
|
140
|
+
args.push(`-timeout`, `'${config.timeout * 1000}'`)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (item.http.referrer) {
|
|
144
|
+
args.push(`-headers`, `'Referer: ${item.http.referrer}'`)
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
if (userAgent) {
|
|
115
148
|
args.push(`-user_agent`, `'${userAgent}'`)
|
|
116
149
|
}
|
|
117
150
|
|
|
118
|
-
args.push(`'${url}'`)
|
|
151
|
+
args.push(`'${item.url}'`)
|
|
119
152
|
|
|
120
153
|
args = args.join(` `)
|
|
121
154
|
|
package/src/index.js
CHANGED
|
@@ -90,19 +90,16 @@ class IPTVChecker {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
async checkStream(item) {
|
|
93
|
-
|
|
94
|
-
const logger = this.logger
|
|
95
|
-
|
|
96
|
-
await config.beforeEach(item)
|
|
93
|
+
await this.config.beforeEach(item)
|
|
97
94
|
|
|
98
|
-
item.status = await helper.checkItem.call(
|
|
95
|
+
item.status = await helper.checkItem.call(this, item)
|
|
99
96
|
if (item.status.ok) {
|
|
100
|
-
logger.debug(`OK: ${item.url}`.green)
|
|
97
|
+
this.logger.debug(`OK: ${item.url}`.green)
|
|
101
98
|
} else {
|
|
102
|
-
logger.debug(`FAILED: ${item.url} (${item.status.reason})`.red)
|
|
99
|
+
this.logger.debug(`FAILED: ${item.url} (${item.status.reason})`.red)
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
await config.afterEach(item)
|
|
102
|
+
await this.config.afterEach(item)
|
|
106
103
|
|
|
107
104
|
return item
|
|
108
105
|
}
|
package/test/bin.test.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { performance } = require('perf_hooks')
|
|
1
2
|
const { execSync } = require('child_process')
|
|
2
3
|
const mkdirp = require('mkdirp')
|
|
3
4
|
const del = require('del')
|
|
@@ -41,3 +42,14 @@ test(`Should process a playlist URL`, () => {
|
|
|
41
42
|
|
|
42
43
|
expect(stdoutResultTester(result)).toBeTruthy()
|
|
43
44
|
})
|
|
45
|
+
|
|
46
|
+
test(`Should respect timeout argument`, () => {
|
|
47
|
+
let t0 = performance.now()
|
|
48
|
+
execSync(
|
|
49
|
+
`node ${pwd}/bin/iptv-checker.js -t 7000 -o ${pwd}/test/output ${pwd}/test/input/timeout.m3u`,
|
|
50
|
+
{ encoding: 'utf8' }
|
|
51
|
+
)
|
|
52
|
+
let t1 = performance.now()
|
|
53
|
+
|
|
54
|
+
expect(t1 - t0).toBeGreaterThan(7000)
|
|
55
|
+
})
|
package/test/index.test.js
CHANGED
|
@@ -12,7 +12,8 @@ function resultTester(result) {
|
|
|
12
12
|
Reflect.has(item, `status`) &&
|
|
13
13
|
Reflect.has(item.status, `ok`) &&
|
|
14
14
|
(Reflect.has(item.status, `reason`) ||
|
|
15
|
-
Reflect.has(item.status, `metadata`)
|
|
15
|
+
(Reflect.has(item.status, `metadata`) &&
|
|
16
|
+
Reflect.has(item.status.metadata, `requests`)))
|
|
16
17
|
)
|
|
17
18
|
})
|
|
18
19
|
}
|