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 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-_okTrZbD.js';
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(proxy) {
18
- const parsed = new URL(proxy);
19
- const result = {
20
- protocol: parsed.protocol.replace(":", "") || null,
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) : null
22
+ port: parsed.port ? parseInt(parsed.port) : 8080
23
23
  };
24
24
  if (parsed.username || parsed.password) {
25
- result.auth = {};
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 result;
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 = null) {
51
- if (typeof date === "string") return dayjs.utc(date).startOf("d");
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.43.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
- return [];
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?: Omit<CacheRequestConfig, 'headers' | 'data'> & SiteConfigRequestConfig
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
- interface SiteConfigRequestConfig {
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-_okTrZbD.js';
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.43.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 { ProxyParserResult, XMLElement } from '../types/utils'
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(proxy: string): ProxyParserResult {
10
- const parsed = new URL(proxy)
10
+ export function parseProxy(string: string): AxiosProxyConfig {
11
+ const parsed = new URL(string)
11
12
 
12
- const result: ProxyParserResult = {
13
- protocol: parsed.protocol.replace(':', '') || null,
13
+ const proxy: AxiosProxyConfig = {
14
+ protocol: parsed.protocol.replace(':', ''),
14
15
  host: parsed.hostname,
15
- port: parsed.port ? parseInt(parsed.port) : null
16
+ port: parsed.port ? parseInt(parsed.port) : 8080
16
17
  }
17
18
 
18
19
  if (parsed.username || parsed.password) {
19
- result.auth = {}
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 result
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: string | number | Date | Dayjs | null = null) {
54
- if (typeof date === 'string') return dayjs.utc(date).startOf('d')
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
- return []
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
  }
@@ -3,3 +3,4 @@ export * from 'client'
3
3
  export * from 'grab'
4
4
  export * from 'program'
5
5
  export * from 'siteConfig'
6
+ export * from 'utils'
@@ -25,7 +25,7 @@ export interface SiteConfigObject {
25
25
  debug?: boolean
26
26
  output?: string
27
27
  channels?: string | string[]
28
- request?: Omit<CacheRequestConfig, 'headers' | 'data'> & SiteConfigRequestConfig
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 interface SiteConfigRequestConfig {
42
+ export type SiteConfigRequestConfig = Omit<CacheRequestConfig, 'headers' | 'data'> & {
43
43
  data?:
44
44
  | ((
45
45
  context: SiteConfigRequestContext
@@ -1,13 +1,3 @@
1
- export interface ProxyParserResult {
2
- protocol: string | null
3
- host: string
4
- port: number | null
5
- auth?: {
6
- username?: string
7
- password?: string
8
- }
9
- }
10
-
11
1
  export type XMLElement =
12
2
  | string
13
3
  | number
@@ -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
+ })