epg-grabber 0.43.0 → 0.44.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/dist/cli.js +1 -1
- package/dist/{index-_okTrZbD.js → index-DQUOgwl_.js} +55 -14
- package/dist/index.d.ts +9 -3
- package/dist/index.js +1 -1
- package/package.json +2 -1
- package/src/core/utils.ts +12 -13
- package/src/index.ts +61 -1
- package/src/types/index.d.ts +1 -0
- package/src/types/siteConfig.d.ts +2 -2
- package/src/types/utils.d.ts +0 -10
- package/tests/core/utils.test.ts +9 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as name, v as version, d as description, p as parseNumber, L as Logger, l as loadJs, a as parseProxy, E as EPGGrabber, g as getUTCDate } from './index-
|
|
2
|
+
import { n as name, v as version, d as description, p as parseNumber, L as Logger, l as loadJs, a as parseProxy, E as EPGGrabber, g as getUTCDate } from './index-DQUOgwl_.js';
|
|
3
3
|
import { Template, Collection } from '@freearhey/core';
|
|
4
4
|
import { Command, Option } from 'commander';
|
|
5
5
|
import { SocksProxyAgent } from 'socks-proxy-agent';
|
|
@@ -14,19 +14,17 @@ import xmlJs from 'xml-js';
|
|
|
14
14
|
import fs from 'fs-extra';
|
|
15
15
|
|
|
16
16
|
dayjs.extend(utc);
|
|
17
|
-
function parseProxy(
|
|
18
|
-
const parsed = new URL(
|
|
19
|
-
const
|
|
20
|
-
protocol: parsed.protocol.replace(":", "")
|
|
17
|
+
function parseProxy(string) {
|
|
18
|
+
const parsed = new URL(string);
|
|
19
|
+
const proxy = {
|
|
20
|
+
protocol: parsed.protocol.replace(":", ""),
|
|
21
21
|
host: parsed.hostname,
|
|
22
|
-
port: parsed.port ? parseInt(parsed.port) :
|
|
22
|
+
port: parsed.port ? parseInt(parsed.port) : 8080
|
|
23
23
|
};
|
|
24
24
|
if (parsed.username || parsed.password) {
|
|
25
|
-
|
|
26
|
-
if (parsed.username) result.auth.username = parsed.username;
|
|
27
|
-
if (parsed.password) result.auth.password = parsed.password;
|
|
25
|
+
proxy.auth = { username: parsed.username, password: parsed.password };
|
|
28
26
|
}
|
|
29
|
-
return
|
|
27
|
+
return proxy;
|
|
30
28
|
}
|
|
31
29
|
async function loadJs(filepath) {
|
|
32
30
|
const absPath = path.resolve(filepath);
|
|
@@ -47,9 +45,9 @@ function isObject(value) {
|
|
|
47
45
|
function isPromise(promise) {
|
|
48
46
|
return promise instanceof Promise;
|
|
49
47
|
}
|
|
50
|
-
function getUTCDate(date
|
|
51
|
-
if (
|
|
52
|
-
return dayjs.utc().startOf("d");
|
|
48
|
+
function getUTCDate(date) {
|
|
49
|
+
if (dayjs.isDayjs(date) && date.isUTC()) return date;
|
|
50
|
+
return dayjs.utc(date).startOf("d");
|
|
53
51
|
}
|
|
54
52
|
function getAbsPath(filepath, rootDir) {
|
|
55
53
|
if (path.isAbsolute(filepath)) return filepath;
|
|
@@ -103,7 +101,7 @@ function toArray(value) {
|
|
|
103
101
|
}
|
|
104
102
|
|
|
105
103
|
var name = "epg-grabber";
|
|
106
|
-
var version = "0.
|
|
104
|
+
var version = "0.44.0";
|
|
107
105
|
var description = "Node.js CLI tool for grabbing EPG from different sites";
|
|
108
106
|
var homepage = "https://github.com/freearhey/epg-grabber";
|
|
109
107
|
|
|
@@ -1008,7 +1006,50 @@ class EPGGrabber {
|
|
|
1008
1006
|
}
|
|
1009
1007
|
class EPGGrabberMock extends EPGGrabber {
|
|
1010
1008
|
async grab(channel, date, config, callback) {
|
|
1011
|
-
|
|
1009
|
+
if (!callback) callback = () => {
|
|
1010
|
+
};
|
|
1011
|
+
if (typeof config === "function") {
|
|
1012
|
+
callback = config;
|
|
1013
|
+
config = void 0;
|
|
1014
|
+
}
|
|
1015
|
+
if (!(channel instanceof Channel)) {
|
|
1016
|
+
throw new Error('The first argument must be the "Channel" class');
|
|
1017
|
+
}
|
|
1018
|
+
const utcDate = getUTCDate(date);
|
|
1019
|
+
try {
|
|
1020
|
+
const configObject = config || this.globalConfig;
|
|
1021
|
+
if (!configObject) throw new Error("Site config is missing");
|
|
1022
|
+
const siteConfig = new SiteConfig(configObject);
|
|
1023
|
+
siteConfig.update(this.globalConfig);
|
|
1024
|
+
this.logger.debug(`Config (local): ${JSON.stringify(siteConfig, null, 2)}`);
|
|
1025
|
+
siteConfig.validate();
|
|
1026
|
+
const requestContext = { channel, date: utcDate, siteConfig };
|
|
1027
|
+
await Client.buildRequest(requestContext, { logger: this.logger });
|
|
1028
|
+
const response = { cached: false };
|
|
1029
|
+
if (!siteConfig.parser) {
|
|
1030
|
+
throw new Error("Could not find parser() in the config file");
|
|
1031
|
+
}
|
|
1032
|
+
const parserContext = {
|
|
1033
|
+
...response,
|
|
1034
|
+
channel,
|
|
1035
|
+
date: utcDate,
|
|
1036
|
+
config: siteConfig
|
|
1037
|
+
};
|
|
1038
|
+
let parsedPrograms = siteConfig.parser(parserContext);
|
|
1039
|
+
if (isPromise(parsedPrograms)) {
|
|
1040
|
+
parsedPrograms = await parsedPrograms;
|
|
1041
|
+
}
|
|
1042
|
+
const programs = await EPGGrabber.parseParserResults(
|
|
1043
|
+
parsedPrograms,
|
|
1044
|
+
channel
|
|
1045
|
+
);
|
|
1046
|
+
callback({ channel, date: utcDate, programs }, null);
|
|
1047
|
+
return programs;
|
|
1048
|
+
} catch (error) {
|
|
1049
|
+
this.logger.debug(`Error: ${JSON.stringify(error, null, 2)}`);
|
|
1050
|
+
callback({ channel, date: utcDate, programs: [] }, error);
|
|
1051
|
+
return [];
|
|
1052
|
+
}
|
|
1012
1053
|
}
|
|
1013
1054
|
}
|
|
1014
1055
|
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,11 @@ interface GrabCallbackContext {
|
|
|
207
207
|
date: Dayjs
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
type XMLElement =
|
|
211
|
+
| string
|
|
212
|
+
| number
|
|
213
|
+
| { name: string; attrs?: Record<string, string>; children?: XMLElement[] }
|
|
214
|
+
|
|
210
215
|
type index_d_AudioObject = AudioObject;
|
|
211
216
|
type index_d_ChannelData = ChannelData;
|
|
212
217
|
type index_d_ClientRequestConfig = ClientRequestConfig;
|
|
@@ -234,8 +239,9 @@ type index_d_SubtitlesObject = SubtitlesObject;
|
|
|
234
239
|
type index_d_TextObject = TextObject;
|
|
235
240
|
type index_d_UrlObject = UrlObject;
|
|
236
241
|
type index_d_VideoObject = VideoObject;
|
|
242
|
+
type index_d_XMLElement = XMLElement;
|
|
237
243
|
declare namespace index_d {
|
|
238
|
-
export type { index_d_AudioObject as AudioObject, index_d_ChannelData as ChannelData, index_d_ClientRequestConfig as ClientRequestConfig, index_d_ClientResponse as ClientResponse, index_d_DateObject as DateObject, index_d_EpisodeNumberObject as EpisodeNumberObject, index_d_GrabCallback as GrabCallback, index_d_GrabCallbackContext as GrabCallbackContext, index_d_IconObject as IconObject, index_d_ImageObject as ImageObject, index_d_LenghtObject as LenghtObject, index_d_PersonObject as PersonObject, index_d_PreviouslyShownObject as PreviouslyShownObject, index_d_ProgramData as ProgramData, index_d_RatingObject as RatingObject, index_d_ReviewObject as ReviewObject, index_d_SiteConfigObject as SiteConfigObject, index_d_SiteConfigOptions as SiteConfigOptions, index_d_SiteConfigParserContext as SiteConfigParserContext, index_d_SiteConfigParserResult as SiteConfigParserResult, index_d_SiteConfigRequestConfig as SiteConfigRequestConfig, index_d_SiteConfigRequestConfigData as SiteConfigRequestConfigData, index_d_SiteConfigRequestContext as SiteConfigRequestContext, index_d_SubtitlesObject as SubtitlesObject, index_d_TextObject as TextObject, index_d_UrlObject as UrlObject, index_d_VideoObject as VideoObject };
|
|
244
|
+
export type { index_d_AudioObject as AudioObject, index_d_ChannelData as ChannelData, index_d_ClientRequestConfig as ClientRequestConfig, index_d_ClientResponse as ClientResponse, index_d_DateObject as DateObject, index_d_EpisodeNumberObject as EpisodeNumberObject, index_d_GrabCallback as GrabCallback, index_d_GrabCallbackContext as GrabCallbackContext, index_d_IconObject as IconObject, index_d_ImageObject as ImageObject, index_d_LenghtObject as LenghtObject, index_d_PersonObject as PersonObject, index_d_PreviouslyShownObject as PreviouslyShownObject, index_d_ProgramData as ProgramData, index_d_RatingObject as RatingObject, index_d_ReviewObject as ReviewObject, index_d_SiteConfigObject as SiteConfigObject, index_d_SiteConfigOptions as SiteConfigOptions, index_d_SiteConfigParserContext as SiteConfigParserContext, index_d_SiteConfigParserResult as SiteConfigParserResult, index_d_SiteConfigRequestConfig as SiteConfigRequestConfig, index_d_SiteConfigRequestConfigData as SiteConfigRequestConfigData, index_d_SiteConfigRequestContext as SiteConfigRequestContext, index_d_SubtitlesObject as SubtitlesObject, index_d_TextObject as TextObject, index_d_UrlObject as UrlObject, index_d_VideoObject as VideoObject, index_d_XMLElement as XMLElement };
|
|
239
245
|
}
|
|
240
246
|
|
|
241
247
|
declare class Program {
|
|
@@ -303,7 +309,7 @@ interface SiteConfigObject {
|
|
|
303
309
|
debug?: boolean
|
|
304
310
|
output?: string
|
|
305
311
|
channels?: string | string[]
|
|
306
|
-
request?:
|
|
312
|
+
request?: SiteConfigRequestConfig
|
|
307
313
|
logo?: ((context: SiteConfigRequestContext) => string | Promise<string>) | string
|
|
308
314
|
}
|
|
309
315
|
|
|
@@ -317,7 +323,7 @@ type SiteConfigRequestConfigData =
|
|
|
317
323
|
| Record<string, unknown>
|
|
318
324
|
| null
|
|
319
325
|
|
|
320
|
-
|
|
326
|
+
type SiteConfigRequestConfig = Omit<CacheRequestConfig, 'headers' | 'data'> & {
|
|
321
327
|
data?:
|
|
322
328
|
| ((
|
|
323
329
|
context: SiteConfigRequestContext
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export { C as Channel, E as EPGGrabber, b as EPGGrabberMock, P as Program } from './index-
|
|
2
|
+
export { C as Channel, E as EPGGrabber, b as EPGGrabberMock, P as Program } from './index-DQUOgwl_.js';
|
|
3
3
|
import '@freearhey/core';
|
|
4
4
|
import 'xml-js';
|
|
5
5
|
import 'fs-extra';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epg-grabber",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "Node.js CLI tool for grabbing EPG from different sites",
|
|
5
5
|
"homepage": "https://github.com/freearhey/epg-grabber",
|
|
6
6
|
"preferGlobal": true,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"cli": "tsx ./src/cli.ts",
|
|
18
18
|
"build": "pkgroll --clean-dist",
|
|
19
|
+
"dev": "pkgroll --watch",
|
|
19
20
|
"lint": "npx eslint ./src/**/*.ts ./tests/**/*.ts",
|
|
20
21
|
"test": "npx vitest run"
|
|
21
22
|
},
|
package/src/core/utils.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { XMLElement } from '../types/utils'
|
|
2
2
|
import dayjs, { Dayjs } from 'dayjs'
|
|
3
3
|
import utc from 'dayjs/plugin/utc.js'
|
|
4
4
|
import { URL } from 'node:url'
|
|
5
5
|
import path from 'node:path'
|
|
6
|
+
import { AxiosProxyConfig } from 'axios'
|
|
6
7
|
|
|
7
8
|
dayjs.extend(utc)
|
|
8
9
|
|
|
9
|
-
export function parseProxy(
|
|
10
|
-
const parsed = new URL(
|
|
10
|
+
export function parseProxy(string: string): AxiosProxyConfig {
|
|
11
|
+
const parsed = new URL(string)
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
protocol: parsed.protocol.replace(':', '')
|
|
13
|
+
const proxy: AxiosProxyConfig = {
|
|
14
|
+
protocol: parsed.protocol.replace(':', ''),
|
|
14
15
|
host: parsed.hostname,
|
|
15
|
-
port: parsed.port ? parseInt(parsed.port) :
|
|
16
|
+
port: parsed.port ? parseInt(parsed.port) : 8080
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
if (parsed.username || parsed.password) {
|
|
19
|
-
|
|
20
|
-
if (parsed.username) result.auth.username = parsed.username
|
|
21
|
-
if (parsed.password) result.auth.password = parsed.password
|
|
20
|
+
proxy.auth = { username: parsed.username, password: parsed.password }
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
return
|
|
23
|
+
return proxy
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export async function loadJs(filepath: string) {
|
|
@@ -50,10 +49,10 @@ export function isPromise(promise: unknown): boolean {
|
|
|
50
49
|
return promise instanceof Promise
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
export function getUTCDate(date
|
|
54
|
-
if (
|
|
52
|
+
export function getUTCDate(date?: string | number | Date | Dayjs | null) {
|
|
53
|
+
if (dayjs.isDayjs(date) && date.isUTC()) return date
|
|
55
54
|
|
|
56
|
-
return dayjs.utc().startOf('d')
|
|
55
|
+
return dayjs.utc(date).startOf('d')
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
export function getAbsPath(filepath: string, rootDir: string) {
|
package/src/index.ts
CHANGED
|
@@ -216,6 +216,66 @@ export class EPGGrabberMock extends EPGGrabber {
|
|
|
216
216
|
config?: SiteConfigObject | GrabCallback,
|
|
217
217
|
callback?: GrabCallback
|
|
218
218
|
): Promise<Program[]> {
|
|
219
|
-
|
|
219
|
+
if (!callback) callback = () => {}
|
|
220
|
+
if (typeof config === 'function') {
|
|
221
|
+
callback = config
|
|
222
|
+
config = undefined
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (!(channel instanceof Channel)) {
|
|
226
|
+
throw new Error('The first argument must be the "Channel" class')
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const utcDate = getUTCDate(date)
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
const configObject = config || this.globalConfig
|
|
233
|
+
if (!configObject) throw new Error('Site config is missing')
|
|
234
|
+
|
|
235
|
+
const siteConfig = new SiteConfig(configObject)
|
|
236
|
+
|
|
237
|
+
siteConfig.update(this.globalConfig)
|
|
238
|
+
|
|
239
|
+
this.logger.debug(`Config (local): ${JSON.stringify(siteConfig, null, 2)}`)
|
|
240
|
+
|
|
241
|
+
siteConfig.validate()
|
|
242
|
+
|
|
243
|
+
const requestContext = { channel, date: utcDate, siteConfig }
|
|
244
|
+
|
|
245
|
+
await Client.buildRequest(requestContext, { logger: this.logger })
|
|
246
|
+
|
|
247
|
+
const response = { cached: false }
|
|
248
|
+
|
|
249
|
+
if (!siteConfig.parser) {
|
|
250
|
+
throw new Error('Could not find parser() in the config file')
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const parserContext = {
|
|
254
|
+
...response,
|
|
255
|
+
channel,
|
|
256
|
+
date: utcDate,
|
|
257
|
+
config: siteConfig
|
|
258
|
+
}
|
|
259
|
+
let parsedPrograms = siteConfig.parser(parserContext)
|
|
260
|
+
|
|
261
|
+
if (isPromise(parsedPrograms)) {
|
|
262
|
+
parsedPrograms = await parsedPrograms
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const programs = await EPGGrabber.parseParserResults(
|
|
266
|
+
parsedPrograms as SiteConfigParserResult[],
|
|
267
|
+
channel
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
callback({ channel, date: utcDate, programs }, null)
|
|
271
|
+
|
|
272
|
+
return programs
|
|
273
|
+
} catch (error: unknown) {
|
|
274
|
+
this.logger.debug(`Error: ${JSON.stringify(error, null, 2)}`)
|
|
275
|
+
|
|
276
|
+
callback({ channel, date: utcDate, programs: [] }, error as Error)
|
|
277
|
+
|
|
278
|
+
return []
|
|
279
|
+
}
|
|
220
280
|
}
|
|
221
281
|
}
|
package/src/types/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface SiteConfigObject {
|
|
|
25
25
|
debug?: boolean
|
|
26
26
|
output?: string
|
|
27
27
|
channels?: string | string[]
|
|
28
|
-
request?:
|
|
28
|
+
request?: SiteConfigRequestConfig
|
|
29
29
|
logo?: ((context: SiteConfigRequestContext) => string | Promise<string>) | string
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ export type SiteConfigRequestConfigData =
|
|
|
39
39
|
| Record<string, unknown>
|
|
40
40
|
| null
|
|
41
41
|
|
|
42
|
-
export
|
|
42
|
+
export type SiteConfigRequestConfig = Omit<CacheRequestConfig, 'headers' | 'data'> & {
|
|
43
43
|
data?:
|
|
44
44
|
| ((
|
|
45
45
|
context: SiteConfigRequestContext
|
package/src/types/utils.d.ts
CHANGED
package/tests/core/utils.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { escapeString, parseProxy, sleep } from '../../src/core/utils'
|
|
1
|
+
import { escapeString, getUTCDate, parseProxy, sleep } from '../../src/core/utils'
|
|
2
2
|
import { it, expect, describe, test, vi } from 'vitest'
|
|
3
|
+
import dayjs from 'dayjs'
|
|
3
4
|
|
|
4
5
|
describe('sleep()', () => {
|
|
5
6
|
it('can be skiped during test', async () => {
|
|
@@ -32,3 +33,10 @@ test('parseProxy()', () => {
|
|
|
32
33
|
protocol: 'socks'
|
|
33
34
|
})
|
|
34
35
|
})
|
|
36
|
+
|
|
37
|
+
describe('getUTCDate()', () => {
|
|
38
|
+
it('return original value if it is already UTC date', () => {
|
|
39
|
+
const date = dayjs.utc('2022-10-20')
|
|
40
|
+
expect(getUTCDate(date).toJSON()).toBe('2022-10-20T00:00:00.000Z')
|
|
41
|
+
})
|
|
42
|
+
})
|