diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index c4f65cd0..00000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "env": {
- "node": true,
- "es2021": true,
- "jest": true
- },
- "extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/recommended",
- "prettier"
- ],
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "ecmaVersion": "latest",
- "sourceType": "module"
- },
- "plugins": [
- "@typescript-eslint"
- ],
- "rules": {
- "@typescript-eslint/no-var-requires": "off",
- "no-case-declarations": "off",
- "linebreak-style": [
- "error",
- "windows"
- ],
- "quotes": [
- "error",
- "single",
- {
- "avoidEscape": true
- }
- ],
- "semi": [
- "error",
- "never"
- ]
- }
-}
\ No newline at end of file
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
new file mode 100644
index 00000000..a8d8f70c
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,42 @@
+name: check
+on:
+ workflow_dispatch:
+ pull_request:
+ types: [opened, synchronize, reopened, edited]
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+ - uses: tj-actions/changed-files@v45
+ id: files
+ with:
+ since_last_remote_commit: true
+ files_yaml: |
+ js:
+ - tests/**/*.{js,ts}
+ - scripts/**/*.{js,ts}
+ - sites/**/*.{js,ts}
+ channels:
+ - sites/**/*.channels.xml
+ - uses: actions/setup-node@v4
+ if: ${{ !env.ACT && (steps.files.outputs.js_any_changed == 'true' || steps.files.outputs.channels_any_changed == 'true') }}
+ with:
+ node-version: 22
+ cache: 'npm'
+ - name: install dependencies
+ if: steps.files.outputs.js_any_changed == 'true' || steps.files.outputs.channels_any_changed == 'true'
+ run: SKIP_POSTINSTALL=1 npm install
+ - name: check changed js-files
+ if: steps.files.outputs.js_any_changed == 'true'
+ run: |
+ npx eslint ${{ steps.files.outputs.js_all_changed_files }}
+ - name: check changed *.channels.xml
+ if: steps.files.outputs.channels_any_changed == 'true'
+ run: |
+ npm run channels:lint -- ${{ steps.files.outputs.channels_all_changed_files }}
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 00000000..3c60e992
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,2 @@
+npm run lint
+npm run channels:lint
diff --git a/.prettierrc.js b/.prettierrc.js
index 56f939b5..ed373a0f 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -1,7 +1,7 @@
module.exports = {
tabWidth: 2,
useTabs: false,
- endOfLine: 'lf',
+ endOfLine: 'crlf',
semi: false,
singleQuote: true,
printWidth: 100,
diff --git a/.sites/.gitignore b/.sites/.gitignore
new file mode 100644
index 00000000..3eab715b
--- /dev/null
+++ b/.sites/.gitignore
@@ -0,0 +1 @@
+_table.md
\ No newline at end of file
diff --git a/.sites/_table.md b/.sites/_table.md
deleted file mode 100644
index 9eac21dc..00000000
--- a/.sites/_table.md
+++ /dev/null
@@ -1,207 +0,0 @@
-
\ No newline at end of file
diff --git a/.sites/template.md b/.sites/template.md
index aa2746bf..0f16f542 100644
--- a/.sites/template.md
+++ b/.sites/template.md
@@ -1,4 +1,4 @@
-# Sites
-
-
-#include "./.sites/_table.md"
+# Sites
+
+
+#include "./.sites/_table.md"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 35ba2356..3aa8d2b0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -147,6 +147,7 @@ For scripts to work, you must have [Node.js](https://nodejs.org/en) installed on
To run scripts use the `npm run ` command.
+- `act:check`: allows to test the [check](https://github.com/iptv-org/iptv/blob/master/.github/workflows/check.yml) workflow locally. Depends on [nektos/act](https://github.com/nektos/act).
- `act:update`: allows to test the [update](https://github.com/iptv-org/iptv/blob/master/.github/workflows/update.yml) workflow locally. Depends on [nektos/act](https://github.com/nektos/act).
- `api:load`: downloads the latest channels data from the [iptv-org/api](https://github.com/iptv-org/api).
- `api:generate`: generates a JSON file with all channels for the [iptv-org/api](https://github.com/iptv-org/api) repository.
diff --git a/SITES.md b/SITES.md
index a3fdf3f0..d8a12a97 100644
--- a/SITES.md
+++ b/SITES.md
@@ -1,212 +1,215 @@
-# Sites
-
-
-
+# Sites
+
+
+
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 00000000..49931f5b
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,52 @@
+import typescriptEslint from '@typescript-eslint/eslint-plugin'
+import globals from 'globals'
+import tsParser from '@typescript-eslint/parser'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+import js from '@eslint/js'
+import { FlatCompat } from '@eslint/eslintrc'
+
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = path.dirname(__filename)
+const compat = new FlatCompat({
+ baseDirectory: __dirname,
+ recommendedConfig: js.configs.recommended,
+ allConfig: js.configs.all
+})
+
+export default [
+ ...compat.extends('eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'),
+ {
+ plugins: {
+ '@typescript-eslint': typescriptEslint
+ },
+
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest
+ },
+
+ parser: tsParser,
+ ecmaVersion: 'latest',
+ sourceType: 'module'
+ },
+
+ rules: {
+ '@typescript-eslint/no-require-imports': 'off',
+ '@typescript-eslint/no-var-requires': 'off',
+ 'no-case-declarations': 'off',
+ 'linebreak-style': ['error', 'windows'],
+
+ quotes: [
+ 'error',
+ 'single',
+ {
+ avoidEscape: true
+ }
+ ],
+
+ semi: ['error', 'never']
+ }
+ }
+]
diff --git a/package-lock.json b/package-lock.json
index 962e3af2..e2d2fc50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,11 +9,15 @@
"license": "UNLICENSED",
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
+ "@eslint/eslintrc": "^3.2.0",
+ "@eslint/js": "^9.17.0",
"@freearhey/core": "^0.3.1",
"@freearhey/search-js": "^0.1.1",
"@ntlab/sfetch": "^1.0.0",
"@octokit/plugin-paginate-rest": "^11.3.6",
"@octokit/plugin-rest-endpoint-methods": "^13.2.6",
+ "@swc/core": "^1.10.4",
+ "@swc/jest": "^0.2.37",
"@types/cli-progress": "^3.11.3",
"@types/fs-extra": "^11.0.2",
"@types/inquirer": "^9.0.3",
@@ -39,9 +43,12 @@
"form-data": "^4.0.0",
"fs-extra": "^10.0.1",
"glob": "^7.2.0",
+ "globals": "^15.14.0",
+ "husky": "^9.1.7",
"iconv-lite": "^0.4.24",
"inquirer": "^8.2.6",
"jest": "^29.7.0",
+ "jest-offline": "^1.0.1",
"langs": "^2.0.0",
"libxmljs2": "^0.35.0",
"lodash": "^4.17.21",
@@ -58,12 +65,12 @@
"run-script-os": "^1.1.6",
"serve": "^14.2.4",
"signale": "^1.4.0",
+ "skip-postinstall": "^1.0.0",
"srcset": "^4.0.0",
"table2array": "^0.0.2",
"tabletojson": "^2.0.7",
"tough-cookie": "^5.0.0",
"transliteration": "^2.2.0",
- "ts-jest": "^29.1.1",
"tsx": "^4.19.2",
"unzipit": "^1.4.0",
"wildcard-match": "^5.1.2"
@@ -639,6 +646,14 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/types": {
"version": "7.23.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz",
@@ -1508,6 +1523,17 @@
}
}
},
+ "node_modules/@jest/create-cache-key-function": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+ "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
+ "dependencies": {
+ "@jest/types": "^29.6.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/@jest/environment": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
@@ -2246,6 +2272,222 @@
"@sinonjs/commons": "^3.0.0"
}
},
+ "node_modules/@swc/core": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.4.tgz",
+ "integrity": "sha512-ut3zfiTLORMxhr6y/GBxkHmzcGuVpwJYX4qyXWuBKkpw/0g0S5iO1/wW7RnLnZbAi8wS/n0atRZoaZlXWBkeJg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.17"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.10.4",
+ "@swc/core-darwin-x64": "1.10.4",
+ "@swc/core-linux-arm-gnueabihf": "1.10.4",
+ "@swc/core-linux-arm64-gnu": "1.10.4",
+ "@swc/core-linux-arm64-musl": "1.10.4",
+ "@swc/core-linux-x64-gnu": "1.10.4",
+ "@swc/core-linux-x64-musl": "1.10.4",
+ "@swc/core-win32-arm64-msvc": "1.10.4",
+ "@swc/core-win32-ia32-msvc": "1.10.4",
+ "@swc/core-win32-x64-msvc": "1.10.4"
+ },
+ "peerDependencies": {
+ "@swc/helpers": "*"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.4.tgz",
+ "integrity": "sha512-sV/eurLhkjn/197y48bxKP19oqcLydSel42Qsy2zepBltqUx+/zZ8+/IS0Bi7kaWVFxerbW1IPB09uq8Zuvm3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.4.tgz",
+ "integrity": "sha512-gjYNU6vrAUO4+FuovEo9ofnVosTFXkF0VDuo1MKPItz6e2pxc2ale4FGzLw0Nf7JB1sX4a8h06CN16/pLJ8Q2w==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.4.tgz",
+ "integrity": "sha512-zd7fXH5w8s+Sfvn2oO464KDWl+ZX1MJiVmE4Pdk46N3PEaNwE0koTfgx2vQRqRG4vBBobzVvzICC3618WcefOA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.4.tgz",
+ "integrity": "sha512-+UGfoHDxsMZgFD3tABKLeEZHqLNOkxStu+qCG7atGBhS4Slri6h6zijVvf4yI5X3kbXdvc44XV/hrP/Klnui2A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.4.tgz",
+ "integrity": "sha512-cDDj2/uYsOH0pgAnDkovLZvKJpFmBMyXkxEG6Q4yw99HbzO6QzZ5HDGWGWVq/6dLgYKlnnmpjZCPPQIu01mXEg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.4.tgz",
+ "integrity": "sha512-qJXh9D6Kf5xSdGWPINpLGixAbB5JX8JcbEJpRamhlDBoOcQC79dYfOMEIxWPhTS1DGLyFakAx2FX/b2VmQmj0g==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.4.tgz",
+ "integrity": "sha512-A76lIAeyQnHCVt0RL/pG+0er8Qk9+acGJqSZOZm67Ve3B0oqMd871kPtaHBM0BW3OZAhoILgfHW3Op9Q3mx3Cw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.4.tgz",
+ "integrity": "sha512-e6j5kBu4fIY7fFxFxnZI0MlEovRvp50Lg59Fw+DVbtqHk3C85dckcy5xKP+UoXeuEmFceauQDczUcGs19SRGSQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.4.tgz",
+ "integrity": "sha512-RSYHfdKgNXV/amY5Tqk1EWVsyQnhlsM//jeqMLw5Fy9rfxP592W9UTumNikNRPdjI8wKKzNMXDb1U29tQjN0dg==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.4.tgz",
+ "integrity": "sha512-1ujYpaqfqNPYdwKBlvJnOqcl+Syn3UrQ4XE0Txz6zMYgyh6cdU6a3pxqLqIUSJ12MtXRA9ZUhEz1ekU3LfLWXw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+ },
+ "node_modules/@swc/jest": {
+ "version": "0.2.37",
+ "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.37.tgz",
+ "integrity": "sha512-CR2BHhmXKGxTiFr21DYPRHQunLkX3mNIFGFkxBGji6r9uyIR5zftTOVYj1e0sFNMV2H7mf/+vpaglqaryBtqfQ==",
+ "dependencies": {
+ "@jest/create-cache-key-function": "^29.7.0",
+ "@swc/counter": "^0.1.3",
+ "jsonc-parser": "^3.2.0"
+ },
+ "engines": {
+ "npm": ">= 7.0.0"
+ },
+ "peerDependencies": {
+ "@swc/core": "*"
+ }
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
+ "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
"node_modules/@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
@@ -3326,17 +3568,6 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
- "node_modules/bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "dependencies": {
- "fast-json-stable-stringify": "2.x"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@@ -5262,11 +5493,14 @@
}
},
"node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "version": "15.14.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
+ "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==",
"engines": {
- "node": ">=4"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/got": {
@@ -5417,6 +5651,20 @@
"node": ">=10.17.0"
}
},
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -6209,6 +6457,14 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/jest-offline": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/jest-offline/-/jest-offline-1.0.1.tgz",
+ "integrity": "sha512-pcYJ8rVxWP3SS9de15iSQY87ErLGGgMC4qtVcRLb/qemrefI1IgnAzOusp0eemGu7JoAGlb4oBGnZorehu95KA==",
+ "dependencies": {
+ "mitm": "^1.3.2"
+ }
+ },
"node_modules/jest-pnp-resolver": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
@@ -6562,6 +6818,11 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="
+ },
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -6721,11 +6982,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "node_modules/lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
- },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -6796,7 +7052,9 @@
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "optional": true,
+ "peer": true
},
"node_modules/make-fetch-happen": {
"version": "13.0.1",
@@ -7083,6 +7341,25 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
+ "node_modules/mitm": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/mitm/-/mitm-1.7.3.tgz",
+ "integrity": "sha512-linie/mGisDH73C7aiW6JmstA5XskXd15JBJAEeNQBdH3/L0dJdE/yZ+rw/y2zT7Fcib5KAnL5OvxYOOFQbsgw==",
+ "dependencies": {
+ "semver": ">= 5 < 6"
+ },
+ "engines": {
+ "node": ">= 0.10.24"
+ }
+ },
+ "node_modules/mitm/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -8910,6 +9187,15 @@
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
},
+ "node_modules/skip-postinstall": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/skip-postinstall/-/skip-postinstall-1.0.0.tgz",
+ "integrity": "sha512-IUVEmm4v7Ubzrp9JDG15oTzMB+abJdHcduXMRzBlHnHRrmpQ/QoPtYCRaorP+abAULTGEh87gPPyyMK5H1X1Dg==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+ "bin": {
+ "skip-postinstall": "index.js"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -9406,86 +9692,6 @@
"typescript": ">=4.2.0"
}
},
- "node_modules/ts-jest": {
- "version": "29.1.1",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz",
- "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==",
- "dependencies": {
- "bs-logger": "0.x",
- "fast-json-stable-stringify": "2.x",
- "jest-util": "^29.0.0",
- "json5": "^2.2.3",
- "lodash.memoize": "4.x",
- "make-error": "1.x",
- "semver": "^7.5.3",
- "yargs-parser": "^21.0.1"
- },
- "bin": {
- "ts-jest": "cli.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- },
- "peerDependencies": {
- "@babel/core": ">=7.0.0-beta.0 <8",
- "@jest/types": "^29.0.0",
- "babel-jest": "^29.0.0",
- "jest": "^29.0.0",
- "typescript": ">=4.3 <6"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@jest/types": {
- "optional": true
- },
- "babel-jest": {
- "optional": true
- },
- "esbuild": {
- "optional": true
- }
- }
- },
- "node_modules/ts-jest/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ts-jest/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ts-jest/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
- "node_modules/ts-jest/node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
@@ -10484,6 +10690,13 @@
"@babel/types": "^7.23.3",
"debug": "^4.1.0",
"globals": "^11.1.0"
+ },
+ "dependencies": {
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ }
}
},
"@babel/types": {
@@ -10994,6 +11207,14 @@
"strip-ansi": "^6.0.0"
}
},
+ "@jest/create-cache-key-function": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+ "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
+ "requires": {
+ "@jest/types": "^29.6.3"
+ }
+ },
"@jest/environment": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
@@ -11591,6 +11812,108 @@
"@sinonjs/commons": "^3.0.0"
}
},
+ "@swc/core": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.4.tgz",
+ "integrity": "sha512-ut3zfiTLORMxhr6y/GBxkHmzcGuVpwJYX4qyXWuBKkpw/0g0S5iO1/wW7RnLnZbAi8wS/n0atRZoaZlXWBkeJg==",
+ "requires": {
+ "@swc/core-darwin-arm64": "1.10.4",
+ "@swc/core-darwin-x64": "1.10.4",
+ "@swc/core-linux-arm-gnueabihf": "1.10.4",
+ "@swc/core-linux-arm64-gnu": "1.10.4",
+ "@swc/core-linux-arm64-musl": "1.10.4",
+ "@swc/core-linux-x64-gnu": "1.10.4",
+ "@swc/core-linux-x64-musl": "1.10.4",
+ "@swc/core-win32-arm64-msvc": "1.10.4",
+ "@swc/core-win32-ia32-msvc": "1.10.4",
+ "@swc/core-win32-x64-msvc": "1.10.4",
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.17"
+ }
+ },
+ "@swc/core-darwin-arm64": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.4.tgz",
+ "integrity": "sha512-sV/eurLhkjn/197y48bxKP19oqcLydSel42Qsy2zepBltqUx+/zZ8+/IS0Bi7kaWVFxerbW1IPB09uq8Zuvm3g==",
+ "optional": true
+ },
+ "@swc/core-darwin-x64": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.4.tgz",
+ "integrity": "sha512-gjYNU6vrAUO4+FuovEo9ofnVosTFXkF0VDuo1MKPItz6e2pxc2ale4FGzLw0Nf7JB1sX4a8h06CN16/pLJ8Q2w==",
+ "optional": true
+ },
+ "@swc/core-linux-arm-gnueabihf": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.4.tgz",
+ "integrity": "sha512-zd7fXH5w8s+Sfvn2oO464KDWl+ZX1MJiVmE4Pdk46N3PEaNwE0koTfgx2vQRqRG4vBBobzVvzICC3618WcefOA==",
+ "optional": true
+ },
+ "@swc/core-linux-arm64-gnu": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.4.tgz",
+ "integrity": "sha512-+UGfoHDxsMZgFD3tABKLeEZHqLNOkxStu+qCG7atGBhS4Slri6h6zijVvf4yI5X3kbXdvc44XV/hrP/Klnui2A==",
+ "optional": true
+ },
+ "@swc/core-linux-arm64-musl": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.4.tgz",
+ "integrity": "sha512-cDDj2/uYsOH0pgAnDkovLZvKJpFmBMyXkxEG6Q4yw99HbzO6QzZ5HDGWGWVq/6dLgYKlnnmpjZCPPQIu01mXEg==",
+ "optional": true
+ },
+ "@swc/core-linux-x64-gnu": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.4.tgz",
+ "integrity": "sha512-qJXh9D6Kf5xSdGWPINpLGixAbB5JX8JcbEJpRamhlDBoOcQC79dYfOMEIxWPhTS1DGLyFakAx2FX/b2VmQmj0g==",
+ "optional": true
+ },
+ "@swc/core-linux-x64-musl": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.4.tgz",
+ "integrity": "sha512-A76lIAeyQnHCVt0RL/pG+0er8Qk9+acGJqSZOZm67Ve3B0oqMd871kPtaHBM0BW3OZAhoILgfHW3Op9Q3mx3Cw==",
+ "optional": true
+ },
+ "@swc/core-win32-arm64-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.4.tgz",
+ "integrity": "sha512-e6j5kBu4fIY7fFxFxnZI0MlEovRvp50Lg59Fw+DVbtqHk3C85dckcy5xKP+UoXeuEmFceauQDczUcGs19SRGSQ==",
+ "optional": true
+ },
+ "@swc/core-win32-ia32-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.4.tgz",
+ "integrity": "sha512-RSYHfdKgNXV/amY5Tqk1EWVsyQnhlsM//jeqMLw5Fy9rfxP592W9UTumNikNRPdjI8wKKzNMXDb1U29tQjN0dg==",
+ "optional": true
+ },
+ "@swc/core-win32-x64-msvc": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.4.tgz",
+ "integrity": "sha512-1ujYpaqfqNPYdwKBlvJnOqcl+Syn3UrQ4XE0Txz6zMYgyh6cdU6a3pxqLqIUSJ12MtXRA9ZUhEz1ekU3LfLWXw==",
+ "optional": true
+ },
+ "@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+ },
+ "@swc/jest": {
+ "version": "0.2.37",
+ "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.37.tgz",
+ "integrity": "sha512-CR2BHhmXKGxTiFr21DYPRHQunLkX3mNIFGFkxBGji6r9uyIR5zftTOVYj1e0sFNMV2H7mf/+vpaglqaryBtqfQ==",
+ "requires": {
+ "@jest/create-cache-key-function": "^29.7.0",
+ "@swc/counter": "^0.1.3",
+ "jsonc-parser": "^3.2.0"
+ }
+ },
+ "@swc/types": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
+ "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
+ "requires": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
"@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
@@ -12372,14 +12695,6 @@
"update-browserslist-db": "^1.0.11"
}
},
- "bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "requires": {
- "fast-json-stable-stringify": "2.x"
- }
- },
"bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@@ -13782,9 +14097,9 @@
}
},
"globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ "version": "15.14.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
+ "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig=="
},
"got": {
"version": "11.8.5",
@@ -13888,6 +14203,11 @@
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
},
+ "husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="
+ },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -14438,6 +14758,14 @@
"jest-util": "^29.7.0"
}
},
+ "jest-offline": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/jest-offline/-/jest-offline-1.0.1.tgz",
+ "integrity": "sha512-pcYJ8rVxWP3SS9de15iSQY87ErLGGgMC4qtVcRLb/qemrefI1IgnAzOusp0eemGu7JoAGlb4oBGnZorehu95KA==",
+ "requires": {
+ "mitm": "^1.3.2"
+ }
+ },
"jest-pnp-resolver": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
@@ -14721,6 +15049,11 @@
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
+ "jsonc-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="
+ },
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -14849,11 +15182,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
- },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -14908,7 +15236,9 @@
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "optional": true,
+ "peer": true
},
"make-fetch-happen": {
"version": "13.0.1",
@@ -15138,6 +15468,21 @@
}
}
},
+ "mitm": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/mitm/-/mitm-1.7.3.tgz",
+ "integrity": "sha512-linie/mGisDH73C7aiW6JmstA5XskXd15JBJAEeNQBdH3/L0dJdE/yZ+rw/y2zT7Fcib5KAnL5OvxYOOFQbsgw==",
+ "requires": {
+ "semver": ">= 5 < 6"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
+ }
+ }
+ },
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -16465,6 +16810,11 @@
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
},
+ "skip-postinstall": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/skip-postinstall/-/skip-postinstall-1.0.0.tgz",
+ "integrity": "sha512-IUVEmm4v7Ubzrp9JDG15oTzMB+abJdHcduXMRzBlHnHRrmpQ/QoPtYCRaorP+abAULTGEh87gPPyyMK5H1X1Dg=="
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -16818,49 +17168,6 @@
"integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
"requires": {}
},
- "ts-jest": {
- "version": "29.1.1",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz",
- "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==",
- "requires": {
- "bs-logger": "0.x",
- "fast-json-stable-stringify": "2.x",
- "jest-util": "^29.0.0",
- "json5": "^2.2.3",
- "lodash.memoize": "4.x",
- "make-error": "1.x",
- "semver": "^7.5.3",
- "yargs-parser": "^21.0.1"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
- "yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
- }
- }
- },
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
diff --git a/package.json b/package.json
index 77685b4d..01277e4d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,7 @@
{
"name": "epg",
"scripts": {
+ "act:check": "act pull_request -W .github/workflows/check.yml",
"act:update": "act workflow_dispatch -W .github/workflows/update.yml",
"api:load": "npx tsx scripts/commands/api/load.ts",
"api:generate": "npx tsx scripts/commands/api/generate.ts",
@@ -10,29 +11,37 @@
"channels:validate": "npx tsx scripts/commands/channels/validate.ts",
"sites:update": "npx tsx scripts/commands/sites/update.ts",
"grab": "npx tsx scripts/commands/epg/grab.ts",
- "lint": "npx eslint \"{scripts,tests}/**/*.{ts,js}\"",
+ "lint": "npx eslint \"{scripts,tests,sites}/**/*.{ts,js}\"",
"test": "run-script-os",
"test:win32": "SET \"TZ=Pacific/Nauru\" && npx jest --runInBand",
"test:default": "TZ=Pacific/Nauru npx jest --runInBand",
- "postinstall": "npm run api:load"
+ "postinstall": "skip-postinstall || npm run api:load",
+ "prepare": "husky"
},
"private": true,
"author": "Arhey",
"license": "UNLICENSED",
"jest": {
+ "setupFiles": [
+ "/node_modules/jest-offline"
+ ],
"transform": {
- "^.+\\.(ts|js)$": "ts-jest"
+ "^.+\\.(ts|js)$": "@swc/jest"
},
"testRegex": "(tests|sites)/(.*?/)?.*test.(js|ts)$",
"testTimeout": 10000
},
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
+ "@eslint/eslintrc": "^3.2.0",
+ "@eslint/js": "^9.17.0",
"@freearhey/core": "^0.3.1",
"@freearhey/search-js": "^0.1.1",
"@ntlab/sfetch": "^1.0.0",
"@octokit/plugin-paginate-rest": "^11.3.6",
"@octokit/plugin-rest-endpoint-methods": "^13.2.6",
+ "@swc/core": "^1.10.4",
+ "@swc/jest": "^0.2.37",
"@types/cli-progress": "^3.11.3",
"@types/fs-extra": "^11.0.2",
"@types/inquirer": "^9.0.3",
@@ -58,9 +67,12 @@
"form-data": "^4.0.0",
"fs-extra": "^10.0.1",
"glob": "^7.2.0",
+ "globals": "^15.14.0",
+ "husky": "^9.1.7",
"iconv-lite": "^0.4.24",
"inquirer": "^8.2.6",
"jest": "^29.7.0",
+ "jest-offline": "^1.0.1",
"langs": "^2.0.0",
"libxmljs2": "^0.35.0",
"lodash": "^4.17.21",
@@ -77,12 +89,12 @@
"run-script-os": "^1.1.6",
"serve": "^14.2.4",
"signale": "^1.4.0",
+ "skip-postinstall": "^1.0.0",
"srcset": "^4.0.0",
"table2array": "^0.0.2",
"tabletojson": "^2.0.7",
"tough-cookie": "^5.0.0",
"transliteration": "^2.2.0",
- "ts-jest": "^29.1.1",
"tsx": "^4.19.2",
"unzipit": "^1.4.0",
"wildcard-match": "^5.1.2"
diff --git a/scripts/commands/api/generate.ts b/scripts/commands/api/generate.ts
index 7b0f8276..43634f8c 100644
--- a/scripts/commands/api/generate.ts
+++ b/scripts/commands/api/generate.ts
@@ -1,51 +1,51 @@
-import { Logger, Storage, Collection } from '@freearhey/core'
-import { ChannelsParser } from '../../core'
-import path from 'path'
-import { SITES_DIR, API_DIR } from '../../constants'
-import { Channel } from 'epg-grabber'
-
-type OutputItem = {
- channel: string | null
- site: string
- site_id: string
- site_name: string
- lang: string
-}
-
-async function main() {
- const logger = new Logger()
-
- logger.start('staring...')
-
- logger.info('loading channels...')
- const sitesStorage = new Storage(SITES_DIR)
- const parser = new ChannelsParser({ storage: sitesStorage })
-
- let files: string[] = []
- files = await sitesStorage.list('**/*.channels.xml')
-
- let parsedChannels = new Collection()
- for (const filepath of files) {
- parsedChannels = parsedChannels.concat(await parser.parse(filepath))
- }
-
- logger.info(` found ${parsedChannels.count()} channel(s)`)
-
- const output = parsedChannels.map((channel: Channel): OutputItem => {
- return {
- channel: channel.xmltv_id || null,
- site: channel.site || '',
- site_id: channel.site_id || '',
- site_name: channel.name,
- lang: channel.lang || ''
- }
- })
-
- const apiStorage = new Storage(API_DIR)
- const outputFilename = 'guides.json'
- await apiStorage.save('guides.json', output.toJSON())
-
- logger.info(`saved to "${path.join(API_DIR, outputFilename)}"`)
-}
-
-main()
+import { Logger, Storage, Collection } from '@freearhey/core'
+import { ChannelsParser } from '../../core'
+import path from 'path'
+import { SITES_DIR, API_DIR } from '../../constants'
+import { Channel } from 'epg-grabber'
+
+type OutputItem = {
+ channel: string | null
+ site: string
+ site_id: string
+ site_name: string
+ lang: string
+}
+
+async function main() {
+ const logger = new Logger()
+
+ logger.start('staring...')
+
+ logger.info('loading channels...')
+ const sitesStorage = new Storage(SITES_DIR)
+ const parser = new ChannelsParser({ storage: sitesStorage })
+
+ let files: string[] = []
+ files = await sitesStorage.list('**/*.channels.xml')
+
+ let parsedChannels = new Collection()
+ for (const filepath of files) {
+ parsedChannels = parsedChannels.concat(await parser.parse(filepath))
+ }
+
+ logger.info(` found ${parsedChannels.count()} channel(s)`)
+
+ const output = parsedChannels.map((channel: Channel): OutputItem => {
+ return {
+ channel: channel.xmltv_id || null,
+ site: channel.site || '',
+ site_id: channel.site_id || '',
+ site_name: channel.name,
+ lang: channel.lang || ''
+ }
+ })
+
+ const apiStorage = new Storage(API_DIR)
+ const outputFilename = 'guides.json'
+ await apiStorage.save('guides.json', output.toJSON())
+
+ logger.info(`saved to "${path.join(API_DIR, outputFilename)}"`)
+}
+
+main()
diff --git a/scripts/commands/channels/editor.ts b/scripts/commands/channels/editor.ts
index 33058192..0898cbff 100644
--- a/scripts/commands/channels/editor.ts
+++ b/scripts/commands/channels/editor.ts
@@ -43,7 +43,7 @@ async function main() {
const channelsIndex = sj.createIndex(channelsContent)
const buffer = new Dictionary()
- for (let option of options.all()) {
+ for (const option of options.all()) {
const channel: Channel = option.channel
if (channel.xmltv_id) {
if (channel.xmltv_id !== '-') {
@@ -150,7 +150,7 @@ function getOptions(channelsIndex, channel: Channel) {
const query = channel.name
.replace(/\s(SD|TV|HD|SD\/HD|HDTV)$/i, '')
.replace(/(\(|\)|,)/gi, '')
- .replace(/\-/gi, ' ')
+ .replace(/-/gi, ' ')
.replace(/\+/gi, '')
const similar = channelsIndex.search(query).map(item => new ApiChannel(item))
diff --git a/scripts/commands/channels/lint.ts b/scripts/commands/channels/lint.ts
index 37c6b646..c865d7f6 100644
--- a/scripts/commands/channels/lint.ts
+++ b/scripts/commands/channels/lint.ts
@@ -1,7 +1,7 @@
import chalk from 'chalk'
import libxml, { ValidationError } from 'libxmljs2'
import { program } from 'commander'
-import { Logger, Storage, File } from '@freearhey/core'
+import { Storage, File } from '@freearhey/core'
const xsd = `
@@ -23,26 +23,14 @@ const xsd = `
`
-program
- .option(
- '-c, --channels ',
- 'Path to channels.xml file to validate',
- 'sites/**/*.channels.xml'
- )
- .parse(process.argv)
-
-const options = program.opts()
+program.argument('[filepath]', 'Path to *.channels.xml files to validate').parse(process.argv)
async function main() {
- const logger = new Logger()
const storage = new Storage()
- logger.info('options:')
- logger.tree(options)
-
let errors: ValidationError[] = []
- const files: string[] = await storage.list(options.channels)
+ const files = program.args.length ? program.args : await storage.list('sites/**/*.channels.xml')
for (const filepath of files) {
const file = new File(filepath)
if (file.extension() !== 'xml') continue
@@ -51,11 +39,15 @@ async function main() {
let localErrors: ValidationError[] = []
- const xsdDoc = libxml.parseXml(xsd)
- const doc = libxml.parseXml(xml)
+ try {
+ const xsdDoc = libxml.parseXml(xsd)
+ const doc = libxml.parseXml(xml)
- if (!doc.validate(xsdDoc)) {
- localErrors = doc.validationErrors
+ if (!doc.validate(xsdDoc)) {
+ localErrors = doc.validationErrors
+ }
+ } catch (error) {
+ localErrors.push(error)
}
if (localErrors.length) {
diff --git a/scripts/commands/channels/parse.ts b/scripts/commands/channels/parse.ts
index b00d2a26..96c57a52 100644
--- a/scripts/commands/channels/parse.ts
+++ b/scripts/commands/channels/parse.ts
@@ -2,7 +2,7 @@ import { Logger, File, Collection, Storage } from '@freearhey/core'
import { ChannelsParser, XML } from '../../core'
import { Channel } from 'epg-grabber'
import { Command } from 'commander'
-import path from 'path'
+import { pathToFileURL } from 'node:url'
const program = new Command()
program
@@ -26,7 +26,7 @@ async function main() {
const logger = new Logger()
const file = new File(options.config)
const dir = file.dirname()
- const config = require(path.resolve(options.config))
+ const config = (await import(pathToFileURL(options.config))).default
const outputFilepath = options.output || `${dir}/${config.site}.channels.xml`
let channels = new Collection()
diff --git a/scripts/commands/channels/validate.ts b/scripts/commands/channels/validate.ts
index 35ab873b..e2f38429 100644
--- a/scripts/commands/channels/validate.ts
+++ b/scripts/commands/channels/validate.ts
@@ -47,7 +47,6 @@ async function main() {
const parsedChannels = await parser.parse(filepath)
- const bufferById = new Dictionary()
const bufferBySiteId = new Dictionary()
const errors: ValidationError[] = []
parsedChannels.forEach((channel: Channel) => {
diff --git a/scripts/commands/sites/update.ts b/scripts/commands/sites/update.ts
index d1f7e8a4..b9550550 100644
--- a/scripts/commands/sites/update.ts
+++ b/scripts/commands/sites/update.ts
@@ -1,58 +1,58 @@
-import { Logger, Storage, Collection, Dictionary } from '@freearhey/core'
-import { IssueLoader, HTMLTable, Markdown } from '../../core'
-import { Issue, Site } from '../../models'
-import { SITES_DIR, DOT_SITES_DIR } from '../../constants'
-import path from 'path'
-
-async function main() {
- const logger = new Logger({ disabled: true })
- const loader = new IssueLoader()
- const storage = new Storage(SITES_DIR)
- const sites = new Collection()
-
- logger.info('loading list of sites')
- const folders = await storage.list('*/')
-
- logger.info('loading issues...')
- const issues = await loadIssues(loader)
-
- logger.info('putting the data together...')
- folders.forEach((domain: string) => {
- const filteredIssues = issues.filter((issue: Issue) => domain === issue.data.get('site'))
- const site = new Site({
- domain,
- issues: filteredIssues
- })
-
- sites.add(site)
- })
-
- logger.info('creating sites table...')
- let data = new Collection()
- sites.forEach((site: Site) => {
- data.add([
- `${site.domain} `,
- site.getStatus().emoji,
- site.getIssues().all().join(', ')
- ])
- })
-
- const table = new HTMLTable(data.all(), [{ name: 'Site' }, { name: 'Status' }, { name: 'Notes' }])
-
- const readmeStorage = new Storage(DOT_SITES_DIR)
- await readmeStorage.save('_table.md', table.toString())
-
- logger.info('updating sites.md...')
- const configPath = path.join(DOT_SITES_DIR, 'config.json')
- const sitesMarkdown = new Markdown(configPath)
- sitesMarkdown.compile()
-}
-
-main()
-
-async function loadIssues(loader: IssueLoader) {
- const issuesWithStatusWarning = await loader.load({ labels: ['broken guide', 'status:warning'] })
- const issuesWithStatusDown = await loader.load({ labels: ['broken guide', 'status:down'] })
-
- return issuesWithStatusWarning.concat(issuesWithStatusDown)
-}
+import { Logger, Storage, Collection } from '@freearhey/core'
+import { IssueLoader, HTMLTable, Markdown } from '../../core'
+import { Issue, Site } from '../../models'
+import { SITES_DIR, DOT_SITES_DIR } from '../../constants'
+import path from 'path'
+
+async function main() {
+ const logger = new Logger({ disabled: true })
+ const loader = new IssueLoader()
+ const storage = new Storage(SITES_DIR)
+ const sites = new Collection()
+
+ logger.info('loading list of sites')
+ const folders = await storage.list('*/')
+
+ logger.info('loading issues...')
+ const issues = await loadIssues(loader)
+
+ logger.info('putting the data together...')
+ folders.forEach((domain: string) => {
+ const filteredIssues = issues.filter((issue: Issue) => domain === issue.data.get('site'))
+ const site = new Site({
+ domain,
+ issues: filteredIssues
+ })
+
+ sites.add(site)
+ })
+
+ logger.info('creating sites table...')
+ const data = new Collection()
+ sites.forEach((site: Site) => {
+ data.add([
+ `${site.domain} `,
+ site.getStatus().emoji,
+ site.getIssues().all().join(', ')
+ ])
+ })
+
+ const table = new HTMLTable(data.all(), [{ name: 'Site' }, { name: 'Status' }, { name: 'Notes' }])
+
+ const readmeStorage = new Storage(DOT_SITES_DIR)
+ await readmeStorage.save('_table.md', table.toString())
+
+ logger.info('updating sites.md...')
+ const configPath = path.join(DOT_SITES_DIR, 'config.json')
+ const sitesMarkdown = new Markdown(configPath)
+ sitesMarkdown.compile()
+}
+
+main()
+
+async function loadIssues(loader: IssueLoader) {
+ const issuesWithStatusWarning = await loader.load({ labels: ['broken guide', 'status:warning'] })
+ const issuesWithStatusDown = await loader.load({ labels: ['broken guide', 'status:down'] })
+
+ return issuesWithStatusWarning.concat(issuesWithStatusDown)
+}
diff --git a/scripts/core/date.js b/scripts/core/date.js
index 5515a1c4..08c4d938 100644
--- a/scripts/core/date.js
+++ b/scripts/core/date.js
@@ -1,5 +1,6 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
+import dayjs from 'dayjs'
+import utc from 'dayjs/plugin/utc'
+
dayjs.extend(utc)
const date = {}
@@ -10,4 +11,4 @@ date.getUTC = function (d = null) {
return dayjs.utc().startOf('d')
}
-module.exports = date
+export default date
diff --git a/scripts/core/htmlTable.ts b/scripts/core/htmlTable.ts
index 1caa85fa..72d6bd8d 100644
--- a/scripts/core/htmlTable.ts
+++ b/scripts/core/htmlTable.ts
@@ -1,46 +1,46 @@
-type Column = {
- name: string
- nowrap?: boolean
- align?: string
-}
-
-type DataItem = string[]
-
-export class HTMLTable {
- data: DataItem[]
- columns: Column[]
-
- constructor(data: DataItem[], columns: Column[]) {
- this.data = data
- this.columns = columns
- }
-
- toString() {
- let output = '\n'
-
- output += ' \n '
- for (const column of this.columns) {
- output += `${column.name} `
- }
- output += ' \n \n'
-
- output += ' \n'
- for (const item of this.data) {
- output += ' '
- let i = 0
- for (const prop in item) {
- const column = this.columns[i]
- const nowrap = column.nowrap ? ' nowrap' : ''
- const align = column.align ? ` align="${column.align}"` : ''
- output += `${item[prop]} `
- i++
- }
- output += ' \n'
- }
- output += ' \n'
-
- output += '
'
-
- return output
- }
-}
+type Column = {
+ name: string
+ nowrap?: boolean
+ align?: string
+}
+
+type DataItem = string[]
+
+export class HTMLTable {
+ data: DataItem[]
+ columns: Column[]
+
+ constructor(data: DataItem[], columns: Column[]) {
+ this.data = data
+ this.columns = columns
+ }
+
+ toString() {
+ let output = '\r\n'
+
+ output += ' \r\n '
+ for (const column of this.columns) {
+ output += `${column.name} `
+ }
+ output += ' \r\n \r\n'
+
+ output += ' \r\n'
+ for (const item of this.data) {
+ output += ' '
+ let i = 0
+ for (const prop in item) {
+ const column = this.columns[i]
+ const nowrap = column.nowrap ? ' nowrap' : ''
+ const align = column.align ? ` align="${column.align}"` : ''
+ output += `${item[prop]} `
+ i++
+ }
+ output += ' \r\n'
+ }
+ output += ' \r\n'
+
+ output += '
'
+
+ return output
+ }
+}
diff --git a/scripts/core/issueLoader.ts b/scripts/core/issueLoader.ts
index 28697e58..8d9b6479 100644
--- a/scripts/core/issueLoader.ts
+++ b/scripts/core/issueLoader.ts
@@ -1,40 +1,41 @@
-import { Collection } from '@freearhey/core'
-import { restEndpointMethods } from '@octokit/plugin-rest-endpoint-methods'
-import { paginateRest } from '@octokit/plugin-paginate-rest'
-import { Octokit } from '@octokit/core'
-import { IssueParser } from './'
-import { TESTING, OWNER, REPO } from '../constants'
-
-const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
-const octokit = new CustomOctokit()
-
-export class IssueLoader {
- async load({ labels }: { labels: string[] | string }) {
- labels = Array.isArray(labels) ? labels.join(',') : labels
- let issues: object[] = []
- if (TESTING) {
- switch (labels) {
- case 'broken guide,status:warning':
- issues = require('../../tests/__data__/input/issues/broken_guide_warning.js')
- break
- case 'broken guide,status:down':
- issues = require('../../tests/__data__/input/issues/broken_guide_down.js')
- break
- }
- } else {
- issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
- owner: OWNER,
- repo: REPO,
- per_page: 100,
- labels,
- headers: {
- 'X-GitHub-Api-Version': '2022-11-28'
- }
- })
- }
-
- const parser = new IssueParser()
-
- return new Collection(issues).map(parser.parse)
- }
-}
+import { Collection } from '@freearhey/core'
+import { restEndpointMethods } from '@octokit/plugin-rest-endpoint-methods'
+import { paginateRest } from '@octokit/plugin-paginate-rest'
+import { Octokit } from '@octokit/core'
+import { IssueParser } from './'
+import { TESTING, OWNER, REPO } from '../constants'
+
+const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
+const octokit = new CustomOctokit()
+
+export class IssueLoader {
+ async load({ labels }: { labels: string[] | string }) {
+ labels = Array.isArray(labels) ? labels.join(',') : labels
+ let issues: object[] = []
+ if (TESTING) {
+ switch (labels) {
+ case 'broken guide,status:warning':
+ issues = (await import('../../tests/__data__/input/issues/broken_guide_warning.mjs'))
+ .default
+ break
+ case 'broken guide,status:down':
+ issues = (await import('../../tests/__data__/input/issues/broken_guide_down.mjs')).default
+ break
+ }
+ } else {
+ issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
+ owner: OWNER,
+ repo: REPO,
+ per_page: 100,
+ labels,
+ headers: {
+ 'X-GitHub-Api-Version': '2022-11-28'
+ }
+ })
+ }
+
+ const parser = new IssueParser()
+
+ return new Collection(issues).map(parser.parse)
+ }
+}
diff --git a/scripts/core/issueParser.ts b/scripts/core/issueParser.ts
index 2fe2ddd8..e4626514 100644
--- a/scripts/core/issueParser.ts
+++ b/scripts/core/issueParser.ts
@@ -1,34 +1,34 @@
-import { Dictionary } from '@freearhey/core'
-import { Issue } from '../models'
-
-const FIELDS = new Dictionary({
- Site: 'site'
-})
-
-export class IssueParser {
- parse(issue: { number: number; body: string; labels: { name: string }[] }): Issue {
- const fields = issue.body.split('###')
-
- const data = new Dictionary()
- fields.forEach((field: string) => {
- let parsed = field.split(/\r?\n/).filter(Boolean)
- let _label = parsed.shift()
- _label = _label ? _label.trim() : ''
- let _value = parsed.join('\r\n')
- _value = _value ? _value.trim() : ''
-
- if (!_label || !_value) return data
-
- const id: string = FIELDS.get(_label)
- const value: string = _value === '_No response_' || _value === 'None' ? '' : _value
-
- if (!id) return
-
- data.set(id, value)
- })
-
- const labels = issue.labels.map(label => label.name)
-
- return new Issue({ number: issue.number, labels, data })
- }
-}
+import { Dictionary } from '@freearhey/core'
+import { Issue } from '../models'
+
+const FIELDS = new Dictionary({
+ Site: 'site'
+})
+
+export class IssueParser {
+ parse(issue: { number: number; body: string; labels: { name: string }[] }): Issue {
+ const fields = issue.body.split('###')
+
+ const data = new Dictionary()
+ fields.forEach((field: string) => {
+ const parsed = field.split(/\r?\n/).filter(Boolean)
+ let _label = parsed.shift()
+ _label = _label ? _label.trim() : ''
+ let _value = parsed.join('\r\n')
+ _value = _value ? _value.trim() : ''
+
+ if (!_label || !_value) return data
+
+ const id: string = FIELDS.get(_label)
+ const value: string = _value === '_No response_' || _value === 'None' ? '' : _value
+
+ if (!id) return
+
+ data.set(id, value)
+ })
+
+ const labels = issue.labels.map(label => label.name)
+
+ return new Issue({ number: issue.number, labels, data })
+ }
+}
diff --git a/scripts/core/markdown.ts b/scripts/core/markdown.ts
index b43b5608..4efaddb0 100644
--- a/scripts/core/markdown.ts
+++ b/scripts/core/markdown.ts
@@ -1,13 +1,13 @@
-import markdownInclude from 'markdown-include'
-
-export class Markdown {
- filepath: string
-
- constructor(filepath: string) {
- this.filepath = filepath
- }
-
- compile() {
- markdownInclude.compileFiles(this.filepath)
- }
-}
+import markdownInclude from 'markdown-include'
+
+export class Markdown {
+ filepath: string
+
+ constructor(filepath: string) {
+ this.filepath = filepath
+ }
+
+ compile() {
+ markdownInclude.compileFiles(this.filepath)
+ }
+}
diff --git a/scripts/core/queueCreator.ts b/scripts/core/queueCreator.ts
index 8cc9fcb3..2816f57f 100644
--- a/scripts/core/queueCreator.ts
+++ b/scripts/core/queueCreator.ts
@@ -1,7 +1,7 @@
import { Storage, Collection, DateTime, Logger } from '@freearhey/core'
import { ChannelsParser, ConfigLoader, ApiChannel, Queue } from './'
import { SITES_DIR, DATA_DIR } from '../constants'
-import { Channel, SiteConfig } from 'epg-grabber'
+import { SiteConfig } from 'epg-grabber'
import path from 'path'
import { GrabOptions } from '../commands/epg/grab'
diff --git a/scripts/models/index.ts b/scripts/models/index.ts
index 1065611d..f8188a40 100644
--- a/scripts/models/index.ts
+++ b/scripts/models/index.ts
@@ -1,2 +1,2 @@
-export * from './issue'
-export * from './site'
+export * from './issue'
+export * from './site'
diff --git a/scripts/models/issue.ts b/scripts/models/issue.ts
index 7eb241e5..d9653a4f 100644
--- a/scripts/models/issue.ts
+++ b/scripts/models/issue.ts
@@ -1,24 +1,24 @@
-import { Dictionary } from '@freearhey/core'
-import { OWNER, REPO } from '../constants'
-
-type IssueProps = {
- number: number
- labels: string[]
- data: Dictionary
-}
-
-export class Issue {
- number: number
- labels: string[]
- data: Dictionary
-
- constructor({ number, labels, data }: IssueProps) {
- this.number = number
- this.labels = labels
- this.data = data
- }
-
- getURL() {
- return `https://github.com/${OWNER}/${REPO}/issues/${this.number}`
- }
-}
+import { Dictionary } from '@freearhey/core'
+import { OWNER, REPO } from '../constants'
+
+type IssueProps = {
+ number: number
+ labels: string[]
+ data: Dictionary
+}
+
+export class Issue {
+ number: number
+ labels: string[]
+ data: Dictionary
+
+ constructor({ number, labels, data }: IssueProps) {
+ this.number = number
+ this.labels = labels
+ this.data = data
+ }
+
+ getURL() {
+ return `https://github.com/${OWNER}/${REPO}/issues/${this.number}`
+ }
+}
diff --git a/scripts/models/site.ts b/scripts/models/site.ts
index 1e7dcadd..4fd5b33a 100644
--- a/scripts/models/site.ts
+++ b/scripts/models/site.ts
@@ -1,57 +1,57 @@
-import { Collection } from '@freearhey/core'
-import { Issue } from './'
-
-enum StatusCode {
- DOWN = 'down',
- WARNING = 'warning',
- OK = 'ok'
-}
-
-type Status = {
- code: StatusCode
- emoji: string
-}
-
-type SiteProps = {
- domain: string
- issues: Collection
-}
-
-export class Site {
- domain: string
- issues: Collection
-
- constructor({ domain, issues }: SiteProps) {
- this.domain = domain
- this.issues = issues
- }
-
- getStatus(): Status {
- const issuesWithStatusDown = this.issues.filter((issue: Issue) =>
- issue.labels.find(label => label === 'status:down')
- )
- if (issuesWithStatusDown.notEmpty())
- return {
- code: StatusCode.DOWN,
- emoji: '🔴'
- }
-
- const issuesWithStatusWarning = this.issues.filter((issue: Issue) =>
- issue.labels.find(label => label === 'status:warning')
- )
- if (issuesWithStatusWarning.notEmpty())
- return {
- code: StatusCode.WARNING,
- emoji: '🟡'
- }
-
- return {
- code: StatusCode.OK,
- emoji: '🟢'
- }
- }
-
- getIssues(): Collection {
- return this.issues.map((issue: Issue) => issue.getURL())
- }
-}
+import { Collection } from '@freearhey/core'
+import { Issue } from './'
+
+enum StatusCode {
+ DOWN = 'down',
+ WARNING = 'warning',
+ OK = 'ok'
+}
+
+type Status = {
+ code: StatusCode
+ emoji: string
+}
+
+type SiteProps = {
+ domain: string
+ issues: Collection
+}
+
+export class Site {
+ domain: string
+ issues: Collection
+
+ constructor({ domain, issues }: SiteProps) {
+ this.domain = domain
+ this.issues = issues
+ }
+
+ getStatus(): Status {
+ const issuesWithStatusDown = this.issues.filter((issue: Issue) =>
+ issue.labels.find(label => label === 'status:down')
+ )
+ if (issuesWithStatusDown.notEmpty())
+ return {
+ code: StatusCode.DOWN,
+ emoji: '🔴'
+ }
+
+ const issuesWithStatusWarning = this.issues.filter((issue: Issue) =>
+ issue.labels.find(label => label === 'status:warning')
+ )
+ if (issuesWithStatusWarning.notEmpty())
+ return {
+ code: StatusCode.WARNING,
+ emoji: '🟡'
+ }
+
+ return {
+ code: StatusCode.OK,
+ emoji: '🟢'
+ }
+ }
+
+ getIssues(): Collection {
+ return this.issues.map((issue: Issue) => issue.getURL())
+ }
+}
diff --git a/sites/abc.net.au/abc.net.au.config.js b/sites/abc.net.au/abc.net.au.config.js
index 5caa9356..0550574b 100644
--- a/sites/abc.net.au/abc.net.au.config.js
+++ b/sites/abc.net.au/abc.net.au.config.js
@@ -92,7 +92,7 @@ function parseItems(content, channel) {
const [, channelId] = channel.site_id.split('#')
const channelData = data.schedule.find(i => i.channel == channelId)
return channelData.listing && Array.isArray(channelData.listing) ? channelData.listing : []
- } catch (err) {
+ } catch {
return []
}
}
diff --git a/sites/awilime.com/awilime.com.test.js b/sites/awilime.com/awilime.com.test.js
index df3677fe..08da5912 100644
--- a/sites/awilime.com/awilime.com.test.js
+++ b/sites/awilime.com/awilime.com.test.js
@@ -1,4 +1,4 @@
-const { parser, url, request } = require('./awilime.com.config.js')
+const { parser, url } = require('./awilime.com.config.js')
const fs = require('fs')
const path = require('path')
const dayjs = require('dayjs')
diff --git a/sites/beinsports.com/beinsports.com.config.js b/sites/beinsports.com/beinsports.com.config.js
index 4bfae6de..41b6c899 100644
--- a/sites/beinsports.com/beinsports.com.config.js
+++ b/sites/beinsports.com/beinsports.com.config.js
@@ -1,5 +1,4 @@
const axios = require('axios')
-const cheerio = require('cheerio')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
@@ -62,7 +61,7 @@ function parseItems(content) {
let data
try {
data = JSON.parse(content)
- } catch (error) {
+ } catch {
return []
}
diff --git a/sites/beinsports.com/beinsports.com.test.js b/sites/beinsports.com/beinsports.com.test.js
index 7651968e..563c18b1 100644
--- a/sites/beinsports.com/beinsports.com.test.js
+++ b/sites/beinsports.com/beinsports.com.test.js
@@ -1,6 +1,4 @@
const { parser, url } = require('./beinsports.com.config.js')
-const fs = require('fs')
-const path = require('path')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
diff --git a/sites/chada.ma/chada.ma.config.js b/sites/chada.ma/chada.ma.config.js
index 087028a7..b6002c35 100644
--- a/sites/chada.ma/chada.ma.config.js
+++ b/sites/chada.ma/chada.ma.config.js
@@ -1,54 +1,55 @@
-const axios = require('axios');
-const cheerio = require('cheerio');
-const dayjs = require('dayjs');
-const utc = require('dayjs/plugin/utc');
-const timezone = require('dayjs/plugin/timezone');
-const customParseFormat = require('dayjs/plugin/customParseFormat');
-
-dayjs.extend(utc);
-dayjs.extend(timezone);
-dayjs.extend(customParseFormat);
-
-module.exports = {
- site: 'chada.ma',
- channels: 'chada.ma.channels.xml',
- days: 1,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1 hour
- }
- },
- url() {
- return 'https://chada.ma/fr/chada-tv/grille-tv/';
- },
- parser: function ({ content }) {
- const $ = cheerio.load(content);
- const programs = [];
-
- $('#stopfix .posts-area h2').each((i, element) => {
- const timeRange = $(element).text().trim();
- const [start, stop] = timeRange.split(' - ').map(t => parseProgramTime(t.trim()));
-
- const titleElement = $(element).next('div').next('h3');
- const title = titleElement.text().trim();
-
- const description = titleElement.next('div').text().trim() || 'No description available';
-
- programs.push({
- title,
- description,
- start,
- stop
- });
- });
-
- return programs;
- }
-};
-
-function parseProgramTime(timeStr) {
- const timeZone = 'Africa/Casablanca';
- const currentDate = dayjs().format('YYYY-MM-DD');
-
- return dayjs.tz(`${currentDate} ${timeStr}`, 'YYYY-MM-DD HH:mm', timeZone).format('YYYY-MM-DDTHH:mm:ssZ');
-}
+const cheerio = require('cheerio')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'chada.ma',
+ channels: 'chada.ma.channels.xml',
+ days: 1,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1 hour
+ }
+ },
+ url() {
+ return 'https://chada.ma/fr/chada-tv/grille-tv/'
+ },
+ parser: function ({ content }) {
+ const $ = cheerio.load(content)
+ const programs = []
+
+ $('#stopfix .posts-area h2').each((i, element) => {
+ const timeRange = $(element).text().trim()
+ const [start, stop] = timeRange.split(' - ').map(t => parseProgramTime(t.trim()))
+
+ const titleElement = $(element).next('div').next('h3')
+ const title = titleElement.text().trim()
+
+ const description = titleElement.next('div').text().trim() || 'No description available'
+
+ programs.push({
+ title,
+ description,
+ start,
+ stop
+ })
+ })
+
+ return programs
+ }
+}
+
+function parseProgramTime(timeStr) {
+ const timeZone = 'Africa/Casablanca'
+ const currentDate = dayjs().format('YYYY-MM-DD')
+
+ return dayjs
+ .tz(`${currentDate} ${timeStr}`, 'YYYY-MM-DD HH:mm', timeZone)
+ .format('YYYY-MM-DDTHH:mm:ssZ')
+}
diff --git a/sites/chada.ma/chada.ma.test.js b/sites/chada.ma/chada.ma.test.js
index 557da6ea..51f715d4 100644
--- a/sites/chada.ma/chada.ma.test.js
+++ b/sites/chada.ma/chada.ma.test.js
@@ -1,60 +1,58 @@
-const { parser, url } = require('./chada.ma.config.js')
-const axios = require('axios')
-const dayjs = require('dayjs')
-const cheerio = require('cheerio')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-jest.mock('axios')
-
-const mockHtmlContent = `
-
-
Programmes d'Aujourd'hui
-
-
00:00 - 09:00
-
-
Bloc Prime + Clips
-
-
-
-
-`;
-
-it('can generate valid url', () => {
- expect(url()).toBe('https://chada.ma/fr/chada-tv/grille-tv/')
-});
-
-it('can parse response', () => {
- const content = mockHtmlContent
-
- const result = parser({ content }).map(p => {
- p.start = dayjs(p.start).tz('Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
- p.stop = dayjs(p.stop).tz('Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: "Bloc Prime + Clips",
- description: "No description available",
- start: dayjs.tz('00:00', 'HH:mm', 'Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ'),
- stop: dayjs.tz('09:00', 'HH:mm', 'Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: ''
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./chada.ma.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+jest.mock('axios')
+
+const mockHtmlContent = `
+
+
Programmes d'Aujourd'hui
+
+
00:00 - 09:00
+
+
Bloc Prime + Clips
+
+
+
+
+`
+
+it('can generate valid url', () => {
+ expect(url()).toBe('https://chada.ma/fr/chada-tv/grille-tv/')
+})
+
+it('can parse response', () => {
+ const content = mockHtmlContent
+
+ const result = parser({ content }).map(p => {
+ p.start = dayjs(p.start).tz('Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
+ p.stop = dayjs(p.stop).tz('Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Bloc Prime + Clips',
+ description: 'No description available',
+ start: dayjs.tz('00:00', 'HH:mm', 'Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ'),
+ stop: dayjs.tz('09:00', 'HH:mm', 'Africa/Casablanca').format('YYYY-MM-DDTHH:mm:ssZ')
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ content: ''
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.config.js b/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.config.js
index d8b49148..3ed3ebc4 100644
--- a/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.config.js
+++ b/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.config.js
@@ -16,9 +16,12 @@ module.exports = {
const start = parseStart(item)
const stop = parseStop(item, start)
programs.push({
- title: item.season?.serie?.title ? item.season.serie.title : item.title,
+ title: item.title,
+ subTitle: item.season?.serie?.title,
category: item.genreDetailed,
description: item.synopsis,
+ season: parseSeason(item),
+ episode: parseEpisode(item),
image: parseImage(item),
start: start.toJSON(),
stop: stop.toJSON()
@@ -29,7 +32,7 @@ module.exports = {
},
async channels() {
const html = await axios
- .get(`https://chaines-tv.orange.fr/programme-tv?filtres=all`)
+ .get('https://chaines-tv.orange.fr/programme-tv?filtres=all')
.then(r => r.data)
.catch(console.log)
@@ -61,6 +64,14 @@ function parseStop(item, start) {
return start.add(item.duration, 's')
}
+function parseSeason(item) {
+ return item.season?.number
+}
+
+function parseEpisode(item) {
+ return item.episodeNumber
+}
+
function parseItems(content, channel) {
const data = JSON.parse(content)
diff --git a/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js b/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js
index cd4dae36..9a07e69f 100644
--- a/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js
+++ b/sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js
@@ -27,6 +27,9 @@ it('can parse response', () => {
start: '2021-11-07T23:35:00.000Z',
stop: '2021-11-08T00:20:00.000Z',
title: 'Tête de liste',
+ subTitle: 'Esprits criminels',
+ season: 10,
+ episode: 12,
description:
"Un tueur en série prend un plaisir pervers à prévenir les autorités de Tallahassee avant chaque nouveau meurtre. Rossi apprend le décès d'un de ses vieux amis.",
category: 'Série Suspense',
diff --git a/sites/content.astro.com.my/content.astro.com.my.config.js b/sites/content.astro.com.my/content.astro.com.my.config.js
index 12c7f2af..6f261a91 100644
--- a/sites/content.astro.com.my/content.astro.com.my.config.js
+++ b/sites/content.astro.com.my/content.astro.com.my.config.js
@@ -40,7 +40,7 @@ module.exports = {
},
async channels() {
const data = await axios
- .get(`https://contenthub-api.eco.astro.com.my/channel/all.json`)
+ .get('https://contenthub-api.eco.astro.com.my/channel/all.json')
.then(r => r.data)
.catch(console.log)
@@ -85,7 +85,7 @@ function parseItems(content, date) {
const schedules = data.response.schedule
return schedules[date.format('YYYY-MM-DD')] || []
- } catch (e) {
+ } catch {
return []
}
}
diff --git a/sites/cosmotetv.gr/cosmotetv.gr.config.js b/sites/cosmotetv.gr/cosmotetv.gr.config.js
index ef26df1f..8374f050 100644
--- a/sites/cosmotetv.gr/cosmotetv.gr.config.js
+++ b/sites/cosmotetv.gr/cosmotetv.gr.config.js
@@ -1,81 +1,85 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const timezone = require('dayjs/plugin/timezone')
-
-dayjs.extend(utc)
-dayjs.extend(customParseFormat)
-dayjs.extend(timezone)
-
-module.exports = {
- site: 'cosmotetv.gr',
- days: 5,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1 hour
- },
- method: 'GET',
- headers: {
- 'referer': 'https://www.cosmotetv.gr/',
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
- 'Accept': '*/*',
- 'Accept-Language': 'en-US,en;q=0.9',
- 'Accept-Encoding': 'gzip, deflate, br, zstd',
- 'Origin': 'https://www.cosmotetv.gr',
- 'Sec-Ch-Ua': '"Not.A/Brand";v="24", "Chromium";v="131", "Google Chrome";v="131"',
- 'Sec-Ch-Ua-Mobile': '?0',
- 'Sec-Ch-Ua-Platform': '"Windows"',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'cross-site'
- }
- },
- url: function ({date, channel}) {
- const startOfDay = dayjs(date).startOf('day').utc().unix()
- const endOfDay = dayjs(date).endOf('day').utc().unix()
- return `https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/listings/el?from=${startOfDay}&to=${endOfDay}&callSigns=${channel.site_id}&endingIncludedInRange=false`
- },
- parser: function ({ date, content }) {
- let programs = []
- const data = JSON.parse(content)
- data.channels.forEach(channel => {
- channel.items.forEach(item => {
- const start = dayjs(item.startTime).utc().toISOString()
- const stop = dayjs(item.endTime).utc().toISOString()
- programs.push({
- title: item.title,
- description: item.description || 'No description available',
- category: item.qoe.genre,
- image: item.thumbnails.standard,
- start,
- stop
- })
- })
- })
- return programs
- },
- async channels() {
- const axios = require('axios')
- try {
- const response = await axios.get('https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/channels/all/el', {
- headers: this.request.headers
- })
- const data = response.data
-
- if (data && data.channels) {
- return data.channels.map(item => ({
- lang: 'el',
- site_id: item.callSign,
- name: item.title,
- //logo: item.logos.square
- }))
- } else {
- console.error('Unexpected response structure:', data)
- return []
- }
- } catch (error) {
- console.error('Error fetching channel data:', error)
- return []
- }
- }
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(utc)
+dayjs.extend(customParseFormat)
+dayjs.extend(timezone)
+
+module.exports = {
+ site: 'cosmotetv.gr',
+ days: 5,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1 hour
+ },
+ method: 'GET',
+ headers: {
+ referer: 'https://www.cosmotetv.gr/',
+ 'User-Agent':
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
+ Accept: '*/*',
+ 'Accept-Language': 'en-US,en;q=0.9',
+ 'Accept-Encoding': 'gzip, deflate, br, zstd',
+ Origin: 'https://www.cosmotetv.gr',
+ 'Sec-Ch-Ua': '"Not.A/Brand";v="24", "Chromium";v="131", "Google Chrome";v="131"',
+ 'Sec-Ch-Ua-Mobile': '?0',
+ 'Sec-Ch-Ua-Platform': '"Windows"',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'cross-site'
+ }
+ },
+ url: function ({ date, channel }) {
+ const startOfDay = dayjs(date).startOf('day').utc().unix()
+ const endOfDay = dayjs(date).endOf('day').utc().unix()
+ return `https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/listings/el?from=${startOfDay}&to=${endOfDay}&callSigns=${channel.site_id}&endingIncludedInRange=false`
+ },
+ parser: function ({ content }) {
+ let programs = []
+ const data = JSON.parse(content)
+ data.channels.forEach(channel => {
+ channel.items.forEach(item => {
+ const start = dayjs(item.startTime).utc().toISOString()
+ const stop = dayjs(item.endTime).utc().toISOString()
+ programs.push({
+ title: item.title,
+ description: item.description || 'No description available',
+ category: item.qoe.genre,
+ image: item.thumbnails.standard,
+ start,
+ stop
+ })
+ })
+ })
+ return programs
+ },
+ async channels() {
+ const axios = require('axios')
+ try {
+ const response = await axios.get(
+ 'https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/channels/all/el',
+ {
+ headers: this.request.headers
+ }
+ )
+ const data = response.data
+
+ if (data && data.channels) {
+ return data.channels.map(item => ({
+ lang: 'el',
+ site_id: item.callSign,
+ name: item.title
+ //logo: item.logos.square
+ }))
+ } else {
+ console.error('Unexpected response structure:', data)
+ return []
+ }
+ } catch (error) {
+ console.error('Error fetching channel data:', error)
+ return []
+ }
+ }
+}
diff --git a/sites/cosmotetv.gr/cosmotetv.gr.test.js b/sites/cosmotetv.gr/cosmotetv.gr.test.js
index dc73ce7e..405e3d9b 100644
--- a/sites/cosmotetv.gr/cosmotetv.gr.test.js
+++ b/sites/cosmotetv.gr/cosmotetv.gr.test.js
@@ -1,81 +1,76 @@
-const { parser, url, channels } = require('./cosmotetv.gr.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const timezone = require('dayjs/plugin/timezone')
-const axios = require('axios')
-
-dayjs.extend(utc)
-dayjs.extend(customParseFormat)
-dayjs.extend(timezone)
-
-jest.mock('axios')
-
-const date = dayjs.utc('2024-12-26', 'YYYY-MM-DD').startOf('d')
-const channel = { site_id: 'vouli', xmltv_id: 'HellenicParliamentTV.gr' }
-
-const mockChannelData = {
- "channels": [
- {
- "guid": "XTV100000954",
- "title": "ΒΟΥΛΗ HD",
- "callSign": "vouli",
- "logos": {
- "square": "https://tr.static.cdn.cosmotetvott.gr/ote-prod/channel_logos/vouli1-normal.png",
- "wide": "https://tr.static.cdn.cosmotetvott.gr/ote-prod/channel_logos/vouli1-wide.png"
- }
- }
- ]
-}
-
-const mockEpgData = {
- "channels": [
- {
- "items": [
- {
- "startTime": "2024-12-26T23:00:00+00:00",
- "endTime": "2024-12-27T00:00:00+00:00",
- "title": "Τι Λέει ο Νόμος",
- "description": "νημερωτική εκπομπή. Συζήτηση με τους εισηγητές των κομμάτων για το νομοθετικό έργο.",
- "qoe": {
- "genre": "Special"
- },
- "thumbnails": {
- "standard": "https://gr-ermou-prod-cache05.static.cdn.cosmotetvott.gr/ote-prod/70/280/040029714812000800_1734415727199.jpg"
- }
- }
- ]
- }
- ]
-}
-
-it('can generate valid url', () => {
- const startOfDay = dayjs(date).startOf('day').utc().unix()
- const endOfDay = dayjs(date).endOf('day').utc().unix()
- expect(url({ date, channel })).toBe(`https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/listings/el?from=${startOfDay}&to=${endOfDay}&callSigns=${channel.site_id}&endingIncludedInRange=false`)
-})
-
-it('can parse response', () => {
- const content = JSON.stringify(mockEpgData)
- const result = parser({ date, content }).map(p => {
- p.start = dayjs(p.start).toISOString()
- p.stop = dayjs(p.stop).toISOString()
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: "Τι Λέει ο Νόμος",
- description: "νημερωτική εκπομπή. Συζήτηση με τους εισηγητές των κομμάτων για το νομοθετικό έργο.",
- category: "Special",
- image: "https://gr-ermou-prod-cache05.static.cdn.cosmotetvott.gr/ote-prod/70/280/040029714812000800_1734415727199.jpg",
- start: "2024-12-26T23:00:00.000Z",
- stop: "2024-12-27T00:00:00.000Z"
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({ date, channel, content: '{"date":"2024-12-26","categories":[],"channels":[]}' });
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./cosmotetv.gr.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(utc)
+dayjs.extend(customParseFormat)
+dayjs.extend(timezone)
+
+jest.mock('axios')
+
+const date = dayjs.utc('2024-12-26', 'YYYY-MM-DD').startOf('d')
+const channel = { site_id: 'vouli', xmltv_id: 'HellenicParliamentTV.gr' }
+
+const mockEpgData = {
+ channels: [
+ {
+ items: [
+ {
+ startTime: '2024-12-26T23:00:00+00:00',
+ endTime: '2024-12-27T00:00:00+00:00',
+ title: 'Τι Λέει ο Νόμος',
+ description:
+ 'νημερωτική εκπομπή. Συζήτηση με τους εισηγητές των κομμάτων για το νομοθετικό έργο.',
+ qoe: {
+ genre: 'Special'
+ },
+ thumbnails: {
+ standard:
+ 'https://gr-ermou-prod-cache05.static.cdn.cosmotetvott.gr/ote-prod/70/280/040029714812000800_1734415727199.jpg'
+ }
+ }
+ ]
+ }
+ ]
+}
+
+it('can generate valid url', () => {
+ const startOfDay = dayjs(date).startOf('day').utc().unix()
+ const endOfDay = dayjs(date).endOf('day').utc().unix()
+ expect(url({ date, channel })).toBe(
+ `https://mwapi-prod.cosmotetvott.gr/api/v3.4/epg/listings/el?from=${startOfDay}&to=${endOfDay}&callSigns=${channel.site_id}&endingIncludedInRange=false`
+ )
+})
+
+it('can parse response', () => {
+ const content = JSON.stringify(mockEpgData)
+ const result = parser({ date, content }).map(p => {
+ p.start = dayjs(p.start).toISOString()
+ p.stop = dayjs(p.stop).toISOString()
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Τι Λέει ο Νόμος',
+ description:
+ 'νημερωτική εκπομπή. Συζήτηση με τους εισηγητές των κομμάτων για το νομοθετικό έργο.',
+ category: 'Special',
+ image:
+ 'https://gr-ermou-prod-cache05.static.cdn.cosmotetvott.gr/ote-prod/70/280/040029714812000800_1734415727199.jpg',
+ start: '2024-12-26T23:00:00.000Z',
+ stop: '2024-12-27T00:00:00.000Z'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ date,
+ channel,
+ content: '{"date":"2024-12-26","categories":[],"channels":[]}'
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/cubmu.com/cubmu.com.config.js b/sites/cubmu.com/cubmu.com.config.js
index 6b408aed..ec288a36 100644
--- a/sites/cubmu.com/cubmu.com.config.js
+++ b/sites/cubmu.com/cubmu.com.config.js
@@ -1,102 +1,114 @@
-const dayjs = require('dayjs')
-const timezone = require('dayjs/plugin/timezone')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(timezone)
-dayjs.extend(utc)
-
-module.exports = {
- site: 'cubmu.com',
- days: 2,
- url({ channel, date }) {
- return `https://servicebuss.transvision.co.id/v2/cms/getEPGData?app_id=cubmu&tvs_platform_id=standalone&schedule_date=${date.format('YYYY-MM-DD')}&channel_id=${channel.site_id}`
- },
- parser({ content, channel }) {
- const programs = []
- const items = parseItems(content)
- items.forEach(item => {
- programs.push({
- title: parseTitle(item),
- description: parseDescription(item, channel.lang),
- episode: parseEpisode(item),
- start: parseStart(item).toISOString(),
- stop: parseStop(item).toISOString()
- })
- })
-
- return programs
- },
- async channels({ lang = 'id' }) {
- const axios = require('axios')
- const cheerio = require('cheerio')
- const result = await axios
- .get('https://cubmu.com/live-tv')
- .then(response => response.data)
- .catch(console.error)
-
- const $ = cheerio.load(result)
-
- // retrieve service api data
- const config = JSON.parse($('#__NEXT_DATA__').text()).runtimeConfig || {}
-
- const options = {
- headers: {
- Origin: 'https://cubmu.com',
- Referer: 'https://cubmu.com/live-tv'
- }
- }
- // login to service bus
- const token = await axios
- .post(`https://servicebuss.transvision.co.id/tvs/login/external?email=${config.email}&password=${config.password}&deviceId=${config.deviceId}&deviceType=${config.deviceType}&deviceModel=${config.deviceModel}&deviceToken=&serial=&platformId=${config.platformId}`, options)
- .then(response => response.data)
- .catch(console.error)
- // list channels
- const subscribedChannels = await axios
- .post(`https://servicebuss.transvision.co.id/tvs/subscribe_product/list?platformId=${config.platformId}`, options)
- .then(response => response.data)
- .catch(console.error)
-
- const channels = []
- const included = []
- if (Array.isArray(subscribedChannels.channelPackageList)) {
- subscribedChannels.channelPackageList.forEach(pkg => {
- pkg.channelList.forEach(channel => {
- if (included.indexOf(channel.id) < 0) {
- included.push(channel.id)
- channels.push({
- lang,
- site_id: channel.id,
- name: channel.name
- })
- }
- })
- })
- }
-
- return channels
- }
-}
-
-function parseItems(content) {
- return content ? JSON.parse(content.trim()).result || [] : []
-}
-
-function parseTitle(item) {
- return item.scehedule_title
-}
-
-function parseDescription(item, lang = 'id') {
- return lang === 'id' ? item.schedule_json.primarySynopsis : item.schedule_json.secondarySynopsis
-}
-
-function parseEpisode(item) {
- return item.schedule_json.episodeName
-}
-
-function parseStart(item) {
- return dayjs.tz(item.schedule_date, 'YYYY-MM-DD HH:mm:ss', 'Asia/Jakarta')
-}
-
-function parseStop(item) {
- return dayjs.tz([item.schedule_date.split(' ')[0], item.schedule_end_time].join(' '), 'YYYY-MM-DD HH:mm:ss', 'Asia/Jakarta')
-}
+const dayjs = require('dayjs')
+const timezone = require('dayjs/plugin/timezone')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(timezone)
+dayjs.extend(utc)
+
+module.exports = {
+ site: 'cubmu.com',
+ days: 2,
+ url({ channel, date }) {
+ return `https://servicebuss.transvision.co.id/v2/cms/getEPGData?app_id=cubmu&tvs_platform_id=standalone&schedule_date=${date.format(
+ 'YYYY-MM-DD'
+ )}&channel_id=${channel.site_id}`
+ },
+ parser({ content, channel }) {
+ const programs = []
+ const items = parseItems(content)
+ items.forEach(item => {
+ programs.push({
+ title: parseTitle(item),
+ description: parseDescription(item, channel.lang),
+ episode: parseEpisode(item),
+ start: parseStart(item).toISOString(),
+ stop: parseStop(item).toISOString()
+ })
+ })
+
+ return programs
+ },
+ async channels({ lang = 'id' }) {
+ const axios = require('axios')
+ const cheerio = require('cheerio')
+ const result = await axios
+ .get('https://cubmu.com/live-tv')
+ .then(response => response.data)
+ .catch(console.error)
+
+ const $ = cheerio.load(result)
+
+ // retrieve service api data
+ const config = JSON.parse($('#__NEXT_DATA__').text()).runtimeConfig || {}
+
+ const options = {
+ headers: {
+ Origin: 'https://cubmu.com',
+ Referer: 'https://cubmu.com/live-tv'
+ }
+ }
+ // login to service bus
+ await axios
+ .post(
+ `https://servicebuss.transvision.co.id/tvs/login/external?email=${config.email}&password=${config.password}&deviceId=${config.deviceId}&deviceType=${config.deviceType}&deviceModel=${config.deviceModel}&deviceToken=&serial=&platformId=${config.platformId}`,
+ options
+ )
+ .then(response => response.data)
+ .catch(console.error)
+ // list channels
+ const subscribedChannels = await axios
+ .post(
+ `https://servicebuss.transvision.co.id/tvs/subscribe_product/list?platformId=${config.platformId}`,
+ options
+ )
+ .then(response => response.data)
+ .catch(console.error)
+
+ const channels = []
+ const included = []
+ if (Array.isArray(subscribedChannels.channelPackageList)) {
+ subscribedChannels.channelPackageList.forEach(pkg => {
+ pkg.channelList.forEach(channel => {
+ if (included.indexOf(channel.id) < 0) {
+ included.push(channel.id)
+ channels.push({
+ lang,
+ site_id: channel.id,
+ name: channel.name
+ })
+ }
+ })
+ })
+ }
+
+ return channels
+ }
+}
+
+function parseItems(content) {
+ return content ? JSON.parse(content.trim()).result || [] : []
+}
+
+function parseTitle(item) {
+ return item.scehedule_title
+}
+
+function parseDescription(item, lang = 'id') {
+ return lang === 'id' ? item.schedule_json.primarySynopsis : item.schedule_json.secondarySynopsis
+}
+
+function parseEpisode(item) {
+ return item.schedule_json.episodeName
+}
+
+function parseStart(item) {
+ return dayjs.tz(item.schedule_date, 'YYYY-MM-DD HH:mm:ss', 'Asia/Jakarta')
+}
+
+function parseStop(item) {
+ return dayjs.tz(
+ [item.schedule_date.split(' ')[0], item.schedule_end_time].join(' '),
+ 'YYYY-MM-DD HH:mm:ss',
+ 'Asia/Jakarta'
+ )
+}
diff --git a/sites/cubmu.com/cubmu.com.test.js b/sites/cubmu.com/cubmu.com.test.js
index 38bbf099..cdf5cde3 100644
--- a/sites/cubmu.com/cubmu.com.test.js
+++ b/sites/cubmu.com/cubmu.com.test.js
@@ -1,47 +1,47 @@
-const { url, parser } = require('./cubmu.com.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-11-05', 'DD/MM/YYYY').startOf('d')
-const channel = { site_id: '4028c68574537fcd0174be43042758d8', xmltv_id: 'TransTV.id', lang: 'id' }
-const channelEn = Object.assign({}, channel, { lang: 'en' })
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe(
- 'https://servicebuss.transvision.co.id/v2/cms/getEPGData?app_id=cubmu&tvs_platform_id=standalone&schedule_date=2023-11-05&channel_id=4028c68574537fcd0174be43042758d8'
- )
-})
-
-it('can parse response', () => {
- const content =
- '{"result":[{"channel_id":"4028c68574537fcd0174be43042758d8","channel_name":"Trans TV","scehedule_title":"CNN Tech News","schedule_date":"2023-11-05 01:30:00","schedule_end_time":"02:00:00","schedule_json":{"availability":0,"channelId":"4028c68574537fcd0174be43042758d8","channelName":"Trans TV","duration":1800,"editable":true,"episodeName":"","imageUrl":"https://cdnjkt2.transvision.co.id:1001/catchup/schedule/thumbnail/4028c68574537fcd0174be43042758d8/4028c6858b8b3621018b9330e3701a7e/458x640","imageUrlWide":"https://cdnjkt2.transvision.co.id:1001/catchup/schedule/thumbnail/4028c68574537fcd0174be43042758d8/4028c6858b8b3621018b9330e3701a7e/320x180","name":"CNN Tech News","ottImageUrl":"","primarySynopsis":"CNN Indonesia Tech News adalah berita teknologi yang membawa pemirsa ke dunia teknologi yang penuh dengan informasi, pendidikan, hiburan sampai informasi kesehatan terkini.","scheduleId":"4028c6858b8b3621018b9330e3701a7e","scheduleTime":"18:30:00","secondarySynopsis":"CNN Indonesia Tech News is tech news brings viewers into the world of technology that provides information, education, entertainment to the latest health information.","startDt":"20231104183000","url":""},"schedule_start_time":"01:30:00"}]}'
-
- const idResults = parser({ content, channel })
- expect(idResults).toMatchObject([
- {
- start: '2023-11-04T18:30:00.000Z',
- stop: '2023-11-04T19:00:00.000Z',
- title: 'CNN Tech News',
- description:
- 'CNN Indonesia Tech News adalah berita teknologi yang membawa pemirsa ke dunia teknologi yang penuh dengan informasi, pendidikan, hiburan sampai informasi kesehatan terkini.'
- }
- ])
-
- const enResults = parser({ content, channel: channelEn })
- expect(enResults).toMatchObject([
- {
- start: '2023-11-04T18:30:00.000Z',
- stop: '2023-11-04T19:00:00.000Z',
- title: 'CNN Tech News',
- description:
- 'CNN Indonesia Tech News is tech news brings viewers into the world of technology that provides information, education, entertainment to the latest health information.'
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const results = parser({ content: '' })
-
- expect(results).toMatchObject([])
-})
+const { url, parser } = require('./cubmu.com.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-11-05', 'DD/MM/YYYY').startOf('d')
+const channel = { site_id: '4028c68574537fcd0174be43042758d8', xmltv_id: 'TransTV.id', lang: 'id' }
+const channelEn = Object.assign({}, channel, { lang: 'en' })
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe(
+ 'https://servicebuss.transvision.co.id/v2/cms/getEPGData?app_id=cubmu&tvs_platform_id=standalone&schedule_date=2023-11-05&channel_id=4028c68574537fcd0174be43042758d8'
+ )
+})
+
+it('can parse response', () => {
+ const content =
+ '{"result":[{"channel_id":"4028c68574537fcd0174be43042758d8","channel_name":"Trans TV","scehedule_title":"CNN Tech News","schedule_date":"2023-11-05 01:30:00","schedule_end_time":"02:00:00","schedule_json":{"availability":0,"channelId":"4028c68574537fcd0174be43042758d8","channelName":"Trans TV","duration":1800,"editable":true,"episodeName":"","imageUrl":"https://cdnjkt2.transvision.co.id:1001/catchup/schedule/thumbnail/4028c68574537fcd0174be43042758d8/4028c6858b8b3621018b9330e3701a7e/458x640","imageUrlWide":"https://cdnjkt2.transvision.co.id:1001/catchup/schedule/thumbnail/4028c68574537fcd0174be43042758d8/4028c6858b8b3621018b9330e3701a7e/320x180","name":"CNN Tech News","ottImageUrl":"","primarySynopsis":"CNN Indonesia Tech News adalah berita teknologi yang membawa pemirsa ke dunia teknologi yang penuh dengan informasi, pendidikan, hiburan sampai informasi kesehatan terkini.","scheduleId":"4028c6858b8b3621018b9330e3701a7e","scheduleTime":"18:30:00","secondarySynopsis":"CNN Indonesia Tech News is tech news brings viewers into the world of technology that provides information, education, entertainment to the latest health information.","startDt":"20231104183000","url":""},"schedule_start_time":"01:30:00"}]}'
+
+ const idResults = parser({ content, channel })
+ expect(idResults).toMatchObject([
+ {
+ start: '2023-11-04T18:30:00.000Z',
+ stop: '2023-11-04T19:00:00.000Z',
+ title: 'CNN Tech News',
+ description:
+ 'CNN Indonesia Tech News adalah berita teknologi yang membawa pemirsa ke dunia teknologi yang penuh dengan informasi, pendidikan, hiburan sampai informasi kesehatan terkini.'
+ }
+ ])
+
+ const enResults = parser({ content, channel: channelEn })
+ expect(enResults).toMatchObject([
+ {
+ start: '2023-11-04T18:30:00.000Z',
+ stop: '2023-11-04T19:00:00.000Z',
+ title: 'CNN Tech News',
+ description:
+ 'CNN Indonesia Tech News is tech news brings viewers into the world of technology that provides information, education, entertainment to the latest health information.'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const results = parser({ content: '' })
+
+ expect(results).toMatchObject([])
+})
diff --git a/sites/cyta.com.cy/cyta.com.cy.config.js b/sites/cyta.com.cy/cyta.com.cy.config.js
index ef9937a5..f698dfa4 100644
--- a/sites/cyta.com.cy/cyta.com.cy.config.js
+++ b/sites/cyta.com.cy/cyta.com.cy.config.js
@@ -1,60 +1,59 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const cheerio = require('cheerio')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-module.exports = {
- site: 'cyta.com.cy',
- days: 7,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1 hour
- }
- },
- url: function ({date, channel}) {
- // Get the epoch timestamp
- const todayEpoch = date.startOf('day').utc().valueOf()
- // Get the epoch timestamp for the next day
- const nextDayEpoch = date.add(1, 'day').startOf('day').utc().valueOf()
- return `https://epg.cyta.com.cy/api/mediacatalog/fetchEpg?startTimeEpoch=${todayEpoch}&endTimeEpoch=${nextDayEpoch}&language=1&channelIds=${channel.site_id}`
- },
- parser: function ({content}) {
- const data = JSON.parse(content)
- const programs = []
-
- data.channelEpgs.forEach(channel => {
- channel.epgPlayables.forEach(epg => {
- const start = new Date(epg.startTime).toISOString();
- const stop = new Date(epg.endTime).toISOString();
-
- programs.push({
- title: epg.name,
- start,
- stop
- })
- })
- })
-
- return programs
- },
- async channels() {
- const axios = require('axios')
- const data = await axios
- .get(`https://epg.cyta.com.cy/api/mediacatalog/fetchChannels?language=1`)
- .then(r => r.data)
- .catch(console.log)
-
- return data.channels.map(item => {
- return {
- lang: 'el',
- site_id: item.id,
- name: item.name
- }
- })
- }
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'cyta.com.cy',
+ days: 7,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1 hour
+ }
+ },
+ url: function ({ date, channel }) {
+ // Get the epoch timestamp
+ const todayEpoch = date.startOf('day').utc().valueOf()
+ // Get the epoch timestamp for the next day
+ const nextDayEpoch = date.add(1, 'day').startOf('day').utc().valueOf()
+ return `https://epg.cyta.com.cy/api/mediacatalog/fetchEpg?startTimeEpoch=${todayEpoch}&endTimeEpoch=${nextDayEpoch}&language=1&channelIds=${channel.site_id}`
+ },
+ parser: function ({ content }) {
+ const data = JSON.parse(content)
+ const programs = []
+
+ data.channelEpgs.forEach(channel => {
+ channel.epgPlayables.forEach(epg => {
+ const start = new Date(epg.startTime).toISOString()
+ const stop = new Date(epg.endTime).toISOString()
+
+ programs.push({
+ title: epg.name,
+ start,
+ stop
+ })
+ })
+ })
+
+ return programs
+ },
+ async channels() {
+ const axios = require('axios')
+ const data = await axios
+ .get('https://epg.cyta.com.cy/api/mediacatalog/fetchChannels?language=1')
+ .then(r => r.data)
+ .catch(console.log)
+
+ return data.channels.map(item => {
+ return {
+ lang: 'el',
+ site_id: item.id,
+ name: item.name
+ }
+ })
+ }
+}
diff --git a/sites/cyta.com.cy/cyta.com.cy.test.js b/sites/cyta.com.cy/cyta.com.cy.test.js
index d09f7bcc..95797a92 100644
--- a/sites/cyta.com.cy/cyta.com.cy.test.js
+++ b/sites/cyta.com.cy/cyta.com.cy.test.js
@@ -1,53 +1,49 @@
-const { url, parser } = require('./cyta.com.cy.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(utc)
-dayjs.extend(customParseFormat)
-
-const date = dayjs.utc('2025-01-03', 'YYYY-MM-DD').startOf('day')
-const channel = {
- site_id: '561066',
- xmltv_id: 'RIK1.cy'
-}
-
-it('can generate valid url', () => {
- const generatedUrl = url({ date, channel })
- expect(generatedUrl).toBe(
- 'https://epg.cyta.com.cy/api/mediacatalog/fetchEpg?startTimeEpoch=1735862400000&endTimeEpoch=1735948800000&language=1&channelIds=561066'
- )
-})
-
-it('can parse response', () => {
- const content = `
- {
- "channelEpgs": [
- {
- "epgPlayables": [
- { "name": "Πρώτη Ενημέρωση", "startTime": 1735879500000, "endTime": 1735889400000 }
- ]
- }
- ]
- }`
-
- const result = parser({ content }).map(p => {
- p.start = p.start
- p.stop = p.stop
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: 'Πρώτη Ενημέρωση',
- start: '2025-01-03T04:45:00.000Z',
- stop: '2025-01-03T07:30:00.000Z'
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: '{"channelEpgs":[]}'
- })
- expect(result).toMatchObject([])
-})
+const { url, parser } = require('./cyta.com.cy.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(utc)
+dayjs.extend(customParseFormat)
+
+const date = dayjs.utc('2025-01-03', 'YYYY-MM-DD').startOf('day')
+const channel = {
+ site_id: '561066',
+ xmltv_id: 'RIK1.cy'
+}
+
+it('can generate valid url', () => {
+ const generatedUrl = url({ date, channel })
+ expect(generatedUrl).toBe(
+ 'https://epg.cyta.com.cy/api/mediacatalog/fetchEpg?startTimeEpoch=1735862400000&endTimeEpoch=1735948800000&language=1&channelIds=561066'
+ )
+})
+
+it('can parse response', () => {
+ const content = `
+ {
+ "channelEpgs": [
+ {
+ "epgPlayables": [
+ { "name": "Πρώτη Ενημέρωση", "startTime": 1735879500000, "endTime": 1735889400000 }
+ ]
+ }
+ ]
+ }`
+
+ const result = parser({ content })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Πρώτη Ενημέρωση',
+ start: '2025-01-03T04:45:00.000Z',
+ stop: '2025-01-03T07:30:00.000Z'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ content: '{"channelEpgs":[]}'
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/dens.tv/dens.tv.config.js b/sites/dens.tv/dens.tv.config.js
index 4ac40aa3..25cd3036 100644
--- a/sites/dens.tv/dens.tv.config.js
+++ b/sites/dens.tv/dens.tv.config.js
@@ -13,9 +13,9 @@ module.exports = {
site: 'dens.tv',
days: 2,
url({ channel, date }) {
- return `https://www.dens.tv/api/dens3/tv/TvChannels/listEpgByDate?date=${date.format('YYYY-MM-DD')}&id_channel=${
- channel.site_id
- }&app_type=10`
+ return `https://www.dens.tv/api/dens3/tv/TvChannels/listEpgByDate?date=${date.format(
+ 'YYYY-MM-DD'
+ )}&id_channel=${channel.site_id}&app_type=10`
},
parser({ content }) {
// parsing
@@ -25,8 +25,9 @@ module.exports = {
if (Array.isArray(response?.data)) {
response.data.forEach(item => {
const title = item.title
- const [, , , season, , , episode] = title.match(/( (Season |Season|S)(\d+))?( (Episode|Ep) (\d+))/) ||
- [null, null, null, null, null, null, null]
+ const [, , , season, , , episode] = title.match(
+ /( (Season |Season|S)(\d+))?( (Episode|Ep) (\d+))/
+ ) || [null, null, null, null, null, null, null]
programs.push({
title,
description: item.description,
@@ -52,7 +53,7 @@ module.exports = {
const channels = []
for (const id_category of Object.values(categories)) {
const data = await axios
- .get(`https://www.dens.tv/api/dens3/tv/TvChannels/listByCategory`, {
+ .get('https://www.dens.tv/api/dens3/tv/TvChannels/listByCategory', {
params: { id_category }
})
.then(r => r.data)
diff --git a/sites/dens.tv/dens.tv.test.js b/sites/dens.tv/dens.tv.test.js
index 3417000e..79883d0f 100644
--- a/sites/dens.tv/dens.tv.test.js
+++ b/sites/dens.tv/dens.tv.test.js
@@ -10,7 +10,9 @@ const date = dayjs.utc('2024-11-24').startOf('d')
const channel = { site_id: '38', xmltv_id: 'AniplusAsia.sg', lang: 'id' }
it('can generate valid url', () => {
- expect(url({ channel, date })).toBe('https://www.dens.tv/api/dens3/tv/TvChannels/listEpgByDate?date=2024-11-24&id_channel=38&app_type=10')
+ expect(url({ channel, date })).toBe(
+ 'https://www.dens.tv/api/dens3/tv/TvChannels/listEpgByDate?date=2024-11-24&id_channel=38&app_type=10'
+ )
})
it('can parse response', () => {
diff --git a/sites/digiturk.com.tr/digiturk.com.tr.config.js b/sites/digiturk.com.tr/digiturk.com.tr.config.js
index 03280f4c..4dba0999 100644
--- a/sites/digiturk.com.tr/digiturk.com.tr.config.js
+++ b/sites/digiturk.com.tr/digiturk.com.tr.config.js
@@ -65,7 +65,7 @@ module.exports = {
const cheerio = require('cheerio')
const data = await axios
- .get(`https://www.digiturk.com.tr/`, {
+ .get('https://www.digiturk.com.tr/', {
headers: {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
diff --git a/sites/dishtv.in/dishtv.in.config.js b/sites/dishtv.in/dishtv.in.config.js
index 6a9d3f18..8c2bd878 100644
--- a/sites/dishtv.in/dishtv.in.config.js
+++ b/sites/dishtv.in/dishtv.in.config.js
@@ -60,7 +60,7 @@ module.exports = {
$('.pgrid').each((i, el) => {
const onclick = $(el).find('.chnl-logo').attr('onclick')
const number = $(el).find('.cnl-fav > a > span').text().trim()
- const [, name, site_id] = onclick.match(/ShowChannelGuid\('([^']+)','([^']+)'/) || [
+ const [, , site_id] = onclick.match(/ShowChannelGuid\('([^']+)','([^']+)'/) || [
null,
'',
''
diff --git a/sites/guida.tv/guida.tv.config.js b/sites/guida.tv/guida.tv.config.js
index 44402d16..0c14a1cd 100644
--- a/sites/guida.tv/guida.tv.config.js
+++ b/sites/guida.tv/guida.tv.config.js
@@ -49,7 +49,7 @@ module.exports = {
const channels = []
for (let provider of providers) {
const data = await axios
- .post(`https://www.guida.tv/guide/schedule`, null, {
+ .post('https://www.guida.tv/guide/schedule', null, {
params: {
provider,
region: 'Italy',
@@ -81,7 +81,7 @@ module.exports = {
}
}
-function parseStart($item, date, channel) {
+function parseStart($item, date) {
const timeString = $item('td:eq(0)').text().trim()
const dateString = `${date.format('YYYY-MM-DD')} ${timeString}`
diff --git a/sites/guidatv.sky.it/guidatv.sky.it.config.js b/sites/guidatv.sky.it/guidatv.sky.it.config.js
index 834deab4..ddafb89d 100644
--- a/sites/guidatv.sky.it/guidatv.sky.it.config.js
+++ b/sites/guidatv.sky.it/guidatv.sky.it.config.js
@@ -35,7 +35,7 @@ module.exports = {
const cheerio = require('cheerio')
const data = await axios
- .get(`https://guidatv.sky.it/canali`)
+ .get('https://guidatv.sky.it/canali')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/hoy.tv/hoy.tv.config.js b/sites/hoy.tv/hoy.tv.config.js
index d5931ee1..30cc2b82 100644
--- a/sites/hoy.tv/hoy.tv.config.js
+++ b/sites/hoy.tv/hoy.tv.config.js
@@ -1,63 +1,63 @@
-const axios = require('axios')
-const convert = require('xml-js')
-const dayjs = require('dayjs')
-const timezone = require('dayjs/plugin/timezone')
-
-dayjs.extend(timezone)
-
-module.exports = {
- site: 'hoy.tv',
- days: 2,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1h
- }
- },
- url: function ({ channel, date }) {
- return `https://epg-file.hoy.tv/hoy/OTT${channel.site_id}${date.format('YYYYMMDD')}.xml`
- },
- parser({ content, channel, date }) {
- const data = convert.xml2js(content, {
- compact: true,
- ignoreDeclaration: true,
- ignoreAttributes: true
- })
-
- const programs = []
-
- for (let item of data.ProgramGuide.Channel.EpgItem) {
- const start = dayjs.tz(item.EpgStartDateTime._text, 'YYYY-MM-DD HH:mm:ss', 'Asia/Hong_Kong')
-
- if (! date.isSame(start, 'day')) {
- continue
- }
-
- const epIndex = item.EpisodeInfo.EpisodeIndex._text
- const subtitle = parseInt(epIndex) > 0 ? `第${epIndex}集` : undefined
-
- programs.push({
- title: `${item.ComScore.ns_st_pr._text}${item.EpgOtherInfo?._text || ''}`,
- sub_title: subtitle,
- description: item.EpisodeInfo.EpisodeLongDescription._text,
- start,
- stop: dayjs.tz(item.EpgEndDateTime._text, 'YYYY-MM-DD HH:mm:ss', 'Asia/Hong_Kong'),
- })
- }
-
- return programs
- },
- async channels({ lang }) {
- const data = await axios
- .get('https://api2.hoy.tv/api/v2/a/channel')
- .then(r => r.data)
- .catch(console.error)
-
- return data.data.map(c => {
- return {
- site_id: c.videos.id,
- name: c.name.zh_hk,
- lang: 'zh',
- }
- })
- }
-}
+const axios = require('axios')
+const convert = require('xml-js')
+const dayjs = require('dayjs')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(timezone)
+
+module.exports = {
+ site: 'hoy.tv',
+ days: 2,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1h
+ }
+ },
+ url: function ({ channel, date }) {
+ return `https://epg-file.hoy.tv/hoy/OTT${channel.site_id}${date.format('YYYYMMDD')}.xml`
+ },
+ parser({ content, date }) {
+ const data = convert.xml2js(content, {
+ compact: true,
+ ignoreDeclaration: true,
+ ignoreAttributes: true
+ })
+
+ const programs = []
+
+ for (let item of data.ProgramGuide.Channel.EpgItem) {
+ const start = dayjs.tz(item.EpgStartDateTime._text, 'YYYY-MM-DD HH:mm:ss', 'Asia/Hong_Kong')
+
+ if (!date.isSame(start, 'day')) {
+ continue
+ }
+
+ const epIndex = item.EpisodeInfo.EpisodeIndex._text
+ const subtitle = parseInt(epIndex) > 0 ? `第${epIndex}集` : undefined
+
+ programs.push({
+ title: `${item.ComScore.ns_st_pr._text}${item.EpgOtherInfo?._text || ''}`,
+ sub_title: subtitle,
+ description: item.EpisodeInfo.EpisodeLongDescription._text,
+ start,
+ stop: dayjs.tz(item.EpgEndDateTime._text, 'YYYY-MM-DD HH:mm:ss', 'Asia/Hong_Kong')
+ })
+ }
+
+ return programs
+ },
+ async channels() {
+ const data = await axios
+ .get('https://api2.hoy.tv/api/v2/a/channel')
+ .then(r => r.data)
+ .catch(console.error)
+
+ return data.data.map(c => {
+ return {
+ site_id: c.videos.id,
+ name: c.name.zh_hk,
+ lang: 'zh'
+ }
+ })
+ }
+}
diff --git a/sites/hoy.tv/hoy.tv.test.js b/sites/hoy.tv/hoy.tv.test.js
index 1a751021..155c2963 100644
--- a/sites/hoy.tv/hoy.tv.test.js
+++ b/sites/hoy.tv/hoy.tv.test.js
@@ -1,116 +1,115 @@
-const { parser, url } = require('./hoy.tv.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-jest.mock('axios')
-
-const date = dayjs.utc('2024-09-13', 'YYYY-MM-DD').startOf('d')
-const channel = {
- site_id: '76',
- xmltv_id: 'HOYIBC.hk',
- lang: 'zh'
-}
-const content = `
-
-
-
- 2024-09-13 11:30:00
- 2024-09-13 12:30:00
- [PG]
- false
- false
- 2024-09-27 11:30:00
-
- 0
-
- 0
-
- http://tv.fantv.hk/images/thumbnail_1920_1080_fantv.jpg
-
-
- EQ00135
- 46
- 點講都係一家人
-
- http://tv.fantv.hk/images/nosuchthumbnail.jpg
-
-
-
- 點講都係一家人
- 0
- EQ00135
- 點講都係一家人 Episode 46
- 1
- 20240913
- 1130
- 0001
- 3704000
-
-
-
- 2024-09-13 12:30:00
- 2024-09-13 13:30:00
-
- false
- false
- 2024-09-27 12:30:00
-
- 0
-
- 0
-
- http://tv.fantv.hk/images/thumbnail_1920_1080_fantv.jpg
-
-
- ED00311
- 0
- 麝香之路
- Ep. 2 .The Secret of disappeared kingdom.shows the mysterious disappearance of the ancient Tibetan kingdom which gained world
- http://tv.fantv.hk/images/nosuchthumbnail.jpg
-
-
-
- 麝香之路
- 0
- ED00311
- 麝香之路 2024-09-13
- 1
- 20240913
- 1230
- 0001
- 3704000
-
-
-
- `
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe(
- 'https://epg-file.hoy.tv/hoy/OTT7620240913.xml'
- )
-})
-
-it('can parse response', () => {
- const result = parser({ content, channel, date }).map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(result).toMatchObject([
- {
- start: '2024-09-13T03:30:00.000Z',
- stop: '2024-09-13T04:30:00.000Z',
- title: '點講都係一家人[PG]',
- sub_title: '第46集',
- },
- {
- start: '2024-09-13T04:30:00.000Z',
- stop: '2024-09-13T05:30:00.000Z',
- title: '麝香之路',
- description: 'Ep. 2 .The Secret of disappeared kingdom.shows the mysterious disappearance of the ancient Tibetan kingdom which gained world',
- }
- ])
-})
+const { parser, url } = require('./hoy.tv.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+jest.mock('axios')
+
+const date = dayjs.utc('2024-09-13', 'YYYY-MM-DD').startOf('d')
+const channel = {
+ site_id: '76',
+ xmltv_id: 'HOYIBC.hk',
+ lang: 'zh'
+}
+const content = `
+
+
+
+ 2024-09-13 11:30:00
+ 2024-09-13 12:30:00
+ [PG]
+ false
+ false
+ 2024-09-27 11:30:00
+
+ 0
+
+ 0
+
+ http://tv.fantv.hk/images/thumbnail_1920_1080_fantv.jpg
+
+
+ EQ00135
+ 46
+ 點講都係一家人
+
+ http://tv.fantv.hk/images/nosuchthumbnail.jpg
+
+
+
+ 點講都係一家人
+ 0
+ EQ00135
+ 點講都係一家人 Episode 46
+ 1
+ 20240913
+ 1130
+ 0001
+ 3704000
+
+
+
+ 2024-09-13 12:30:00
+ 2024-09-13 13:30:00
+
+ false
+ false
+ 2024-09-27 12:30:00
+
+ 0
+
+ 0
+
+ http://tv.fantv.hk/images/thumbnail_1920_1080_fantv.jpg
+
+
+ ED00311
+ 0
+ 麝香之路
+ Ep. 2 .The Secret of disappeared kingdom.shows the mysterious disappearance of the ancient Tibetan kingdom which gained world
+ http://tv.fantv.hk/images/nosuchthumbnail.jpg
+
+
+
+ 麝香之路
+ 0
+ ED00311
+ 麝香之路 2024-09-13
+ 1
+ 20240913
+ 1230
+ 0001
+ 3704000
+
+
+
+ `
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe('https://epg-file.hoy.tv/hoy/OTT7620240913.xml')
+})
+
+it('can parse response', () => {
+ const result = parser({ content, channel, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ start: '2024-09-13T03:30:00.000Z',
+ stop: '2024-09-13T04:30:00.000Z',
+ title: '點講都係一家人[PG]',
+ sub_title: '第46集'
+ },
+ {
+ start: '2024-09-13T04:30:00.000Z',
+ stop: '2024-09-13T05:30:00.000Z',
+ title: '麝香之路',
+ description:
+ 'Ep. 2 .The Secret of disappeared kingdom.shows the mysterious disappearance of the ancient Tibetan kingdom which gained world'
+ }
+ ])
+})
diff --git a/sites/i.mjh.nz/i.mjh.nz.config.js b/sites/i.mjh.nz/i.mjh.nz.config.js
index f0a12a69..f29316a0 100644
--- a/sites/i.mjh.nz/i.mjh.nz.config.js
+++ b/sites/i.mjh.nz/i.mjh.nz.config.js
@@ -172,14 +172,17 @@ function parseItems(content, channel, date) {
if (!data || !Array.isArray(data.programs)) return []
return data.programs
- .filter(p => p.channel === site_id && dayjs(p.start, 'YYYYMMDDHHmmss ZZ').isBetween(curr_day, next_day))
+ .filter(
+ p =>
+ p.channel === site_id && dayjs(p.start, 'YYYYMMDDHHmmss ZZ').isBetween(curr_day, next_day)
+ )
.map(p => {
if (Array.isArray(p.date) && p.date.length) {
p.date = p.date[0]
}
return p
})
- } catch (error) {
+ } catch {
return []
}
}
diff --git a/sites/ipko.tv/ipko.tv.config.js b/sites/ipko.tv/ipko.tv.config.js
index 6658ee01..55803f1e 100644
--- a/sites/ipko.tv/ipko.tv.config.js
+++ b/sites/ipko.tv/ipko.tv.config.js
@@ -1,73 +1,80 @@
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-module.exports = {
- site: 'ipko.tv',
- timezone: 'Europe/Belgrade',
- days: 5,
- url({ date, channel }) { return 'https://stargate.ipko.tv/api/titan.tv.WebEpg/GetWebEpgData' },
- request: {
- method: 'POST',
- headers: {
- 'Host': 'stargate.ipko.tv',
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
- 'Accept': 'application/json, text/plain, */*',
- 'Accept-Language': 'nl,en-US;q=0.7,en;q=0.3',
- 'Content-Type': 'application/json',
- 'X-AppLayout': '1',
- 'x-language': 'sq',
- 'Origin': 'https://ipko.tv',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'cross-site',
- 'Sec-GPC': '1',
- 'Connection': 'keep-alive'
- },
- data({ channel, date }) {
- const todayEpoch = date.startOf('day').unix();
- const nextDayEpoch = date.add(1, 'day').startOf('day').unix();
- return JSON.stringify({
- ch_ext_id: channel.site_id,
- from: todayEpoch,
- to: nextDayEpoch
- })
- }
- },
- parser: function ({ content }) {
- const programs = [];
- const data = JSON.parse(content);
- data.shows.forEach(show => {
- const start = dayjs.unix(show.show_start).utc();
- const stop = dayjs.unix(show.show_end).utc();
- const programData = {
- title: show.title,
- description: show.summary || 'No description available',
- start: start.toISOString(),
- stop: stop.toISOString(),
- thumbnail: show.thumbnail
- }
- programs.push(programData)
- })
- return programs
- },
- async channels() {
- const response = await axios.post('https://stargate.ipko.tv/api/titan.tv.WebEpg/ZapList', JSON.stringify({ includeRadioStations: true }), {
- headers: this.request.headers
- });
-
- const data = response.data.data;
- return data.map(item => ({
- lang: 'sq',
- name: String(item.channel.title),
- site_id: String(item.channel.id),
- //logo: String(item.channel.logo)
- }))
- }
-}
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'ipko.tv',
+ timezone: 'Europe/Belgrade',
+ days: 5,
+ url() {
+ return 'https://stargate.ipko.tv/api/titan.tv.WebEpg/GetWebEpgData'
+ },
+ request: {
+ method: 'POST',
+ headers: {
+ Host: 'stargate.ipko.tv',
+ 'User-Agent':
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
+ Accept: 'application/json, text/plain, */*',
+ 'Accept-Language': 'nl,en-US;q=0.7,en;q=0.3',
+ 'Content-Type': 'application/json',
+ 'X-AppLayout': '1',
+ 'x-language': 'sq',
+ Origin: 'https://ipko.tv',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'cross-site',
+ 'Sec-GPC': '1',
+ Connection: 'keep-alive'
+ },
+ data({ channel, date }) {
+ const todayEpoch = date.startOf('day').unix()
+ const nextDayEpoch = date.add(1, 'day').startOf('day').unix()
+ return JSON.stringify({
+ ch_ext_id: channel.site_id,
+ from: todayEpoch,
+ to: nextDayEpoch
+ })
+ }
+ },
+ parser: function ({ content }) {
+ const programs = []
+ const data = JSON.parse(content)
+ data.shows.forEach(show => {
+ const start = dayjs.unix(show.show_start).utc()
+ const stop = dayjs.unix(show.show_end).utc()
+ const programData = {
+ title: show.title,
+ description: show.summary || 'No description available',
+ start: start.toISOString(),
+ stop: stop.toISOString(),
+ thumbnail: show.thumbnail
+ }
+ programs.push(programData)
+ })
+ return programs
+ },
+ async channels() {
+ const response = await axios.post(
+ 'https://stargate.ipko.tv/api/titan.tv.WebEpg/ZapList',
+ JSON.stringify({ includeRadioStations: true }),
+ {
+ headers: this.request.headers
+ }
+ )
+
+ const data = response.data.data
+ return data.map(item => ({
+ lang: 'sq',
+ name: String(item.channel.title),
+ site_id: String(item.channel.id)
+ //logo: String(item.channel.logo)
+ }))
+ }
+}
diff --git a/sites/ipko.tv/ipko.tv.test.js b/sites/ipko.tv/ipko.tv.test.js
index 2064eeb0..19a83e86 100644
--- a/sites/ipko.tv/ipko.tv.test.js
+++ b/sites/ipko.tv/ipko.tv.test.js
@@ -1,115 +1,111 @@
-const { parser, url } = require('./ipko.tv.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2024-12-24', 'YYYY-MM-DD').startOf('day')
-const channel = {
- site_id: 'ipko-promo',
- xmltv_id: 'IPKOPROMO'
-}
-
-it('can generate valid url', () => {
- expect(url({ date, channel })).toBe('https://stargate.ipko.tv/api/titan.tv.WebEpg/GetWebEpgData')
-})
-
-it('can parse response', () => {
- const content = `
- {
- "shows": [
- {
- "title": "IPKO Promo",
- "show_start": 1735012800,
- "show_end": 1735020000,
- "timestamp": "5:00 - 7:00",
- "show_id": "EPG_TvProfil_IPKOPROMO_296105567",
- "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
- "is_adult": false,
- "friendly_id": "ipko_promo_4cf3",
- "pg": "",
- "genres": [],
- "year": 0,
- "summary": "",
- "categories": "Other",
- "stb_only": false,
- "is_live": false,
- "original_title": "IPKO Promo"
- },
- {
- "title": "IPKO Promo",
- "show_start": 1735020000,
- "show_end": 1735027200,
- "timestamp": "7:00 - 9:00",
- "show_id": "EPG_TvProfil_IPKOPROMO_296105568",
- "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
- "is_adult": false,
- "friendly_id": "ipko_promo_416b",
- "pg": "",
- "genres": [],
- "year": 0,
- "summary": "",
- "categories": "Other",
- "stb_only": false,
- "is_live": false,
- "original_title": "IPKO Promo"
- },
- {
- "title": "IPKO Promo",
- "show_start": 1735027200,
- "show_end": 1735034400,
- "timestamp": "9:00 - 11:00",
- "show_id": "EPG_TvProfil_IPKOPROMO_296105569",
- "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
- "is_adult": false,
- "friendly_id": "ipko_promo_2e23",
- "pg": "",
- "genres": [],
- "year": 0,
- "summary": "",
- "categories": "Other",
- "stb_only": false,
- "is_live": false,
- "original_title": "IPKO Promo"
- }
- ]
- }`
-
- const result = parser({ content, channel }).map(p => {
- p.start = p.start
- p.stop = p.stop
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: "IPKO Promo",
- description: "No description available",
- start: "2024-12-24T04:00:00.000Z",
- stop: "2024-12-24T06:00:00.000Z",
- thumbnail: "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg"
- },
- {
- title: "IPKO Promo",
- description: "No description available",
- start: "2024-12-24T06:00:00.000Z",
- stop: "2024-12-24T08:00:00.000Z",
- thumbnail: "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg"
- },
- {
- title: "IPKO Promo",
- description: "No description available",
- start: "2024-12-24T08:00:00.000Z",
- stop: "2024-12-24T10:00:00.000Z",
- thumbnail: "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg"
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: '{"shows":[]}'
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./ipko.tv.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2024-12-24', 'YYYY-MM-DD').startOf('day')
+const channel = {
+ site_id: 'ipko-promo',
+ xmltv_id: 'IPKOPROMO'
+}
+
+it('can generate valid url', () => {
+ expect(url({ date, channel })).toBe('https://stargate.ipko.tv/api/titan.tv.WebEpg/GetWebEpgData')
+})
+
+it('can parse response', () => {
+ const content = `
+ {
+ "shows": [
+ {
+ "title": "IPKO Promo",
+ "show_start": 1735012800,
+ "show_end": 1735020000,
+ "timestamp": "5:00 - 7:00",
+ "show_id": "EPG_TvProfil_IPKOPROMO_296105567",
+ "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
+ "is_adult": false,
+ "friendly_id": "ipko_promo_4cf3",
+ "pg": "",
+ "genres": [],
+ "year": 0,
+ "summary": "",
+ "categories": "Other",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "IPKO Promo"
+ },
+ {
+ "title": "IPKO Promo",
+ "show_start": 1735020000,
+ "show_end": 1735027200,
+ "timestamp": "7:00 - 9:00",
+ "show_id": "EPG_TvProfil_IPKOPROMO_296105568",
+ "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
+ "is_adult": false,
+ "friendly_id": "ipko_promo_416b",
+ "pg": "",
+ "genres": [],
+ "year": 0,
+ "summary": "",
+ "categories": "Other",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "IPKO Promo"
+ },
+ {
+ "title": "IPKO Promo",
+ "show_start": 1735027200,
+ "show_end": 1735034400,
+ "timestamp": "9:00 - 11:00",
+ "show_id": "EPG_TvProfil_IPKOPROMO_296105569",
+ "thumbnail": "https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg",
+ "is_adult": false,
+ "friendly_id": "ipko_promo_2e23",
+ "pg": "",
+ "genres": [],
+ "year": 0,
+ "summary": "",
+ "categories": "Other",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "IPKO Promo"
+ }
+ ]
+ }`
+
+ const result = parser({ content, channel })
+
+ expect(result).toMatchObject([
+ {
+ title: 'IPKO Promo',
+ description: 'No description available',
+ start: '2024-12-24T04:00:00.000Z',
+ stop: '2024-12-24T06:00:00.000Z',
+ thumbnail: 'https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg'
+ },
+ {
+ title: 'IPKO Promo',
+ description: 'No description available',
+ start: '2024-12-24T06:00:00.000Z',
+ stop: '2024-12-24T08:00:00.000Z',
+ thumbnail: 'https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg'
+ },
+ {
+ title: 'IPKO Promo',
+ description: 'No description available',
+ start: '2024-12-24T08:00:00.000Z',
+ stop: '2024-12-24T10:00:00.000Z',
+ thumbnail: 'https://vimg.ipko.tv/mtcms/18/2/1/1821cc68-a9bf-4733-b1af-9a5d80163b78.jpg'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ content: '{"shows":[]}'
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/m.tv.sms.cz/m.tv.sms.cz.config.js b/sites/m.tv.sms.cz/m.tv.sms.cz.config.js
index b3dcd9c2..92861212 100644
--- a/sites/m.tv.sms.cz/m.tv.sms.cz.config.js
+++ b/sites/m.tv.sms.cz/m.tv.sms.cz.config.js
@@ -38,7 +38,7 @@ module.exports = {
async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://m.tv.sms.cz/?zmen_stanice=true`)
+ .get('https://m.tv.sms.cz/?zmen_stanice=true')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/magticom.ge/magticom.ge.config.js b/sites/magticom.ge/magticom.ge.config.js
index 0e5a475d..2a936ba1 100644
--- a/sites/magticom.ge/magticom.ge.config.js
+++ b/sites/magticom.ge/magticom.ge.config.js
@@ -77,8 +77,8 @@ function parseItems(content) {
let data
try {
data = JSON.parse(content)
- } catch (error) {
- console.log(error.message)
+ } catch {
+ return []
}
if (!data || !Array.isArray(data)) return []
diff --git a/sites/maxtv.hrvatskitelekom.hr/maxtv.hrvatskitelekom.hr.config.js b/sites/maxtv.hrvatskitelekom.hr/maxtv.hrvatskitelekom.hr.config.js
index c9723812..3dea9ef4 100644
--- a/sites/maxtv.hrvatskitelekom.hr/maxtv.hrvatskitelekom.hr.config.js
+++ b/sites/maxtv.hrvatskitelekom.hr/maxtv.hrvatskitelekom.hr.config.js
@@ -32,7 +32,7 @@ module.exports = {
async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://player.maxtvtogo.tportal.hr:8082/OTT4Proxy/proxy/epg/channels`)
+ .get('https://player.maxtvtogo.tportal.hr:8082/OTT4Proxy/proxy/epg/channels')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/mediaklikk.hu/mediaklikk.hu.config.js b/sites/mediaklikk.hu/mediaklikk.hu.config.js
index 07d17a30..673fb4b3 100644
--- a/sites/mediaklikk.hu/mediaklikk.hu.config.js
+++ b/sites/mediaklikk.hu/mediaklikk.hu.config.js
@@ -56,7 +56,7 @@ function parseStop($item) {
try {
return dayjs(timeString, 'YYYY-MM-DD HH:mm:ssZZ')
- } catch (err) {
+ } catch {
return null
}
}
diff --git a/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.config.js b/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.config.js
index 9997eda8..3a168953 100644
--- a/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.config.js
+++ b/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.config.js
@@ -1,93 +1,97 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const timezone = require('dayjs/plugin/timezone')
-
-dayjs.extend(utc)
-dayjs.extend(customParseFormat)
-dayjs.extend(timezone)
-
-module.exports = {
- site: 'mediasetinfinity.mediaset.it',
- days: 2,
- url: function ({date, channel}) {
- // Get the epoch timestamp
- const todayEpoch = date.startOf('day').utc().valueOf()
- // Get the epoch timestamp for the next day
- const nextDayEpoch = date.add(1, 'day').startOf('day').utc().valueOf()
- return `https://api-ott-prod-fe.mediaset.net/PROD/play/feed/allListingFeedEpg/v2.0?byListingTime=${todayEpoch}~${nextDayEpoch}&byCallSign=${channel.site_id}`
- },
- parser: function ({content}) {
- const programs = []
- const data = JSON.parse(content)
-
- if (!data.response || !data.response.entries || !data.response.entries[0] || !data.response.entries[0].listings) {
- // If the structure is not as expected, return an empty array
- return programs
- }
-
- const listings = data.response.entries[0].listings
-
- listings.forEach((listing) => {
- const title = listing.mediasetlisting$epgTitle
- const subTitle = listing.program.title
- const season = parseSeason(listing)
- const episode = parseEpisode(listing)
-
-
- if (listing.program.title && listing.startTime && listing.endTime) {
- programs.push({
- title: title || subTitle,
- sub_title: title && title != subTitle ? subTitle : null,
- description: listing.program.description || null,
- category: listing.program.mediasetprogram$skyGenre || null,
- season: episode && !season ? '0' : season,
- episode: episode,
- start: parseTime(listing.startTime),
- stop: parseTime(listing.endTime),
- image: getMaxResolutionThumbnails(listing)
- })
- }
- })
-
- return programs
- }
-}
-
-
-function parseTime(timestamp) {
- return dayjs(timestamp).utc().format('YYYY-MM-DD HH:mm')
-}
-
-function parseSeason(item) {
- if (!item.mediasetlisting$shortDescription) return null
- const season = item.mediasetlisting$shortDescription.match(/S(\d+)\s/)
- return season ? season[1] : null
-}
-
-function parseEpisode(item) {
- if (!item.mediasetlisting$shortDescription) return null
- const episode = item.mediasetlisting$shortDescription.match(/Ep(\d+)\s/)
- return episode ? episode[1] : null
-}
-
-function getMaxResolutionThumbnails(item) {
- const thumbnails = item.program.thumbnails || null
- const maxResolutionThumbnails = {}
-
- for (const key in thumbnails) {
- const type = key.split('-')[0] // Estrarre il tipo di thumbnail
- const {width, height, url, title} = thumbnails[key]
-
- if (!maxResolutionThumbnails[type] ||
- (width * height > maxResolutionThumbnails[type].width * maxResolutionThumbnails[type].height)) {
- maxResolutionThumbnails[type] = {width, height, url, title}
- }
- }
- if (maxResolutionThumbnails.image_keyframe_poster)
- return maxResolutionThumbnails.image_keyframe_poster.url
- else if (maxResolutionThumbnails.image_header_poster)
- return maxResolutionThumbnails.image_header_poster.url
- else
- return null
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(utc)
+dayjs.extend(customParseFormat)
+dayjs.extend(timezone)
+
+module.exports = {
+ site: 'mediasetinfinity.mediaset.it',
+ days: 2,
+ url: function ({ date, channel }) {
+ // Get the epoch timestamp
+ const todayEpoch = date.startOf('day').utc().valueOf()
+ // Get the epoch timestamp for the next day
+ const nextDayEpoch = date.add(1, 'day').startOf('day').utc().valueOf()
+ return `https://api-ott-prod-fe.mediaset.net/PROD/play/feed/allListingFeedEpg/v2.0?byListingTime=${todayEpoch}~${nextDayEpoch}&byCallSign=${channel.site_id}`
+ },
+ parser: function ({ content }) {
+ const programs = []
+ const data = JSON.parse(content)
+
+ if (
+ !data.response ||
+ !data.response.entries ||
+ !data.response.entries[0] ||
+ !data.response.entries[0].listings
+ ) {
+ // If the structure is not as expected, return an empty array
+ return programs
+ }
+
+ const listings = data.response.entries[0].listings
+
+ listings.forEach(listing => {
+ const title = listing.mediasetlisting$epgTitle
+ const subTitle = listing.program.title
+ const season = parseSeason(listing)
+ const episode = parseEpisode(listing)
+
+ if (listing.program.title && listing.startTime && listing.endTime) {
+ programs.push({
+ title: title || subTitle,
+ sub_title: title && title != subTitle ? subTitle : null,
+ description: listing.program.description || null,
+ category: listing.program.mediasetprogram$skyGenre || null,
+ season: episode && !season ? '0' : season,
+ episode: episode,
+ start: parseTime(listing.startTime),
+ stop: parseTime(listing.endTime),
+ image: getMaxResolutionThumbnails(listing)
+ })
+ }
+ })
+
+ return programs
+ }
+}
+
+function parseTime(timestamp) {
+ return dayjs(timestamp).utc().format('YYYY-MM-DD HH:mm')
+}
+
+function parseSeason(item) {
+ if (!item.mediasetlisting$shortDescription) return null
+ const season = item.mediasetlisting$shortDescription.match(/S(\d+)\s/)
+ return season ? season[1] : null
+}
+
+function parseEpisode(item) {
+ if (!item.mediasetlisting$shortDescription) return null
+ const episode = item.mediasetlisting$shortDescription.match(/Ep(\d+)\s/)
+ return episode ? episode[1] : null
+}
+
+function getMaxResolutionThumbnails(item) {
+ const thumbnails = item.program.thumbnails || null
+ const maxResolutionThumbnails = {}
+
+ for (const key in thumbnails) {
+ const type = key.split('-')[0] // Estrarre il tipo di thumbnail
+ const { width, height, url, title } = thumbnails[key]
+
+ if (
+ !maxResolutionThumbnails[type] ||
+ width * height > maxResolutionThumbnails[type].width * maxResolutionThumbnails[type].height
+ ) {
+ maxResolutionThumbnails[type] = { width, height, url, title }
+ }
+ }
+ if (maxResolutionThumbnails.image_keyframe_poster)
+ return maxResolutionThumbnails.image_keyframe_poster.url
+ else if (maxResolutionThumbnails.image_header_poster)
+ return maxResolutionThumbnails.image_header_poster.url
+ else return null
+}
diff --git a/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.test.js b/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.test.js
index 528d9200..c1c8ce11 100644
--- a/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.test.js
+++ b/sites/mediasetinfinity.mediaset.it/mediasetinfinity.mediaset.it.test.js
@@ -1,46 +1,53 @@
-const {parser, url} = require('./mediasetinfinity.mediaset.it.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2024-01-20', 'YYYY-MM-DD').startOf('d')
-const channel = {
- site_id: 'LB', xmltv_id: '20.it'
-}
-
-it('can generate valid url', () => {
- expect(url({
- channel,
- date
- })).toBe('https://api-ott-prod-fe.mediaset.net/PROD/play/feed/allListingFeedEpg/v2.0?byListingTime=1705708800000~1705795200000&byCallSign=LB')
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'), 'utf8')
- const results = parser({content, date}).map(p => {
- return p
- })
-
- expect(results[3]).toMatchObject({
- start: '2024-01-20 02:14',
- stop: '2024-01-20 02:54',
- title: 'Chicago Fire',
- sub_title: 'Ep. 22 - Io non ti lascio',
- description: 'Severide e Kidd continuano a indagare su un vecchio caso doloso di Benny. Notizie inaspettate portano Brett a meditare su una grande decisione.',
- category: 'Intrattenimento',
- season: '7',
- episode: '22',
- image: 'https://static2.mediasetplay.mediaset.it/Mediaset_Italia_Production_-_Main/F309370301002204/media/0/0/1ef76b73-3173-43bd-9c16-73986a0ec131/46896726-11e7-4438-b947-d2ae53f58c0b.jpg'
- })
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: '[]'
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./mediasetinfinity.mediaset.it.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2024-01-20', 'YYYY-MM-DD').startOf('d')
+const channel = {
+ site_id: 'LB',
+ xmltv_id: '20.it'
+}
+
+it('can generate valid url', () => {
+ expect(
+ url({
+ channel,
+ date
+ })
+ ).toBe(
+ 'https://api-ott-prod-fe.mediaset.net/PROD/play/feed/allListingFeedEpg/v2.0?byListingTime=1705708800000~1705795200000&byCallSign=LB'
+ )
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'), 'utf8')
+ const results = parser({ content, date }).map(p => {
+ return p
+ })
+
+ expect(results[3]).toMatchObject({
+ start: '2024-01-20 02:14',
+ stop: '2024-01-20 02:54',
+ title: 'Chicago Fire',
+ sub_title: 'Ep. 22 - Io non ti lascio',
+ description:
+ 'Severide e Kidd continuano a indagare su un vecchio caso doloso di Benny. Notizie inaspettate portano Brett a meditare su una grande decisione.',
+ category: 'Intrattenimento',
+ season: '7',
+ episode: '22',
+ image:
+ 'https://static2.mediasetplay.mediaset.it/Mediaset_Italia_Production_-_Main/F309370301002204/media/0/0/1ef76b73-3173-43bd-9c16-73986a0ec131/46896726-11e7-4438-b947-d2ae53f58c0b.jpg'
+ })
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ content: '[]'
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/meo.pt/meo.pt.config.js b/sites/meo.pt/meo.pt.config.js
index 55e74434..d3aa53a5 100644
--- a/sites/meo.pt/meo.pt.config.js
+++ b/sites/meo.pt/meo.pt.config.js
@@ -40,7 +40,7 @@ module.exports = {
async channels() {
const axios = require('axios')
const data = await axios
- .post(`https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getGridAnon`, null, {
+ .post('https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getGridAnon', null, {
headers: {
Origin: 'https://www.meo.pt'
}
diff --git a/sites/meuguia.tv/meuguia.tv.config.js b/sites/meuguia.tv/meuguia.tv.config.js
index c877a08f..e86f2bfa 100644
--- a/sites/meuguia.tv/meuguia.tv.config.js
+++ b/sites/meuguia.tv/meuguia.tv.config.js
@@ -1,101 +1,105 @@
-const cheerio = require('cheerio')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-module.exports = {
- site: 'meuguia.tv',
- days: 2,
- url({ channel }) {
- return `https://meuguia.tv/programacao/canal/${channel.site_id}`
- },
- parser({ content, date }) {
- const programs = []
- parseItems(content, date).forEach(item => {
- if (dayjs.utc(item.start).isSame(date, 'day')) {
- programs.push(item)
- }
- })
-
- return programs
- },
- async channels() {
- const channels = []
- const axios = require('axios')
- const baseUrl = 'https://meuguia.tv'
-
- let seq = 0
- const queues = [baseUrl]
- while (true) {
- if (!queues.length) {
- break
- }
- const url = queues.shift()
- const content = await axios
- .get(url)
- .then(response => response.data)
- .catch(console.error)
-
- if (content) {
- const [ $, items ] = getItems(content)
- if (seq === 0) {
- queues.push(...items.map(category => baseUrl + $(category).attr('href')))
- } else {
- items.forEach(item => {
- const href = $(item).attr('href')
- channels.push({
- lang: 'pt',
- site_id: href.substr(href.lastIndexOf('/') + 1),
- name: $(item).find('.licontent h2').text().trim()
- })
- })
- }
- }
- seq++
- }
-
- return channels
- }
-}
-
-function getItems(content) {
- const $ = cheerio.load(content)
- return [$, $('div.mw ul li a').toArray()]
-}
-
-function parseItems(content, date) {
- const result = []
- const $ = cheerio.load(content)
-
- let lastDate
- for (const item of $('ul.mw li').toArray()) {
- const $item = $(item)
- if ($item.hasClass('subheader')) {
- lastDate = `${$item.text().split(', ')[1]}/${date.format('YYYY')}`
- } else if ($item.hasClass('divider')) {
- // ignore
- } else if (lastDate) {
- const data = { title: $item.find('a').attr('title').trim() }
- const ep = data.title.match(/T(\d+) EP(\d+)/)
- if (ep) {
- data.season = parseInt(ep[1])
- data.episode = parseInt(ep[2])
- }
- data.start = dayjs.tz(`${lastDate} ${$item.find('.time').text()}`, 'DD/MM/YYYY HH:mm', 'America/Sao_Paulo')
- result.push(data)
- }
- }
- // use stop time from next item
- if (result.length > 1) {
- for (let i = 0; i < result.length - 1; i++) {
- result[i].stop = result[i + 1].start
- }
- }
-
- return result
-}
\ No newline at end of file
+const cheerio = require('cheerio')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'meuguia.tv',
+ days: 2,
+ url({ channel }) {
+ return `https://meuguia.tv/programacao/canal/${channel.site_id}`
+ },
+ parser({ content, date }) {
+ const programs = []
+ parseItems(content, date).forEach(item => {
+ if (dayjs.utc(item.start).isSame(date, 'day')) {
+ programs.push(item)
+ }
+ })
+
+ return programs
+ },
+ async channels() {
+ const channels = []
+ const axios = require('axios')
+ const baseUrl = 'https://meuguia.tv'
+
+ let seq = 0
+ const queues = [baseUrl]
+ while (true) {
+ if (!queues.length) {
+ break
+ }
+ const url = queues.shift()
+ const content = await axios
+ .get(url)
+ .then(response => response.data)
+ .catch(console.error)
+
+ if (content) {
+ const [$, items] = getItems(content)
+ if (seq === 0) {
+ queues.push(...items.map(category => baseUrl + $(category).attr('href')))
+ } else {
+ items.forEach(item => {
+ const href = $(item).attr('href')
+ channels.push({
+ lang: 'pt',
+ site_id: href.substr(href.lastIndexOf('/') + 1),
+ name: $(item).find('.licontent h2').text().trim()
+ })
+ })
+ }
+ }
+ seq++
+ }
+
+ return channels
+ }
+}
+
+function getItems(content) {
+ const $ = cheerio.load(content)
+ return [$, $('div.mw ul li a').toArray()]
+}
+
+function parseItems(content, date) {
+ const result = []
+ const $ = cheerio.load(content)
+
+ let lastDate
+ for (const item of $('ul.mw li').toArray()) {
+ const $item = $(item)
+ if ($item.hasClass('subheader')) {
+ lastDate = `${$item.text().split(', ')[1]}/${date.format('YYYY')}`
+ } else if ($item.hasClass('divider')) {
+ // ignore
+ } else if (lastDate) {
+ const data = { title: $item.find('a').attr('title').trim() }
+ const ep = data.title.match(/T(\d+) EP(\d+)/)
+ if (ep) {
+ data.season = parseInt(ep[1])
+ data.episode = parseInt(ep[2])
+ }
+ data.start = dayjs.tz(
+ `${lastDate} ${$item.find('.time').text()}`,
+ 'DD/MM/YYYY HH:mm',
+ 'America/Sao_Paulo'
+ )
+ result.push(data)
+ }
+ }
+ // use stop time from next item
+ if (result.length > 1) {
+ for (let i = 0; i < result.length - 1; i++) {
+ result[i].stop = result[i + 1].start
+ }
+ }
+
+ return result
+}
diff --git a/sites/meuguia.tv/meuguia.tv.test.js b/sites/meuguia.tv/meuguia.tv.test.js
index c121039c..3fe2ce94 100644
--- a/sites/meuguia.tv/meuguia.tv.test.js
+++ b/sites/meuguia.tv/meuguia.tv.test.js
@@ -1,60 +1,60 @@
-const { parser, url } = require('./meuguia.tv.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-11-21').startOf('d')
-const channel = {
- site_id: 'AXN',
- xmltv_id: 'AXN.id'
-}
-it('can generate valid url', () => {
- expect(url({ channel })).toBe('https://meuguia.tv/programacao/canal/AXN')
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
- const result = parser({ content, channel, date }).map(p => {
- p.start = p.start.toJSON()
- if (p.stop) {
- p.stop = p.stop.toJSON()
- }
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: 'Hawaii Five-0 : T10 EP4 - Tiny Is the Flower, Yet It Scents the Grasses Around It',
- start: '2023-11-21T21:20:00.000Z',
- stop: '2023-11-21T22:15:00.000Z',
- season: 10,
- episode: 4
- },
- {
- title:
- "Hawaii Five-0 : T10 EP5 - Don't Blame Ghosts and Spirits for One's Troubles; A Human Is Responsible",
- start: '2023-11-21T22:15:00.000Z',
- stop: '2023-11-21T23:10:00.000Z',
- season: 10,
- episode: 5
- },
- {
- title: 'NCIS : T5 EP15 - In the Zone',
- start: '2023-11-21T23:10:00.000Z',
- season: 5,
- episode: 15
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- date,
- channel,
- content: ''
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./meuguia.tv.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-11-21').startOf('d')
+const channel = {
+ site_id: 'AXN',
+ xmltv_id: 'AXN.id'
+}
+it('can generate valid url', () => {
+ expect(url({ channel })).toBe('https://meuguia.tv/programacao/canal/AXN')
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
+ const result = parser({ content, channel, date }).map(p => {
+ p.start = p.start.toJSON()
+ if (p.stop) {
+ p.stop = p.stop.toJSON()
+ }
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Hawaii Five-0 : T10 EP4 - Tiny Is the Flower, Yet It Scents the Grasses Around It',
+ start: '2023-11-21T21:20:00.000Z',
+ stop: '2023-11-21T22:15:00.000Z',
+ season: 10,
+ episode: 4
+ },
+ {
+ title:
+ "Hawaii Five-0 : T10 EP5 - Don't Blame Ghosts and Spirits for One's Troubles; A Human Is Responsible",
+ start: '2023-11-21T22:15:00.000Z',
+ stop: '2023-11-21T23:10:00.000Z',
+ season: 10,
+ episode: 5
+ },
+ {
+ title: 'NCIS : T5 EP15 - In the Zone',
+ start: '2023-11-21T23:10:00.000Z',
+ season: 5,
+ episode: 15
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ date,
+ channel,
+ content: ''
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/mewatch.sg/mewatch.sg.config.js b/sites/mewatch.sg/mewatch.sg.config.js
index 1559fdf0..1b793c83 100644
--- a/sites/mewatch.sg/mewatch.sg.config.js
+++ b/sites/mewatch.sg/mewatch.sg.config.js
@@ -42,7 +42,7 @@ module.exports = {
const axios = require('axios')
const cheerio = require('cheerio')
const data = await axios
- .get(`https://www.mewatch.sg/channel-guide`)
+ .get('https://www.mewatch.sg/channel-guide')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/mncvision.id/mncvision.id.config.js b/sites/mncvision.id/mncvision.id.config.js
index ba944503..2dd7d94f 100644
--- a/sites/mncvision.id/mncvision.id.config.js
+++ b/sites/mncvision.id/mncvision.id.config.js
@@ -11,9 +11,7 @@ dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
-doFetch
- .setCheckResult(false)
- .setDebugger(debug)
+doFetch.setCheckResult(false).setDebugger(debug)
const languages = { en: 'english', id: 'indonesia' }
const cookies = {}
@@ -125,7 +123,7 @@ async function parseItems(content, date, cookies) {
const url = $item.find('a').attr('href')
const headers = {
'X-Requested-With': 'XMLHttpRequest',
- Cookie: cookies,
+ Cookie: cookies
}
queues.push({ i: $item, url, params: { headers, timeout } })
}
diff --git a/sites/moji.id/moji.id.config.js b/sites/moji.id/moji.id.config.js
index 80c1baf7..ee6d6db2 100644
--- a/sites/moji.id/moji.id.config.js
+++ b/sites/moji.id/moji.id.config.js
@@ -48,8 +48,10 @@ function parseItems(context) {
schDayPrograms.forEach((program, i) => {
const itemDay = {
progStart: parseStart($(schDayMonth), $(program)),
- progStop: parseStop($(schDayMonth), schDayPrograms[i + 1] ?
- $(schDayPrograms[i + 1]) : null),
+ progStop: parseStop(
+ $(schDayMonth),
+ schDayPrograms[i + 1] ? $(schDayPrograms[i + 1]) : null
+ ),
progTitle: parseTitle($(program)),
progDesc: parseDescription($(program))
}
@@ -91,7 +93,9 @@ function parseStop(schDayMonth, itemNext) {
)
} else {
return dayjs.tz(
- `${currentYear}-${monthDate[0]}-${(parseInt(monthDate[1]) + 1).toString().padStart(2, '0')} 00:00`,
+ `${currentYear}-${monthDate[0]}-${(parseInt(monthDate[1]) + 1)
+ .toString()
+ .padStart(2, '0')} 00:00`,
'YYYY-MMM-DD HH:mm',
tz
)
diff --git a/sites/moji.id/moji.id.test.js b/sites/moji.id/moji.id.test.js
index ca2ddc55..452a7072 100644
--- a/sites/moji.id/moji.id.test.js
+++ b/sites/moji.id/moji.id.test.js
@@ -1,15 +1,9 @@
-const { url, parser } = require('./moji.id.config.js')
+const { parser } = require('./moji.id.config.js')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
const date = dayjs.utc('2023-08-18', 'YYYY-MM-DD').startOf('d')
-const channel = {
- site_id: '0',
- xmltv_id: 'moji.id',
- lang: 'en',
- logo: 'https://moji.id/site/uploads/logo/62f9387ce00a2-224-x-71.png'
-}
const content =
'
schedule Jam Tayang Program
00:00 TRUST
Informasi seputar menjaga vitalitas pria
00:30 2023 AVC CHALLENGE CUP FOR WOMEN (RECORDED)
India Vs. Vietnam
02:30 ONE CHAMPIONSHIP 2021
Siaran laga-laga pertandingan tinju gaya bebas internasional. Meyuguhkan pertarungan sengit dari para petarung profeisional kelas dunia.
03:30 VOLLEYBALL NATION\'S LEAGUE 2023 (RECORDED)
TURKI vs BRAZIL
05:00 MOJI SPORT
MOJI SPORT
06:15 LIPUTAN 6 PAGI MOJI
Kompilasi ragam berita hard news dan soft news baik dari dalam negeri maupun internasional juga info prediksi cuaca di wilayah Indonesia
07:00 UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
08:00 PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
10:30 SERIES PAGI
GANTENG GANTENG SERIGALA
12:30 DIAM-DIAM SUKA
DIAM-DIAM SUKA
13:30 PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
16:00 PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
18:00 PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
20:00 MOJI DRAMA (CHHOTI SARDARNI)
CHHOTI SARDARNI
21:30 SINEMA MALAM (BIDADARI CANTIK DI RUMAH KOST)
(BIDADARI CANTIK DI RUMAH KOST
23:00 TRUST
Informasi seputar menjaga vitalitas pria
23:30 TRUST
Informasi seputar menjaga vitalitas pria
00:00 TRUST
Informasi seputar menjaga vitalitas pria
00:30 UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
01:00 EXCLUSIVE INTERVIEW
PETER SCHMEICHEL
01:30 PREMIER LEAGUE (LIVE)
NOTT\'M FOREST VS SHEFFIELD UTD
03:30 VOLLEYBALL NATION\'S LEAGUE 2023 FOR WOMEN (RECORDED)
GERMANY vs USA
05:00 MOJI SPORT
MOJI SPORT
06:15 LIPUTAN 6 PAGI MOJI
Kompilasi ragam berita hard news dan soft news baik dari dalam negeri maupun internasional juga info prediksi cuaca di wilayah Indonesia
07:00 UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
08:00 TRUST
Informasi Kesehatan
08:30 TRUST
Informasi Kesehatan
09:00 MASAK APA CEU?
Jenny Hendrawati, seorang koki selebritis, menyajikan beraneka hidangan internasional serta membagikan tips-tips seputar dunia memasak yang mudah diikuti oleh para pemirsa di rumah.
09:30 BISIK PAGI
berbagai berita dan perkembangan terbaru dari sederet kasus yang menimpa sejumlah sosok ternama di Indonesia.
10:30 GANTENG GANTENG SERIGALA
GANTENG GANTENG SERIGALA
11:30 PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
14:00 PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
16:00 PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
18:00 PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
20:00 MOJI DRAMA (CHHOTI SARDARNI)
CHHOTI SARDARNI
20:45 PREMIER LEAGUE (LIVE)
WOLVES VS BRIGHTON
00:00 TRUST
Informasi seputar menjaga vitalitas pria
00:30 2023 AVC CHALLENGE CUP FOR WOMEN (RECORDED)
Chinese Taipei Vs. India
02:30 ONE CHAMPIONSHIP 2021
Siaran laga-laga pertandingan tinju gaya bebas internasional. Meyuguhkan pertarungan sengit dari para petarung profeisional kelas dunia.
03:30 VOLLEYBALL NATION\'S LEAGUE 2023 FOR WOMEN (RECORDED)
THAILAND vs JAPAN
05:00 MOJI SPORT
MOJI SPORT
06:15 LIPUTAN 6 PAGI MOJI
Kompilasi ragam berita hard news dan soft news baik dari dalam negeri maupun internasional juga info prediksi cuaca di wilayah Indonesia
07:00 UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
08:00 TRUST
Informasi Kesehatan
08:30 TRUST
Informasi Kesehatan
09:00 MASAK APA CEU?
Jenny Hendrawati, seorang koki selebritis, menyajikan beraneka hidangan internasional serta membagikan tips-tips seputar dunia memasak yang mudah diikuti oleh para pemirsa di rumah.
09:30 BISIK PAGI
berbagai berita dan perkembangan terbaru dari sederet kasus yang menimpa sejumlah sosok ternama di Indonesia.
10:30 GANTENG GANTENG SERIGALA
GANTENG GANTENG SERIGALA
12:30 DIAM-DIAM SUKA
DIAM-DIAM SUKA
16:00 SEA VLEAGUE (RECORDED)
PHILIPPINES VS INDONESIA
18:00 NETIZEN UPDATE
berbagai berita dan perkembangan terbaru dari sederet kasus yang menimpa sejumlah sosok ternama di Indonesia.
19:00 MOJI DRAMA (CHHOTI SARDARNI)
CHHOTI SARDARNI
21:00 MOJI MOVIE (LONDON LOVE STORY)
LONDON LOVE STORY
23:00 TRUST
Informasi seputar menjaga vitalitas pria
23:30 TRUST
Informasi seputar menjaga vitalitas pria
'
@@ -20,12 +14,11 @@ it('can handle empty guide', () => {
})
it('can parse response', () => {
- const results = parser({ content, date })
- .map(p => {
- p.start = p.start.year(2023).toJSON()
- p.stop = p.stop.year(2023).toJSON()
- return p
- })
+ const results = parser({ content, date }).map(p => {
+ p.start = p.start.year(2023).toJSON()
+ p.stop = p.stop.year(2023).toJSON()
+ return p
+ })
expect(results[0]).toMatchObject({
title: 'TRUST',
diff --git a/sites/mtel.ba/mtel.ba.config.js b/sites/mtel.ba/mtel.ba.config.js
index 2da967bd..d2a6cc85 100644
--- a/sites/mtel.ba/mtel.ba.config.js
+++ b/sites/mtel.ba/mtel.ba.config.js
@@ -41,7 +41,7 @@ module.exports = {
const pages = Array.from(Array(totalPages).keys())
for (let page of pages) {
const data = await axios
- .get(`https://mtel.ba/oec/epg/program`, {
+ .get('https://mtel.ba/oec/epg/program', {
params: { page, date: dayjs().format('YYYY-MM-DD') },
headers: {
'X-Requested-With': 'XMLHttpRequest'
@@ -65,7 +65,7 @@ module.exports = {
async function getTotalPageCount() {
const data = await axios
- .get(`https://mtel.ba/oec/epg/program`, {
+ .get('https://mtel.ba/oec/epg/program', {
params: { page: 0, date: dayjs().format('YYYY-MM-DD') },
headers: {
'X-Requested-With': 'XMLHttpRequest'
diff --git a/sites/mts.rs/mts.rs.config.js b/sites/mts.rs/mts.rs.config.js
index 251cae94..8b700c38 100644
--- a/sites/mts.rs/mts.rs.config.js
+++ b/sites/mts.rs/mts.rs.config.js
@@ -43,7 +43,7 @@ module.exports = {
const pages = Array.from(Array(totalPages).keys())
for (let page of pages) {
const data = await axios
- .get(`https://mts.rs/oec/epg/program`, {
+ .get('https://mts.rs/oec/epg/program', {
params: { page, date: dayjs().format('YYYY-MM-DD') },
headers: {
'X-Requested-With': 'XMLHttpRequest'
@@ -67,7 +67,7 @@ module.exports = {
async function getTotalPageCount() {
const data = await axios
- .get(`https://mts.rs/oec/epg/program`, {
+ .get('https://mts.rs/oec/epg/program', {
params: { page: 0, date: dayjs().format('YYYY-MM-DD') },
headers: {
'X-Requested-With': 'XMLHttpRequest'
@@ -84,8 +84,8 @@ function parseContent(content, channel) {
let data
try {
data = JSON.parse(content)
- } catch (error) {
- console.log(error)
+ } catch {
+ return []
}
if (!data || !data.channels || !data.channels.length) return null
diff --git a/sites/mujtvprogram.cz/mujtvprogram.cz.config.js b/sites/mujtvprogram.cz/mujtvprogram.cz.config.js
index e544721c..0a8ddb95 100644
--- a/sites/mujtvprogram.cz/mujtvprogram.cz.config.js
+++ b/sites/mujtvprogram.cz/mujtvprogram.cz.config.js
@@ -47,7 +47,7 @@ module.exports = {
const data = await axios
.post(
- `https://services.mujtvprogram.cz/tvprogram2services/services/tvchannellist_mobile.php`,
+ 'https://services.mujtvprogram.cz/tvprogram2services/services/tvchannellist_mobile.php',
params,
{
headers: {
@@ -86,7 +86,7 @@ function parseItems(content) {
if (!data) return []
const programmes = data['tv-program-programmes'].programme
return programmes && Array.isArray(programmes) ? programmes : []
- } catch (err) {
+ } catch {
return []
}
}
diff --git a/sites/musor.tv/musor.tv.config.js b/sites/musor.tv/musor.tv.config.js
index 5900d6f6..d645a811 100644
--- a/sites/musor.tv/musor.tv.config.js
+++ b/sites/musor.tv/musor.tv.config.js
@@ -9,7 +9,7 @@ dayjs.extend(customParseFormat)
const headers = {
'User-Agent':
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0',
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0'
}
module.exports = {
diff --git a/sites/musor.tv/musor.tv.test.js b/sites/musor.tv/musor.tv.test.js
index 42ed2d4b..98bbd4be 100644
--- a/sites/musor.tv/musor.tv.test.js
+++ b/sites/musor.tv/musor.tv.test.js
@@ -26,12 +26,11 @@ it('can generate valid url for today', () => {
it('can parse response', () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
- const results = parser({ content, date })
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ const results = parser({ content, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(results[0]).toMatchObject({
start: '2022-11-19T23:00:00.000Z',
diff --git a/sites/mytelly.co.uk/mytelly.co.uk.config.js b/sites/mytelly.co.uk/mytelly.co.uk.config.js
index 282f8dc4..6ebe128a 100644
--- a/sites/mytelly.co.uk/mytelly.co.uk.config.js
+++ b/sites/mytelly.co.uk/mytelly.co.uk.config.js
@@ -23,14 +23,15 @@ module.exports = {
channel.site_id
}.html?dt=${date.format('YYYY-MM-DD')}`
},
- async parser({ content, date, channel }) {
+ async parser({ content, date }) {
const programs = []
if (content) {
const queues = []
const $ = cheerio.load(content)
- $('table.table > tbody > tr').toArray()
+ $('table.table > tbody > tr')
+ .toArray()
.forEach(el => {
const td = $(el).find('td:eq(1)')
const title = td.find('h5 a')
@@ -66,12 +67,16 @@ module.exports = {
const subTitle = parseText($('.tab-pane > h5 > strong'))
const description = parseText($('.tab-pane > .tvbody > p'))
const image = $('.program-media-image img').attr('src')
- const category = $('.schedule-attributes-genres span').toArray()
+ const category = $('.schedule-attributes-genres span')
+ .toArray()
.map(el => $(el).text())
- const casts = $('.single-cast-head:not([id])').toArray()
+ const casts = $('.single-cast-head:not([id])')
+ .toArray()
.map(el => {
const cast = { name: parseText($(el).find('a')) }
- const [, role] = $(el).text().match(/\((.*)\)/) || [null, null]
+ const [, role] = $(el)
+ .text()
+ .match(/\((.*)\)/) || [null, null]
if (role) {
cast.role = role
}
@@ -102,7 +107,7 @@ module.exports = {
start,
stop
})
- })
+ })
}
}
@@ -115,11 +120,17 @@ module.exports = {
// process form -> provider
if (queue.t === 'p') {
const $ = cheerio.load(res)
- $('#guide_provider option').toArray()
+ $('#guide_provider option')
+ .toArray()
.forEach(el => {
const opt = $(el)
const provider = opt.attr('value')
- queues.push({ t: 'r', method: 'post', url: 'https://www.mytelly.co.uk/getregions', params: { provider } })
+ queues.push({
+ t: 'r',
+ method: 'post',
+ url: 'https://www.mytelly.co.uk/getregions',
+ params: { provider }
+ })
})
}
// process provider -> region
@@ -135,26 +146,30 @@ module.exports = {
u_time: now.format('HHmm'),
is_mobile: 1
}
- queues.push({ t: 's', method: 'post', url: 'https://www.mytelly.co.uk/tv-guide/schedule', params })
+ queues.push({
+ t: 's',
+ method: 'post',
+ url: 'https://www.mytelly.co.uk/tv-guide/schedule',
+ params
+ })
}
}
// process schedule -> channels
if (queue.t === 's') {
const $ = cheerio.load(res)
- $('.channelname')
- .each((i, el) => {
- const name = $(el).find('center > a:eq(1)').text()
- const url = $(el).find('center > a:eq(1)').attr('href')
- const [, number, slug] = url.match(/\/(\d+)\/(.*)\.html$/)
- const site_id = `${number}/${slug}`
- if (channels[site_id] === undefined) {
- channels[site_id] = {
- lang: 'en',
- site_id,
- name
- }
+ $('.channelname').each((i, el) => {
+ const name = $(el).find('center > a:eq(1)').text()
+ const url = $(el).find('center > a:eq(1)').attr('href')
+ const [, number, slug] = url.match(/\/(\d+)\/(.*)\.html$/)
+ const site_id = `${number}/${slug}`
+ if (channels[site_id] === undefined) {
+ channels[site_id] = {
+ lang: 'en',
+ site_id,
+ name
}
- })
+ }
+ })
}
})
@@ -178,13 +193,10 @@ function parseTime(date, time) {
}
function parseText($item) {
- let text = $item.text()
- .replace(/\t/g, '')
- .replace(/\n/g, ' ')
- .trim()
+ let text = $item.text().replace(/\t/g, '').replace(/\n/g, ' ').trim()
while (true) {
- if (text.match(/ /)) {
- text = text.replace(/ /g, ' ')
+ if (text.match(/\s\s/)) {
+ text = text.replace(/\s\s/g, ' ')
continue
}
break
diff --git a/sites/mytelly.co.uk/mytelly.co.uk.test.js b/sites/mytelly.co.uk/mytelly.co.uk.test.js
index 20f6ced0..6199a416 100644
--- a/sites/mytelly.co.uk/mytelly.co.uk.test.js
+++ b/sites/mytelly.co.uk/mytelly.co.uk.test.js
@@ -17,16 +17,18 @@ const channel = {
xmltv_id: 'BBCOneLondon.uk'
}
-axios.get.mockImplementation((url, opts) => {
+axios.get.mockImplementation(url => {
if (
- url === 'https://www.mytelly.co.uk/tv-guide/listings/programme?cid=713&pid=1906433&tm=2024-12-07+00%3A00%3A00'
+ url ===
+ 'https://www.mytelly.co.uk/tv-guide/listings/programme?cid=713&pid=1906433&tm=2024-12-07+00%3A00%3A00'
) {
return Promise.resolve({
data: fs.readFileSync(path.join(__dirname, '__data__', 'programme.html'))
})
}
if (
- url === 'https://www.mytelly.co.uk/tv-guide/listings/programme?cid=713&pid=5656624&tm=2024-12-07+23%3A35%3A00'
+ url ===
+ 'https://www.mytelly.co.uk/tv-guide/listings/programme?cid=713&pid=5656624&tm=2024-12-07+23%3A35%3A00'
) {
return Promise.resolve({
data: fs.readFileSync(path.join(__dirname, '__data__', 'programme2.html'))
@@ -57,7 +59,8 @@ it('can parse response', async () => {
title: 'Captain Phillips',
description:
'An American cargo ship sets a dangerous course around the coast of Somalia, while inland, four men are pressed into service as pirates by the local warlords. The captain is taken hostage when the raiding party hijacks the vessel, resulting in a tense five-day crisis. Fact-based thriller, starring Tom Hanks and Barkhad Abdi',
- image: 'https://d16ia5iwuvax6y.cloudfront.net/uk-prog-images/c44ce7b0d3ae602c0c93ece5af140815.jpg?k=VeeNdUjml3bSHdlZ0OXbGLy%2BmsLdYPwTV6iAxGkzq4dsylOCGGE7OWlqwSWt0cd0Qtrin4DkEMC0Zzdp8ZeNk2vNIQzjMF0DG0h3IeTR5NM%3D',
+ image:
+ 'https://d16ia5iwuvax6y.cloudfront.net/uk-prog-images/c44ce7b0d3ae602c0c93ece5af140815.jpg?k=VeeNdUjml3bSHdlZ0OXbGLy%2BmsLdYPwTV6iAxGkzq4dsylOCGGE7OWlqwSWt0cd0Qtrin4DkEMC0Zzdp8ZeNk2vNIQzjMF0DG0h3IeTR5NM%3D',
category: ['Factual', 'Movie/Drama', 'Thriller']
})
expect(results[1]).toMatchObject({
@@ -67,7 +70,8 @@ it('can parse response', async () => {
subTitle: 'Past and Pressure Season 6, Episode 5',
description:
'The artists are tasked with writing a song about their heritage. For some, the pressure of the competition proves too much for them to match. In their final challenge, they are put face to face with industry experts who grill them about their plans after the competition. Some impress, while others leave the mentors confused',
- image: 'https://d16ia5iwuvax6y.cloudfront.net/uk-prog-images/2039278182b27cc279570b9ab9b89379.jpg?k=VeeNdUjml3bSHdlZ0OXbGLy%2BmsLdYPwTV6iAxGkzq4cDhR7jXTNFW3tgwQCdOPUobhXwlT81mIsqOe93HPusDG6tw1aoeYOgafojtynNWxc%3D',
+ image:
+ 'https://d16ia5iwuvax6y.cloudfront.net/uk-prog-images/2039278182b27cc279570b9ab9b89379.jpg?k=VeeNdUjml3bSHdlZ0OXbGLy%2BmsLdYPwTV6iAxGkzq4cDhR7jXTNFW3tgwQCdOPUobhXwlT81mIsqOe93HPusDG6tw1aoeYOgafojtynNWxc%3D',
category: ['Challenge/Reality Show', 'Show/Game Show'],
season: 6,
episode: 5
diff --git a/sites/neo.io/neo.io.config.js b/sites/neo.io/neo.io.config.js
index 28d41e8d..bea58fca 100644
--- a/sites/neo.io/neo.io.config.js
+++ b/sites/neo.io/neo.io.config.js
@@ -1,73 +1,80 @@
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-module.exports = {
- site: 'neo.io',
- timezone: 'Europe/Ljubljana',
- days: 5,
- url({ date, channel }) { return 'https://stargate.telekom.si/api/titan.tv.WebEpg/GetWebEpgData' },
- request: {
- method: 'POST',
- headers: {
- 'Host': 'stargate.telekom.si',
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
- 'Accept': 'application/json, text/plain, */*',
- 'Accept-Language': 'nl,en-US;q=0.7,en;q=0.3',
- 'Content-Type': 'application/json',
- 'X-AppLayout': '1',
- 'x-language': 'sl',
- 'Origin': 'https://neo.io',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'cross-site',
- 'Sec-GPC': '1',
- 'Connection': 'keep-alive'
- },
- data({ channel, date }) {
- const todayEpoch = date.startOf('day').unix();
- const nextDayEpoch = date.add(1, 'day').startOf('day').unix();
- return JSON.stringify({
- ch_ext_id: channel.site_id,
- from: todayEpoch,
- to: nextDayEpoch
- })
- }
- },
- parser: function ({ content }) {
- const programs = [];
- const data = JSON.parse(content);
- data.shows.forEach(show => {
- const start = dayjs.unix(show.show_start).utc();
- const stop = dayjs.unix(show.show_end).utc();
- const programData = {
- title: show.title,
- description: show.summary || 'No description available',
- start: start.toISOString(),
- stop: stop.toISOString(),
- thumbnail: show.thumbnail
- }
- programs.push(programData)
- })
- return programs
- },
- async channels() {
- const response = await axios.post('https://stargate.telekom.si/api/titan.tv.WebEpg/ZapList', JSON.stringify({ includeRadioStations: true }), {
- headers: this.request.headers
- });
-
- const data = response.data.data;
- return data.map(item => ({
- lang: 'sq',
- name: String(item.channel.title),
- site_id: String(item.channel.id),
- //logo: String(item.channel.logo)
- }))
- }
-}
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'neo.io',
+ timezone: 'Europe/Ljubljana',
+ days: 5,
+ url() {
+ return 'https://stargate.telekom.si/api/titan.tv.WebEpg/GetWebEpgData'
+ },
+ request: {
+ method: 'POST',
+ headers: {
+ Host: 'stargate.telekom.si',
+ 'User-Agent':
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
+ Accept: 'application/json, text/plain, */*',
+ 'Accept-Language': 'nl,en-US;q=0.7,en;q=0.3',
+ 'Content-Type': 'application/json',
+ 'X-AppLayout': '1',
+ 'x-language': 'sl',
+ Origin: 'https://neo.io',
+ 'Sec-Fetch-Dest': 'empty',
+ 'Sec-Fetch-Mode': 'cors',
+ 'Sec-Fetch-Site': 'cross-site',
+ 'Sec-GPC': '1',
+ Connection: 'keep-alive'
+ },
+ data({ channel, date }) {
+ const todayEpoch = date.startOf('day').unix()
+ const nextDayEpoch = date.add(1, 'day').startOf('day').unix()
+ return JSON.stringify({
+ ch_ext_id: channel.site_id,
+ from: todayEpoch,
+ to: nextDayEpoch
+ })
+ }
+ },
+ parser: function ({ content }) {
+ const programs = []
+ const data = JSON.parse(content)
+ data.shows.forEach(show => {
+ const start = dayjs.unix(show.show_start).utc()
+ const stop = dayjs.unix(show.show_end).utc()
+ const programData = {
+ title: show.title,
+ description: show.summary || 'No description available',
+ start: start.toISOString(),
+ stop: stop.toISOString(),
+ thumbnail: show.thumbnail
+ }
+ programs.push(programData)
+ })
+ return programs
+ },
+ async channels() {
+ const response = await axios.post(
+ 'https://stargate.telekom.si/api/titan.tv.WebEpg/ZapList',
+ JSON.stringify({ includeRadioStations: true }),
+ {
+ headers: this.request.headers
+ }
+ )
+
+ const data = response.data.data
+ return data.map(item => ({
+ lang: 'sq',
+ name: String(item.channel.title),
+ site_id: String(item.channel.id)
+ //logo: String(item.channel.logo)
+ }))
+ }
+}
diff --git a/sites/neo.io/neo.io.test.js b/sites/neo.io/neo.io.test.js
index 3698a2fb..295120f7 100644
--- a/sites/neo.io/neo.io.test.js
+++ b/sites/neo.io/neo.io.test.js
@@ -1,121 +1,124 @@
-const { parser, url } = require('./neo.io.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2024-12-26', 'YYYY-MM-DD').startOf('day')
-const channel = {
- site_id: 'tv-slo-1',
- xmltv_id: 'TVSLO1.si'
-}
-
-it('can generate valid url', () => {
- expect(url({ date, channel })).toBe('https://stargate.telekom.si/api/titan.tv.WebEpg/GetWebEpgData')
-})
-
-it('can parse response', () => {
- const content = `
- {
- "shows": [
- {
- "title": "Napovedujemo",
- "show_start": 1735185900,
- "show_end": 1735192200,
- "timestamp": "5:05 - 6:50",
- "show_id": "CUP_IECOM_SLO1_10004660",
- "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/52/0/0/5200d01a-fe5f-487e-835a-274e77227a6b.jpg",
- "is_adult": false,
- "friendly_id": "napovedujemo_db48",
- "pg": "",
- "genres": [
- "napovednik"
- ],
- "year": 0,
- "summary": "Vabilo k ogledu naših oddaj.",
- "categories": "Ostalo",
- "stb_only": false,
- "is_live": false,
- "original_title": "Napovedujemo"
- },
- {
- "title": "S0E0 - Hrabri zajčki: Prvi sneg",
- "show_start": 1735192200,
- "show_end": 1735192800,
- "timestamp": "6:50 - 7:00",
- "show_id": "CUP_IECOM_SLO1_79637910",
- "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/d6/4/5/d6456f4a-4f0a-4825-90c1-1749abd59688.jpg",
- "is_adult": false,
- "friendly_id": "hrabri_zajcki_prvi_sneg_1619",
- "pg": "",
- "genres": [
- "risanka"
- ],
- "year": 2020,
- "summary": "Hrabri zajčki so prispeli v borov gozd in izkusili prvi sneg. Bob in Bu še nikoli nista videla snega. Mami kuha korenčkov kakav, Bu in Bob pa kmalu spoznata novega prijatelja, losa Danija.",
- "categories": "Otroški/Mladinski",
- "stb_only": false,
- "is_live": false,
- "original_title": "S0E0 - Brave Bunnies"
- },
- {
- "title": "Dobro jutro",
- "show_start": 1735192800,
- "show_end": 1735203900,
- "timestamp": "7:00 - 10:05",
- "show_id": "CUP_IECOM_SLO1_79637911",
- "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/e1/2/d/e12d8eb4-693a-43d3-89d4-fd96dade9f0f.jpg",
- "is_adult": false,
- "friendly_id": "dobro_jutro_2f10",
- "pg": "",
- "genres": [
- "zabavna oddaja"
- ],
- "year": 2024,
- "summary": "Oddaja Dobro jutro poleg informativnih in zabavnih vsebin podaja koristne nasvete o najrazličnejših tematikah iz vsakdanjega življenja.",
- "categories": "Razvedrilni program",
- "stb_only": false,
- "is_live": false,
- "original_title": "Dobro jutro"
- }
- ]
- }`
-
- const result = parser({ content, channel }).map(p => {
- p.start = p.start
- p.stop = p.stop
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: "Napovedujemo",
- description: "Vabilo k ogledu naših oddaj.",
- start: "2024-12-26T04:05:00.000Z",
- stop: "2024-12-26T05:50:00.000Z",
- thumbnail: "https://ngimg.siol.tv/sioltv/mtcmsprod/52/0/0/5200d01a-fe5f-487e-835a-274e77227a6b.jpg"
- },
- {
- title: "S0E0 - Hrabri zajčki: Prvi sneg",
- description: "Hrabri zajčki so prispeli v borov gozd in izkusili prvi sneg. Bob in Bu še nikoli nista videla snega. Mami kuha korenčkov kakav, Bu in Bob pa kmalu spoznata novega prijatelja, losa Danija.",
- start: "2024-12-26T05:50:00.000Z",
- stop: "2024-12-26T06:00:00.000Z",
- thumbnail: "https://ngimg.siol.tv/sioltv/mtcmsprod/d6/4/5/d6456f4a-4f0a-4825-90c1-1749abd59688.jpg"
- },
- {
- title: "Dobro jutro",
- description: "Oddaja Dobro jutro poleg informativnih in zabavnih vsebin podaja koristne nasvete o najrazličnejših tematikah iz vsakdanjega življenja.",
- start: "2024-12-26T06:00:00.000Z",
- stop: "2024-12-26T09:05:00.000Z",
- thumbnail: "https://ngimg.siol.tv/sioltv/mtcmsprod/e1/2/d/e12d8eb4-693a-43d3-89d4-fd96dade9f0f.jpg"
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: '{"shows":[]}'
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./neo.io.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2024-12-26', 'YYYY-MM-DD').startOf('day')
+const channel = {
+ site_id: 'tv-slo-1',
+ xmltv_id: 'TVSLO1.si'
+}
+
+it('can generate valid url', () => {
+ expect(url({ date, channel })).toBe(
+ 'https://stargate.telekom.si/api/titan.tv.WebEpg/GetWebEpgData'
+ )
+})
+
+it('can parse response', () => {
+ const content = `
+ {
+ "shows": [
+ {
+ "title": "Napovedujemo",
+ "show_start": 1735185900,
+ "show_end": 1735192200,
+ "timestamp": "5:05 - 6:50",
+ "show_id": "CUP_IECOM_SLO1_10004660",
+ "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/52/0/0/5200d01a-fe5f-487e-835a-274e77227a6b.jpg",
+ "is_adult": false,
+ "friendly_id": "napovedujemo_db48",
+ "pg": "",
+ "genres": [
+ "napovednik"
+ ],
+ "year": 0,
+ "summary": "Vabilo k ogledu naših oddaj.",
+ "categories": "Ostalo",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "Napovedujemo"
+ },
+ {
+ "title": "S0E0 - Hrabri zajčki: Prvi sneg",
+ "show_start": 1735192200,
+ "show_end": 1735192800,
+ "timestamp": "6:50 - 7:00",
+ "show_id": "CUP_IECOM_SLO1_79637910",
+ "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/d6/4/5/d6456f4a-4f0a-4825-90c1-1749abd59688.jpg",
+ "is_adult": false,
+ "friendly_id": "hrabri_zajcki_prvi_sneg_1619",
+ "pg": "",
+ "genres": [
+ "risanka"
+ ],
+ "year": 2020,
+ "summary": "Hrabri zajčki so prispeli v borov gozd in izkusili prvi sneg. Bob in Bu še nikoli nista videla snega. Mami kuha korenčkov kakav, Bu in Bob pa kmalu spoznata novega prijatelja, losa Danija.",
+ "categories": "Otroški/Mladinski",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "S0E0 - Brave Bunnies"
+ },
+ {
+ "title": "Dobro jutro",
+ "show_start": 1735192800,
+ "show_end": 1735203900,
+ "timestamp": "7:00 - 10:05",
+ "show_id": "CUP_IECOM_SLO1_79637911",
+ "thumbnail": "https://ngimg.siol.tv/sioltv/mtcmsprod/e1/2/d/e12d8eb4-693a-43d3-89d4-fd96dade9f0f.jpg",
+ "is_adult": false,
+ "friendly_id": "dobro_jutro_2f10",
+ "pg": "",
+ "genres": [
+ "zabavna oddaja"
+ ],
+ "year": 2024,
+ "summary": "Oddaja Dobro jutro poleg informativnih in zabavnih vsebin podaja koristne nasvete o najrazličnejših tematikah iz vsakdanjega življenja.",
+ "categories": "Razvedrilni program",
+ "stb_only": false,
+ "is_live": false,
+ "original_title": "Dobro jutro"
+ }
+ ]
+ }`
+
+ const result = parser({ content, channel })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Napovedujemo',
+ description: 'Vabilo k ogledu naših oddaj.',
+ start: '2024-12-26T04:05:00.000Z',
+ stop: '2024-12-26T05:50:00.000Z',
+ thumbnail:
+ 'https://ngimg.siol.tv/sioltv/mtcmsprod/52/0/0/5200d01a-fe5f-487e-835a-274e77227a6b.jpg'
+ },
+ {
+ title: 'S0E0 - Hrabri zajčki: Prvi sneg',
+ description:
+ 'Hrabri zajčki so prispeli v borov gozd in izkusili prvi sneg. Bob in Bu še nikoli nista videla snega. Mami kuha korenčkov kakav, Bu in Bob pa kmalu spoznata novega prijatelja, losa Danija.',
+ start: '2024-12-26T05:50:00.000Z',
+ stop: '2024-12-26T06:00:00.000Z',
+ thumbnail:
+ 'https://ngimg.siol.tv/sioltv/mtcmsprod/d6/4/5/d6456f4a-4f0a-4825-90c1-1749abd59688.jpg'
+ },
+ {
+ title: 'Dobro jutro',
+ description:
+ 'Oddaja Dobro jutro poleg informativnih in zabavnih vsebin podaja koristne nasvete o najrazličnejših tematikah iz vsakdanjega življenja.',
+ start: '2024-12-26T06:00:00.000Z',
+ stop: '2024-12-26T09:05:00.000Z',
+ thumbnail:
+ 'https://ngimg.siol.tv/sioltv/mtcmsprod/e1/2/d/e12d8eb4-693a-43d3-89d4-fd96dade9f0f.jpg'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ content: '{"shows":[]}'
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/nhkworldpremium.com/nhkworldpremium.com.config.js b/sites/nhkworldpremium.com/nhkworldpremium.com.config.js
index bdce0c26..79ba59bf 100644
--- a/sites/nhkworldpremium.com/nhkworldpremium.com.config.js
+++ b/sites/nhkworldpremium.com/nhkworldpremium.com.config.js
@@ -50,7 +50,7 @@ function parseItems(content, date) {
if (!data || !data.item || !Array.isArray(data.item.episodes)) return []
return data.item.episodes.filter(ep => ep.schedule.startsWith(date.format('YYYY-MM-DD')))
- } catch (err) {
+ } catch {
return []
}
}
diff --git a/sites/nhl.com/nhl.com.config.js b/sites/nhl.com/nhl.com.config.js
index c3c01408..46127652 100644
--- a/sites/nhl.com/nhl.com.config.js
+++ b/sites/nhl.com/nhl.com.config.js
@@ -1,45 +1,46 @@
-const dayjs = require('dayjs')
-
-module.exports = {
- site: 'nhl.com',
- // I'm not sure what `endDate` represents but they only return 1 day of
- // results, with `endTime`s ocassionally in the following day.
- days: 1,
- url: ({ date }) => `https://api-web.nhle.com/v1/network/tv-schedule/${date.toJSON().split("T")[0]}`,
- parser({ content }) {
- const programs = []
- const items = parseItems(content)
- for (const item of items) {
- programs.push({
- title: item.title,
- description: item.description === item.title ? undefined : item.description,
- category: "Sports",
- // image: parseImage(item),
- start: parseStart(item),
- stop: parseStop(item)
- })
- }
-
- return programs
- }
-}
-
-// Unfortunately I couldn't determine how these are
-// supposed to be formatted. Pointers appreciated!
-// function parseImage(item) {
-// const uri = item.broadcastImageUrl
-
-// return uri ? `https://???/${uri}` : null
-// }
-
-function parseStart(item) {
- return dayjs(item.startTime)
-}
-
-function parseStop(item) {
- return dayjs(item.endTime)
-}
-
-function parseItems(content) {
- return JSON.parse(content).broadcasts
-}
+const dayjs = require('dayjs')
+
+module.exports = {
+ site: 'nhl.com',
+ // I'm not sure what `endDate` represents but they only return 1 day of
+ // results, with `endTime`s ocassionally in the following day.
+ days: 1,
+ url: ({ date }) =>
+ `https://api-web.nhle.com/v1/network/tv-schedule/${date.toJSON().split('T')[0]}`,
+ parser({ content }) {
+ const programs = []
+ const items = parseItems(content)
+ for (const item of items) {
+ programs.push({
+ title: item.title,
+ description: item.description === item.title ? undefined : item.description,
+ category: 'Sports',
+ // image: parseImage(item),
+ start: parseStart(item),
+ stop: parseStop(item)
+ })
+ }
+
+ return programs
+ }
+}
+
+// Unfortunately I couldn't determine how these are
+// supposed to be formatted. Pointers appreciated!
+// function parseImage(item) {
+// const uri = item.broadcastImageUrl
+
+// return uri ? `https://???/${uri}` : null
+// }
+
+function parseStart(item) {
+ return dayjs(item.startTime)
+}
+
+function parseStop(item) {
+ return dayjs(item.endTime)
+}
+
+function parseItems(content) {
+ return JSON.parse(content).broadcasts
+}
diff --git a/sites/nhl.com/nhl.com.test.js b/sites/nhl.com/nhl.com.test.js
index a12db69a..49ce4a0e 100644
--- a/sites/nhl.com/nhl.com.test.js
+++ b/sites/nhl.com/nhl.com.test.js
@@ -1,44 +1,44 @@
-const { parser, url } = require('./nhl.com.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2024-11-21', 'YYYY-MM-DD').startOf('d')
-
-it('can generate valid url', () => {
- expect(url({ date })).toBe(
- 'https://api-web.nhle.com/v1/network/tv-schedule/2024-11-21'
- )
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
- let results = parser({ content, date })
- results = results.map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(results[0]).toMatchObject({
- start: '2024-11-21T12:00:00.000Z',
- stop: '2024-11-21T13:00:00.000Z',
- title: 'On The Fly',
- category: 'Sports',
- })
-})
-
-it('can handle empty guide', () => {
- const results = parser({ content: JSON.stringify({
- // extra props not necessary but they form a valid response
- date: "2024-11-21",
- startDate: "2024-11-07",
- endDate: "2024-12-05",
- broadcasts: [],
- }) })
- expect(results).toMatchObject([])
-})
+const { parser, url } = require('./nhl.com.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2024-11-21', 'YYYY-MM-DD').startOf('d')
+
+it('can generate valid url', () => {
+ expect(url({ date })).toBe('https://api-web.nhle.com/v1/network/tv-schedule/2024-11-21')
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
+ let results = parser({ content, date })
+ results = results.map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(results[0]).toMatchObject({
+ start: '2024-11-21T12:00:00.000Z',
+ stop: '2024-11-21T13:00:00.000Z',
+ title: 'On The Fly',
+ category: 'Sports'
+ })
+})
+
+it('can handle empty guide', () => {
+ const results = parser({
+ content: JSON.stringify({
+ // extra props not necessary but they form a valid response
+ date: '2024-11-21',
+ startDate: '2024-11-07',
+ endDate: '2024-12-05',
+ broadcasts: []
+ })
+ })
+ expect(results).toMatchObject([])
+})
diff --git a/sites/nostv.pt/nostv.pt.config.js b/sites/nostv.pt/nostv.pt.config.js
index a823d165..6ba4dbac 100644
--- a/sites/nostv.pt/nostv.pt.config.js
+++ b/sites/nostv.pt/nostv.pt.config.js
@@ -1,68 +1,68 @@
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-const headers = {
- 'X-Apikey': 'xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI',
- 'X-Core-Appversion': '2.14.0.1',
- 'X-Core-Contentratinglimit': '0',
- 'X-Core-Deviceid': '',
- 'X-Core-Devicetype': 'web',
- Origin: 'https://nostv.pt',
- 'User-Agent':
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
-}
-
-module.exports = {
- site: 'nostv.pt',
- days: 2,
- url({ channel, date }) {
- return `https://tyr-prod.apigee.net/nostv/ott/schedule/range/contents/guest?channels=${
- channel.site_id
- }&minDate=${date.format('YYYY-MM-DD')}T00:00:00Z&maxDate=${date.format(
- 'YYYY-MM-DD'
- )}T23:59:59Z&isDateInclusive=true&client_id=${headers['X-Apikey']}`
- },
- request: { headers },
- parser({ content }) {
- const programs = []
- if (content) {
- const items = Array.isArray(content) ? content : JSON.parse(content)
- items.forEach(item => {
- programs.push({
- title: item.Metadata?.Title,
- sub_title: item.Metadata?.SubTitle ? item.Metadata?.SubTitle : null,
- description: item.Metadata?.Description,
- season: item.Metadata?.Season,
- episode: item.Metadata?.Episode,
- image: item.Images
- ? `https://mage.stream.nos.pt/v1/nostv_mage/Images?sourceUri=${item.Images[0].Url}&profile=ott_1_452x340&client_id=${headers['X-Apikey']}`
- : null,
- start: dayjs.utc(item.UtcDateTimeStart),
- stop: dayjs.utc(item.UtcDateTimeEnd)
- })
- })
- }
-
- return programs
- },
- async channels() {
- const result = await axios
- .get(
- `https://tyr-prod.apigee.net/nostv/ott/channels/guest?client_id=${headers['X-Apikey']}`,
- { headers }
- )
- .then(r => r.data)
- .catch(console.error)
-
- return result.map(item => {
- return {
- lang: 'pt',
- site_id: item.ServiceId,
- name: item.Name
- }
- })
- }
-}
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+const headers = {
+ 'X-Apikey': 'xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI',
+ 'X-Core-Appversion': '2.14.0.1',
+ 'X-Core-Contentratinglimit': '0',
+ 'X-Core-Deviceid': '',
+ 'X-Core-Devicetype': 'web',
+ Origin: 'https://nostv.pt',
+ 'User-Agent':
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
+}
+
+module.exports = {
+ site: 'nostv.pt',
+ days: 2,
+ url({ channel, date }) {
+ return `https://tyr-prod.apigee.net/nostv/ott/schedule/range/contents/guest?channels=${
+ channel.site_id
+ }&minDate=${date.format('YYYY-MM-DD')}T00:00:00Z&maxDate=${date.format(
+ 'YYYY-MM-DD'
+ )}T23:59:59Z&isDateInclusive=true&client_id=${headers['X-Apikey']}`
+ },
+ request: { headers },
+ parser({ content }) {
+ const programs = []
+ if (content) {
+ const items = Array.isArray(content) ? content : JSON.parse(content)
+ items.forEach(item => {
+ programs.push({
+ title: item.Metadata?.Title,
+ sub_title: item.Metadata?.SubTitle ? item.Metadata?.SubTitle : null,
+ description: item.Metadata?.Description,
+ season: item.Metadata?.Season,
+ episode: item.Metadata?.Episode,
+ image: item.Images
+ ? `https://mage.stream.nos.pt/v1/nostv_mage/Images?sourceUri=${item.Images[0].Url}&profile=ott_1_452x340&client_id=${headers['X-Apikey']}`
+ : null,
+ start: dayjs.utc(item.UtcDateTimeStart),
+ stop: dayjs.utc(item.UtcDateTimeEnd)
+ })
+ })
+ }
+
+ return programs
+ },
+ async channels() {
+ const result = await axios
+ .get(
+ `https://tyr-prod.apigee.net/nostv/ott/channels/guest?client_id=${headers['X-Apikey']}`,
+ { headers }
+ )
+ .then(r => r.data)
+ .catch(console.error)
+
+ return result.map(item => {
+ return {
+ lang: 'pt',
+ site_id: item.ServiceId,
+ name: item.Name
+ }
+ })
+ }
+}
diff --git a/sites/nostv.pt/nostv.pt.test.js b/sites/nostv.pt/nostv.pt.test.js
index 47297845..b4163c9b 100644
--- a/sites/nostv.pt/nostv.pt.test.js
+++ b/sites/nostv.pt/nostv.pt.test.js
@@ -1,51 +1,51 @@
-const { parser, url } = require('./nostv.pt.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-12-11').startOf('d')
-const channel = {
- site_id: '510',
- xmltv_id: 'SPlus.pt'
-}
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe(
- 'https://tyr-prod.apigee.net/nostv/ott/schedule/range/contents/guest?channels=510&minDate=2023-12-11T00:00:00Z&maxDate=2023-12-11T23:59:59Z&isDateInclusive=true&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI'
- )
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
- const results = parser({ content }).map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(results[0]).toMatchObject({
- start: '2023-12-11T16:30:00.000Z',
- stop: '2023-12-11T17:00:00.000Z',
- title: 'Village Vets',
- description:
- 'A história de dois melhores amigos veterinários e o seu extraordinário trabalho na Austrália.',
- season: 1,
- episode: 12,
- image:
- 'https://mage.stream.nos.pt/v1/nostv_mage/Images?sourceUri=http://vip.pam.local.internal/PAM.Images/Store/8329ed1aec5d4c0faa2056972256ff9f&profile=ott_1_452x340&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI'
- })
-})
-
-it('can handle empty guide', async () => {
- const results = await parser({
- date,
- content: '[]'
- })
-
- expect(results).toMatchObject([])
-})
+const { parser, url } = require('./nostv.pt.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-12-11').startOf('d')
+const channel = {
+ site_id: '510',
+ xmltv_id: 'SPlus.pt'
+}
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe(
+ 'https://tyr-prod.apigee.net/nostv/ott/schedule/range/contents/guest?channels=510&minDate=2023-12-11T00:00:00Z&maxDate=2023-12-11T23:59:59Z&isDateInclusive=true&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI'
+ )
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
+ const results = parser({ content }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(results[0]).toMatchObject({
+ start: '2023-12-11T16:30:00.000Z',
+ stop: '2023-12-11T17:00:00.000Z',
+ title: 'Village Vets',
+ description:
+ 'A história de dois melhores amigos veterinários e o seu extraordinário trabalho na Austrália.',
+ season: 1,
+ episode: 12,
+ image:
+ 'https://mage.stream.nos.pt/v1/nostv_mage/Images?sourceUri=http://vip.pam.local.internal/PAM.Images/Store/8329ed1aec5d4c0faa2056972256ff9f&profile=ott_1_452x340&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI'
+ })
+})
+
+it('can handle empty guide', async () => {
+ const results = await parser({
+ date,
+ content: '[]'
+ })
+
+ expect(results).toMatchObject([])
+})
diff --git a/sites/nuevosiglo.com.uy/nuevosiglo.com.uy.config.js b/sites/nuevosiglo.com.uy/nuevosiglo.com.uy.config.js
index 37429ac8..6dd2c7e1 100644
--- a/sites/nuevosiglo.com.uy/nuevosiglo.com.uy.config.js
+++ b/sites/nuevosiglo.com.uy/nuevosiglo.com.uy.config.js
@@ -55,7 +55,7 @@ module.exports = {
.map(function () {
return {
lang: 'es',
- site_id: $(this).attr('alt').replace(/\&/gi, '&'),
+ site_id: $(this).attr('alt').replace(/&/gi, '&'),
name: $(this).attr('alt')
}
})
diff --git a/sites/nzxmltv.com/nzxmltv.com.config.js b/sites/nzxmltv.com/nzxmltv.com.config.js
index 4c6e42b8..609b2c09 100644
--- a/sites/nzxmltv.com/nzxmltv.com.config.js
+++ b/sites/nzxmltv.com/nzxmltv.com.config.js
@@ -1,81 +1,81 @@
-const parser = require('epg-parser')
-
-module.exports = {
- site: 'nzxmltv.com',
- days: 2,
- request: {
- cache: {
- ttl: 3600000 // 1 hour
- },
- maxContentLength: 104857600 // 100 MB
- },
- url({ channel }) {
- const [path] = channel.site_id.split('#')
-
- return `https://nzxmltv.com/${path}.xml`
- },
- parser({ content, channel, date }) {
- const programs = []
- parseItems(content, channel, date).forEach(item => {
- const program = {
- title: item.title?.[0]?.value,
- description: item.desc?.[0]?.value,
- icon: item.icon?.[0],
- start: item.start,
- stop: item.stop
- }
- if (item.episodeNum) {
- item.episodeNum.forEach(ep => {
- if (ep.system === 'xmltv_ns') {
- const [season, episode, _] = ep.value.split('.')
- program.season = parseInt(season) + 1
- program.episode = parseInt(episode) + 1
- return true
- }
- })
- }
- programs.push(program)
- })
-
- return programs
- },
- async channels({ provider }) {
- const axios = require('axios')
- const cheerio = require('cheerio')
-
- const providers = {
- freeview: 'xmltv/guide',
- sky: 'sky/guide',
- redbull: 'iptv/redbull',
- pluto: 'iptv/plutotv'
- }
-
- const channels = []
- const path = providers[provider]
- const xml = await axios
- .get(`https://nzxmltv.com/${path}.xml`)
- .then(r => r.data)
- .catch(console.error)
-
- const $ = cheerio.load(xml)
- $('tv channel').each((i, el) => {
- const disp = $(el).find('display-name')
- const channelId = $(el).attr('id')
-
- channels.push({
- lang: disp.attr('lang').substr(0, 2),
- site_id: `${path}#${channelId}`,
- name: disp.text().trim()
- })
- })
-
- return channels
- }
-}
-
-function parseItems(content, channel, date) {
- const { programs } = parser.parse(content)
- const [, channelId] = channel.site_id.split('#')
-
- return programs.filter(p => p.channel === channelId && date.isSame(p.start, 'day'))
-}
+const parser = require('epg-parser')
+
+module.exports = {
+ site: 'nzxmltv.com',
+ days: 2,
+ request: {
+ cache: {
+ ttl: 3600000 // 1 hour
+ },
+ maxContentLength: 104857600 // 100 MB
+ },
+ url({ channel }) {
+ const [path] = channel.site_id.split('#')
+
+ return `https://nzxmltv.com/${path}.xml`
+ },
+ parser({ content, channel, date }) {
+ const programs = []
+ parseItems(content, channel, date).forEach(item => {
+ const program = {
+ title: item.title?.[0]?.value,
+ description: item.desc?.[0]?.value,
+ icon: item.icon?.[0],
+ start: item.start,
+ stop: item.stop
+ }
+ if (item.episodeNum) {
+ item.episodeNum.forEach(ep => {
+ if (ep.system === 'xmltv_ns') {
+ const [season, episode] = ep.value.split('.')
+ program.season = parseInt(season) + 1
+ program.episode = parseInt(episode) + 1
+ return true
+ }
+ })
+ }
+ programs.push(program)
+ })
+
+ return programs
+ },
+ async channels({ provider }) {
+ const axios = require('axios')
+ const cheerio = require('cheerio')
+
+ const providers = {
+ freeview: 'xmltv/guide',
+ sky: 'sky/guide',
+ redbull: 'iptv/redbull',
+ pluto: 'iptv/plutotv'
+ }
+
+ const channels = []
+ const path = providers[provider]
+ const xml = await axios
+ .get(`https://nzxmltv.com/${path}.xml`)
+ .then(r => r.data)
+ .catch(console.error)
+
+ const $ = cheerio.load(xml)
+ $('tv channel').each((i, el) => {
+ const disp = $(el).find('display-name')
+ const channelId = $(el).attr('id')
+
+ channels.push({
+ lang: disp.attr('lang').substr(0, 2),
+ site_id: `${path}#${channelId}`,
+ name: disp.text().trim()
+ })
+ })
+
+ return channels
+ }
+}
+
+function parseItems(content, channel, date) {
+ const { programs } = parser.parse(content)
+ const [, channelId] = channel.site_id.split('#')
+
+ return programs.filter(p => p.channel === channelId && date.isSame(p.start, 'day'))
+}
diff --git a/sites/nzxmltv.com/nzxmltv.com.test.js b/sites/nzxmltv.com/nzxmltv.com.test.js
index f1af8d89..e6ef97a8 100644
--- a/sites/nzxmltv.com/nzxmltv.com.test.js
+++ b/sites/nzxmltv.com/nzxmltv.com.test.js
@@ -1,40 +1,40 @@
-const { parser, url } = require('./nzxmltv.com.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-11-21').startOf('d')
-const channel = {
- site_id: 'xmltv/guide#1',
- xmltv_id: 'TVNZ1.nz'
-}
-
-it('can generate valid url', () => {
- expect(url({ channel })).toBe('https://nzxmltv.com/xmltv/guide.xml')
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.xml'))
- const results = parser({ content, channel, date })
-
- expect(results[0]).toMatchObject({
- start: '2023-11-21T10:30:00.000Z',
- stop: '2023-11-21T11:25:00.000Z',
- title: 'Sunday',
- description:
- 'On Sunday, an unmissable show with stories about divorce, weight loss, and the incomprehensible devastation of Gaza.',
- season: 2023,
- episode: 37,
- icon: 'https://www.thetvdb.com/banners/posters/5dbebff2986f2.jpg'
- })
-})
-
-it('can handle empty guide', () => {
- const result = parser({ content: '', channel, date })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./nzxmltv.com.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-11-21').startOf('d')
+const channel = {
+ site_id: 'xmltv/guide#1',
+ xmltv_id: 'TVNZ1.nz'
+}
+
+it('can generate valid url', () => {
+ expect(url({ channel })).toBe('https://nzxmltv.com/xmltv/guide.xml')
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.xml'))
+ const results = parser({ content, channel, date })
+
+ expect(results[0]).toMatchObject({
+ start: '2023-11-21T10:30:00.000Z',
+ stop: '2023-11-21T11:25:00.000Z',
+ title: 'Sunday',
+ description:
+ 'On Sunday, an unmissable show with stories about divorce, weight loss, and the incomprehensible devastation of Gaza.',
+ season: 2023,
+ episode: 37,
+ icon: 'https://www.thetvdb.com/banners/posters/5dbebff2986f2.jpg'
+ })
+})
+
+it('can handle empty guide', () => {
+ const result = parser({ content: '', channel, date })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/ontvtonight.com/ontvtonight.com.config.js b/sites/ontvtonight.com/ontvtonight.com.config.js
index e41f6ada..20b6efd0 100644
--- a/sites/ontvtonight.com/ontvtonight.com.config.js
+++ b/sites/ontvtonight.com/ontvtonight.com.config.js
@@ -132,7 +132,7 @@ module.exports = {
const $ = cheerio.load(data)
$('.channelname').each((i, el) => {
let name = $(el).find('center > a:eq(1)').text()
- name = name.replace(/\-\-/gi, '-')
+ name = name.replace(/--/gi, '-')
const url = $(el).find('center > a:eq(1)').attr('href')
if (!url) return
const [, number, slug] = url.match(/\/(\d+)\/(.*)\.html$/)
diff --git a/sites/orangetv.orange.es/orangetv.orange.es.config.js b/sites/orangetv.orange.es/orangetv.orange.es.config.js
index 34742993..690e1e80 100644
--- a/sites/orangetv.orange.es/orangetv.orange.es.config.js
+++ b/sites/orangetv.orange.es/orangetv.orange.es.config.js
@@ -1,113 +1,108 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const axios = require('axios')
-
-dayjs.extend(utc)
-
-const API_PROGRAM_ENDPOINT = 'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO'
-const API_CHANNEL_ENDPOINT = 'https://pc.orangetv.orange.es/pc/api/rtv/v1/GetChannelList?bouquet_id=1&model_external_id=PC&filter_unsupported_channels=false&client=json'
-const API_IMAGE_ENDPOINT = 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images'
-
-module.exports = {
- site: 'orangetv.orange.es',
- days: 2,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1 hour
- }
- },
- url({ date }) {
- return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`
- },
- async parser({ content, channel, date }) {
- let programs = []
- let items = parseItems(content, channel)
- if (!items.length) return programs
-
- const promises = [
- axios.get(
- `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`,
- ),
- axios.get(
- `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_2.json`,
- ),
- axios.get(
- `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_3.json`,
- ),
- ]
-
- await Promise.allSettled(promises)
- .then(results => {
- results.forEach(r => {
- if (r.status === 'fulfilled') {
- const parsed = parseItems(r.value.data, channel)
-
- items = items.filter((item, index) => items.findIndex(oi => oi.id === item.id) === index).concat(parsed)
- }
- })
- })
- .catch(console.error)
-
- items.forEach(item => {
- programs.push({
- title: item.name,
- description: item.description,
- category: parseGenres(item),
- season: item.seriesSeason || null,
- episode: item.episodeId || null,
- icon: parseIcon(item),
- start: dayjs.utc(item.startDate) || null,
- stop: dayjs.utc(item.endDate) || null,
- })
- })
-
- return programs
- },
- async channels() {
- const axios = require('axios')
- const data = await axios
- .get(API_CHANNEL_ENDPOINT)
- .then(r => r.data)
- .catch(console.log)
- return data.response.map(item => {
- return {
- lang: 'es',
- name: item.name,
- site_id: item.externalChannelId
- }
- })
- }
-}
-
-function parseIcon(item){
-
- if(item.attachments.length > 0){
- const cover = item.attachments.find(i => i.name === "COVER" || i.name === "cover")
-
- if(cover)
- {
- return `${API_IMAGE_ENDPOINT}${cover.value}`;
- }
- }
-
- return ''
-}
-
-function parseGenres(item){
- return item.genres.map(i => i.name);
-}
-
-function parseItems(content, channel) {
- const json = typeof content === 'string' ? JSON.parse(content) : Array.isArray(content) ? content : []
-
- if (!Array.isArray(json)) {
- return [];
- }
-
- const channelData = json.find(i => i.channelExternalId == channel.site_id);
-
- if(!channelData)
- return [];
-
- return channelData.programs;
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const axios = require('axios')
+
+dayjs.extend(utc)
+
+const API_PROGRAM_ENDPOINT = 'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO'
+const API_CHANNEL_ENDPOINT =
+ 'https://pc.orangetv.orange.es/pc/api/rtv/v1/GetChannelList?bouquet_id=1&model_external_id=PC&filter_unsupported_channels=false&client=json'
+const API_IMAGE_ENDPOINT = 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images'
+
+module.exports = {
+ site: 'orangetv.orange.es',
+ days: 2,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1 hour
+ }
+ },
+ url({ date }) {
+ return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`
+ },
+ async parser({ content, channel, date }) {
+ let programs = []
+ let items = parseItems(content, channel)
+ if (!items.length) return programs
+
+ const promises = [
+ axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`),
+ axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_2.json`),
+ axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_3.json`)
+ ]
+
+ await Promise.allSettled(promises)
+ .then(results => {
+ results.forEach(r => {
+ if (r.status === 'fulfilled') {
+ const parsed = parseItems(r.value.data, channel)
+
+ items = items
+ .filter((item, index) => items.findIndex(oi => oi.id === item.id) === index)
+ .concat(parsed)
+ }
+ })
+ })
+ .catch(console.error)
+
+ items.forEach(item => {
+ programs.push({
+ title: item.name,
+ description: item.description,
+ category: parseGenres(item),
+ season: item.seriesSeason || null,
+ episode: item.episodeId || null,
+ icon: parseIcon(item),
+ start: dayjs.utc(item.startDate) || null,
+ stop: dayjs.utc(item.endDate) || null
+ })
+ })
+
+ return programs
+ },
+ async channels() {
+ const axios = require('axios')
+ const data = await axios
+ .get(API_CHANNEL_ENDPOINT)
+ .then(r => r.data)
+ .catch(console.log)
+ return data.response.map(item => {
+ return {
+ lang: 'es',
+ name: item.name,
+ site_id: item.externalChannelId
+ }
+ })
+ }
+}
+
+function parseIcon(item) {
+ if (item.attachments.length > 0) {
+ const cover = item.attachments.find(i => i.name === 'COVER' || i.name === 'cover')
+
+ if (cover) {
+ return `${API_IMAGE_ENDPOINT}${cover.value}`
+ }
+ }
+
+ return ''
+}
+
+function parseGenres(item) {
+ return item.genres.map(i => i.name)
+}
+
+function parseItems(content, channel) {
+ const json =
+ typeof content === 'string' ? JSON.parse(content) : Array.isArray(content) ? content : []
+
+ if (!Array.isArray(json)) {
+ return []
+ }
+
+ const channelData = json.find(i => i.channelExternalId == channel.site_id)
+
+ if (!channelData) return []
+
+ return channelData.programs
+}
diff --git a/sites/orangetv.orange.es/orangetv.orange.es.test.js b/sites/orangetv.orange.es/orangetv.orange.es.test.js
index 3738523c..c9decd52 100644
--- a/sites/orangetv.orange.es/orangetv.orange.es.test.js
+++ b/sites/orangetv.orange.es/orangetv.orange.es.test.js
@@ -1,49 +1,54 @@
-const { parser, url } = require('./orangetv.orange.es.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-const path = require('path')
-const fs = require('fs')
-
-const date = dayjs.utc('2024-12-01', 'YYYY-MM-DD').startOf('d')
-const channel = {
- site_id: '1010',
- xmltv_id: 'La1.es'
-}
-
-it('can generate valid url', () => {
- expect(url({ date })).toBe(`https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/${date.format('YYYYMMDD')}_8h_1.json`)
-})
-
-it('can parse response', async () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json')).toString()
- let results = await parser({ content, channel, date })
- results = results.map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(results.length).toBe(4)
-
- var sampleResult = results[0];
-
- expect(sampleResult).toMatchObject({
- start: '2024-11-30T22:36:51.000Z',
- stop: '2024-11-30T23:57:25.000Z',
- category: ['Cine', 'Romance', 'Comedia', 'Comedia Romántica'],
- description: 'Charlie trabaja como director en una escuela de primaria y goza de una placentera existencia junto a sus amigos. A pesar de ello, no es feliz porque cada vez que se enamora pierde la cordura.',
- title: 'Loco de amor'
- })
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- date,
- channel,
- content: '{}'
- })
- expect(result).toMatchObject({})
-})
+const { parser, url } = require('./orangetv.orange.es.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+const path = require('path')
+const fs = require('fs')
+
+const date = dayjs.utc('2024-12-01', 'YYYY-MM-DD').startOf('d')
+const channel = {
+ site_id: '1010',
+ xmltv_id: 'La1.es'
+}
+
+it('can generate valid url', () => {
+ expect(url({ date })).toBe(
+ `https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/${date.format(
+ 'YYYYMMDD'
+ )}_8h_1.json`
+ )
+})
+
+it('can parse response', async () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json')).toString()
+ let results = await parser({ content, channel, date })
+ results = results.map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(results.length).toBe(4)
+
+ var sampleResult = results[0]
+
+ expect(sampleResult).toMatchObject({
+ start: '2024-11-30T22:36:51.000Z',
+ stop: '2024-11-30T23:57:25.000Z',
+ category: ['Cine', 'Romance', 'Comedia', 'Comedia Romántica'],
+ description:
+ 'Charlie trabaja como director en una escuela de primaria y goza de una placentera existencia junto a sus amigos. A pesar de ello, no es feliz porque cada vez que se enamora pierde la cordura.',
+ title: 'Loco de amor'
+ })
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ date,
+ channel,
+ content: '{}'
+ })
+ expect(result).toMatchObject({})
+})
diff --git a/sites/osn.com/osn.com.config.js b/sites/osn.com/osn.com.config.js
index d85efae5..ece2bf72 100644
--- a/sites/osn.com/osn.com.config.js
+++ b/sites/osn.com/osn.com.config.js
@@ -5,7 +5,12 @@ const timezone = require('dayjs/plugin/timezone')
dayjs.extend(utc)
dayjs.extend(timezone)
-const packages = { 'OSNTV CONNECT': 3720, 'OSNTV PRIME': 3733, 'ALFA': 1281, 'OSN PINOY PLUS EXTRA': 3519 }
+const packages = {
+ 'OSNTV CONNECT': 3720,
+ 'OSNTV PRIME': 3733,
+ ALFA: 1281,
+ 'OSN PINOY PLUS EXTRA': 3519
+}
const country = 'AE'
const tz = 'Asia/Dubai'
@@ -13,11 +18,9 @@ module.exports = {
site: 'osn.com',
days: 2,
url({ channel, date }) {
- return `https://www.osn.com/api/TVScheduleWebService.asmx/time?dt=${
- encodeURIComponent(date.format('MM/DD/YYYY'))
- }&co=${country}&ch=${
- channel.site_id
- }&mo=false&hr=0`
+ return `https://www.osn.com/api/TVScheduleWebService.asmx/time?dt=${encodeURIComponent(
+ date.format('MM/DD/YYYY')
+ )}&co=${country}&ch=${channel.site_id}&mo=false&hr=0`
},
request: {
headers({ channel }) {
@@ -46,7 +49,9 @@ module.exports = {
const axios = require('axios')
for (const pkg of Object.values(packages)) {
const channels = await axios
- .get(`https://www.osn.com/api/tvchannels.ashx?culture=en-US&packageId=${pkg}&country=${country}`)
+ .get(
+ `https://www.osn.com/api/tvchannels.ashx?culture=en-US&packageId=${pkg}&country=${country}`
+ )
.then(response => response.data)
.catch(console.error)
diff --git a/sites/osn.com/osn.com.test.js b/sites/osn.com/osn.com.test.js
index 144a0b5c..fb2fcfbc 100644
--- a/sites/osn.com/osn.com.test.js
+++ b/sites/osn.com/osn.com.test.js
@@ -28,32 +28,30 @@ it('can generate valid url', () => {
})
it('can parse response (ar)', () => {
- const result = parser({ date, channel: channelAR, content })
- .map(a => {
- a.start = a.start.toJSON()
- a.stop = a.stop.toJSON()
- return a
- })
+ const result = parser({ date, channel: channelAR, content }).map(a => {
+ a.start = a.start.toJSON()
+ a.stop = a.stop.toJSON()
+ return a
+ })
expect(result.length).toBe(29)
expect(result[1]).toMatchObject({
start: '2024-11-26T20:50:00.000Z',
stop: '2024-11-26T21:45:00.000Z',
- title: 'بيت الحلويات: الحلقة 3',
+ title: 'بيت الحلويات: الحلقة 3'
})
})
it('can parse response (en)', () => {
- const result = parser({ date, channel: channelEN, content })
- .map(a => {
- a.start = a.start.toJSON()
- a.stop = a.stop.toJSON()
- return a
- })
+ const result = parser({ date, channel: channelEN, content }).map(a => {
+ a.start = a.start.toJSON()
+ a.stop = a.stop.toJSON()
+ return a
+ })
expect(result.length).toBe(29)
expect(result[1]).toMatchObject({
start: '2024-11-26T20:50:00.000Z',
stop: '2024-11-26T21:45:00.000Z',
- title: 'House Of Desserts: Episode 3',
+ title: 'House Of Desserts: Episode 3'
})
})
diff --git a/sites/pbsguam.org/pbsguam.org.config.js b/sites/pbsguam.org/pbsguam.org.config.js
index 8be09c60..504778df 100644
--- a/sites/pbsguam.org/pbsguam.org.config.js
+++ b/sites/pbsguam.org/pbsguam.org.config.js
@@ -27,7 +27,7 @@ function parseItems(content, date) {
let data
try {
data = JSON.parse(json)
- } catch (error) {
+ } catch {
return []
}
diff --git a/sites/pickx.be/pickx.be.config.js b/sites/pickx.be/pickx.be.config.js
index 38d1ac21..c6a507d1 100644
--- a/sites/pickx.be/pickx.be.config.js
+++ b/sites/pickx.be/pickx.be.config.js
@@ -1,174 +1,172 @@
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-let apiVersion
-
-dayjs.extend(utc)
-
-module.exports = {
- site: 'pickx.be',
- days: 2,
- setApiVersion: function (version) {
- apiVersion = version
- },
- getApiVersion: function () {
- return apiVersion
- },
- fetchApiVersion: fetchApiVersion,
- url: async function ({ channel, date }) {
- if (!apiVersion) {
- await fetchApiVersion()
- }
- return `https://px-epg.azureedge.net/airings/${apiVersion}/${date.format(
- 'YYYY-MM-DD'
- )}/channel/${channel.site_id}?timezone=Europe%2FBrussels`
- },
- request: {
- headers: {
- Origin: 'https://www.pickx.be',
- Referer: 'https://www.pickx.be/'
- }
- },
- parser({ channel, content }) {
- const programs = []
- if (content) {
- const items = JSON.parse(content)
- items.forEach(item => {
- programs.push({
- title: item.program.title,
- sub_title: item.program.episodeTitle,
- description: item.program.description,
- category: item.program.translatedCategory?.[channel.lang]
- ? item.program.translatedCategory[channel.lang]
- : item.program.category.split('.')[1],
- image: item.program.posterFileName
- ? `https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/${item.program.posterFileName}`
- : null,
- season: item.program.seasonNumber,
- episode: item.program.episodeNumber,
- actors: item.program.actors,
- director: item.program.director ? [item.program.director] : null,
- start: dayjs.utc(item.programScheduleStart),
- stop: dayjs.utc(item.programScheduleEnd)
- })
- })
- }
-
- return programs
- },
- async channels({ lang = '' }) {
- const query = {
- operationName: 'getChannels',
- variables: {
- language: lang,
- queryParams: {},
- id: '0',
- params: {
- shouldReadFromCache: true
- }
- },
- query: `query getChannels($language: String!, $queryParams: ChannelQueryParams, $id: String, $params: ChannelParams) {
- channels(language: $language, queryParams: $queryParams, id: $id, params: $params) {
- id
- channelReferenceNumber
- name
- callLetter
- number
- logo {
- key
- url
- __typename
- }
- language
- hd
- radio
- replayable
- ottReplayable
- playable
- ottPlayable
- recordable
- subscribed
- cloudRecordable
- catchUpWindowInHours
- isOttNPVREnabled
- ottNPVRStart
- subscription {
- channelRef
- subscribed
- upselling {
- upsellable
- packages
- __typename
- }
- __typename
- }
- packages
- __typename
- }
- }`
- }
- const result = await axios
- .post('https://api.proximusmwc.be/tiams/v3/graphql', query)
- .then(r => r.data)
- .catch(console.error)
-
- return (
- result?.data?.channels
- .filter(
- channel =>
- !channel.radio && (!lang || channel.language === (lang === 'de' ? 'ger' : lang))
- )
- .map(channel => {
- return {
- lang: channel.language === 'ger' ? 'de' : channel.language,
- site_id: channel.id,
- name: channel.name
- }
- }) || []
- )
- }
-}
-function fetchApiVersion() {
- return new Promise(async (resolve, reject) => {
- try {
- // you'll never find what happened here :)
- // load the pickx page and get the hash from the MWC configuration.
- // it's not the best way to get the version but it's the only way to get it.
-
- const hashUrl = 'https://www.pickx.be/nl/televisie/tv-gids';
-
- const hashData = await axios.get(hashUrl)
- .then(r => {
- const re = /"hashes":\["(.*)"\]/
- const match = r.data.match(re)
- if (match && match[1]) {
- return match[1]
- } else {
- throw new Error('React app version hash not found')
- }
- })
- .catch(console.error);
-
- const versionUrl = `https://www.pickx.be/api/s-${hashData}`
-
- const response = await axios.get(versionUrl, {
- headers: {
- Origin: 'https://www.pickx.be',
- Referer: 'https://www.pickx.be/'
- }
- })
-
- if (response.status === 200) {
- apiVersion = response.data.version
- resolve()
- } else {
- console.error(`Failed to fetch API version. Status: ${response.status}`)
- reject(`Failed to fetch API version. Status: ${response.status}`)
- }
- } catch (error) {
- console.error('Error during fetchApiVersion:', error)
- reject(error)
- }
- })
-}
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+let apiVersion
+
+dayjs.extend(utc)
+
+module.exports = {
+ site: 'pickx.be',
+ days: 2,
+ setApiVersion: function (version) {
+ apiVersion = version
+ },
+ getApiVersion: function () {
+ return apiVersion
+ },
+ fetchApiVersion: fetchApiVersion,
+ url: async function ({ channel, date }) {
+ if (!apiVersion) {
+ await fetchApiVersion()
+ }
+ return `https://px-epg.azureedge.net/airings/${apiVersion}/${date.format(
+ 'YYYY-MM-DD'
+ )}/channel/${channel.site_id}?timezone=Europe%2FBrussels`
+ },
+ request: {
+ headers: {
+ Origin: 'https://www.pickx.be',
+ Referer: 'https://www.pickx.be/'
+ }
+ },
+ parser({ channel, content }) {
+ const programs = []
+ if (content) {
+ const items = JSON.parse(content)
+ items.forEach(item => {
+ programs.push({
+ title: item.program.title,
+ sub_title: item.program.episodeTitle,
+ description: item.program.description,
+ category: item.program.translatedCategory?.[channel.lang]
+ ? item.program.translatedCategory[channel.lang]
+ : item.program.category.split('.')[1],
+ image: item.program.posterFileName
+ ? `https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/${item.program.posterFileName}`
+ : null,
+ season: item.program.seasonNumber,
+ episode: item.program.episodeNumber,
+ actors: item.program.actors,
+ director: item.program.director ? [item.program.director] : null,
+ start: dayjs.utc(item.programScheduleStart),
+ stop: dayjs.utc(item.programScheduleEnd)
+ })
+ })
+ }
+
+ return programs
+ },
+ async channels({ lang = '' }) {
+ const query = {
+ operationName: 'getChannels',
+ variables: {
+ language: lang,
+ queryParams: {},
+ id: '0',
+ params: {
+ shouldReadFromCache: true
+ }
+ },
+ query: `query getChannels($language: String!, $queryParams: ChannelQueryParams, $id: String, $params: ChannelParams) {
+ channels(language: $language, queryParams: $queryParams, id: $id, params: $params) {
+ id
+ channelReferenceNumber
+ name
+ callLetter
+ number
+ logo {
+ key
+ url
+ __typename
+ }
+ language
+ hd
+ radio
+ replayable
+ ottReplayable
+ playable
+ ottPlayable
+ recordable
+ subscribed
+ cloudRecordable
+ catchUpWindowInHours
+ isOttNPVREnabled
+ ottNPVRStart
+ subscription {
+ channelRef
+ subscribed
+ upselling {
+ upsellable
+ packages
+ __typename
+ }
+ __typename
+ }
+ packages
+ __typename
+ }
+ }`
+ }
+ const result = await axios
+ .post('https://api.proximusmwc.be/tiams/v3/graphql', query)
+ .then(r => r.data)
+ .catch(console.error)
+
+ return (
+ result?.data?.channels
+ .filter(
+ channel =>
+ !channel.radio && (!lang || channel.language === (lang === 'de' ? 'ger' : lang))
+ )
+ .map(channel => {
+ return {
+ lang: channel.language === 'ger' ? 'de' : channel.language,
+ site_id: channel.id,
+ name: channel.name
+ }
+ }) || []
+ )
+ }
+}
+async function fetchApiVersion() {
+ // you'll never find what happened here :)
+ // load the pickx page and get the hash from the MWC configuration.
+ // it's not the best way to get the version but it's the only way to get it.
+ const hashUrl = 'https://www.pickx.be/nl/televisie/tv-gids'
+ const hashData = await axios
+ .get(hashUrl)
+ .then(r => {
+ const re = /"hashes":\["(.*)"\]/
+ const match = r.data.match(re)
+ if (match && match[1]) {
+ return match[1]
+ } else {
+ throw new Error('React app version hash not found')
+ }
+ })
+ .catch(console.error)
+
+ const versionUrl = `https://www.pickx.be/api/s-${hashData}`
+ const response = await axios.get(versionUrl, {
+ headers: {
+ Origin: 'https://www.pickx.be',
+ Referer: 'https://www.pickx.be/'
+ }
+ })
+
+ return new Promise((resolve, reject) => {
+ try {
+ if (response.status === 200) {
+ apiVersion = response.data.version
+ resolve()
+ } else {
+ console.error(`Failed to fetch API version. Status: ${response.status}`)
+ reject(`Failed to fetch API version. Status: ${response.status}`)
+ }
+ } catch (error) {
+ console.error('Error during fetchApiVersion:', error)
+ reject(error)
+ }
+ })
+}
diff --git a/sites/pickx.be/pickx.be.test.js b/sites/pickx.be/pickx.be.test.js
index aa89f09c..05a37ae0 100644
--- a/sites/pickx.be/pickx.be.test.js
+++ b/sites/pickx.be/pickx.be.test.js
@@ -1,76 +1,69 @@
-jest.mock('./pickx.be.config.js', () => {
- const originalModule = jest.requireActual('./pickx.be.config.js')
- return {
- ...originalModule,
- fetchApiVersion: jest.fn(() => Promise.resolve())
- }
-})
-
-const {
- parser,
- url,
- request,
- fetchApiVersion,
- setApiVersion,
- getApiVersion
-} = require('./pickx.be.config.js')
-
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-12-13').startOf('d')
-const channel = {
- lang: 'fr',
- site_id: 'UID0118',
- xmltv_id: 'Vedia.be'
-}
-
-beforeEach(() => {
- setApiVersion('mockedApiVersion')
-})
-
-it('can generate valid url', async () => {
- const generatedUrl = await url({ channel, date })
- expect(generatedUrl).toBe(
- `https://px-epg.azureedge.net/airings/mockedApiVersion/2023-12-13/channel/UID0118?timezone=Europe%2FBrussels`
- )
-})
-
-it('can generate valid request headers', () => {
- expect(request.headers).toMatchObject({
- Origin: 'https://www.pickx.be',
- Referer: 'https://www.pickx.be/'
- })
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
- const result = parser({ content, channel, date }).map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(result[0]).toMatchObject({
- start: '2023-12-12T23:55:00.000Z',
- stop: '2023-12-13T00:15:00.000Z',
- title: 'Le 22h30',
- description: 'Le journal de vivre ici.',
- category: 'Info',
- image:
- 'https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/250_250_4B990CC58066A7B2A660AFA0BDDE5C41.jpg'
- })
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- date,
- channel,
- content: ''
- })
- expect(result).toMatchObject([])
-})
+jest.mock('./pickx.be.config.js', () => {
+ const originalModule = jest.requireActual('./pickx.be.config.js')
+ return {
+ ...originalModule,
+ fetchApiVersion: jest.fn(() => Promise.resolve())
+ }
+})
+
+const { parser, url, request, setApiVersion } = require('./pickx.be.config.js')
+
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-12-13').startOf('d')
+const channel = {
+ lang: 'fr',
+ site_id: 'UID0118',
+ xmltv_id: 'Vedia.be'
+}
+
+beforeEach(() => {
+ setApiVersion('mockedApiVersion')
+})
+
+it('can generate valid url', async () => {
+ const generatedUrl = await url({ channel, date })
+ expect(generatedUrl).toBe(
+ 'https://px-epg.azureedge.net/airings/mockedApiVersion/2023-12-13/channel/UID0118?timezone=Europe%2FBrussels'
+ )
+})
+
+it('can generate valid request headers', () => {
+ expect(request.headers).toMatchObject({
+ Origin: 'https://www.pickx.be',
+ Referer: 'https://www.pickx.be/'
+ })
+})
+
+it('can parse response', () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
+ const result = parser({ content, channel, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(result[0]).toMatchObject({
+ start: '2023-12-12T23:55:00.000Z',
+ stop: '2023-12-13T00:15:00.000Z',
+ title: 'Le 22h30',
+ description: 'Le journal de vivre ici.',
+ category: 'Info',
+ image:
+ 'https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/250_250_4B990CC58066A7B2A660AFA0BDDE5C41.jpg'
+ })
+})
+
+it('can handle empty guide', () => {
+ const result = parser({
+ date,
+ channel,
+ content: ''
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/player.ee.co.uk/player.ee.co.uk.config.js b/sites/player.ee.co.uk/player.ee.co.uk.config.js
index f8a9411e..6914b017 100644
--- a/sites/player.ee.co.uk/player.ee.co.uk.config.js
+++ b/sites/player.ee.co.uk/player.ee.co.uk.config.js
@@ -1,102 +1,104 @@
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-module.exports = {
- site: 'player.ee.co.uk',
- days: 2,
- url({ date, channel, hour = 0 }) {
- return `https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=${
- encodeURIComponent(channel.site_id)
- }&interval=${date.format('YYYY-MM-DD')}T${hour.toString().padStart(2,'0')}Z/PT12H`
- },
- request: {
- headers: {
- Referer: 'https://player.ee.co.uk/'
- }
- },
- async parser({ content, channel, date }) {
- const programs = []
- if (content) {
- const schedule = JSON.parse(content)
- // fetch next 12 hours schedule
- const { url, request } = module.exports
- const nextSchedule = await axios
- .get(url({ channel, date, hour: 12 }), { headers: request.headers })
- .then(response => response.data)
- .catch(console.error)
-
- if (schedule?.items) {
- // merge schedules
- if (nextSchedule?.items) {
- schedule.items.push(...nextSchedule.items)
- }
- schedule.items.forEach(item => {
- let season, episode
- const start = dayjs.utc(item.publishedStartTime)
- const stop = start.add(item.publishedDuration, 's')
- const description = item.synopsis
- if (description) {
- const matches = description.trim().match(/\(?S(\d+)[\/\s]Ep(\d+)\)?/)
- if (matches) {
- if (matches[1]) {
- season = parseInt(matches[1])
- }
- if (matches[2]) {
- episode = parseInt(matches[2])
- }
- }
- }
- programs.push({
- title: item.title,
- description,
- season,
- episode,
- start,
- stop
- })
- })
- }
- }
-
- return programs
- },
- async channels() {
- const token =
- 'eyJkaXNjb3ZlcnlVc2VyR3JvdXBzIjpbIkFMTFVTRVJTIiwiYWxsIiwiaHR0cDovL3JlZmRhd' +
- 'GEueW91dmlldy5jb20vbXBlZzdjcy9Zb3VWaWV3QXBwbGljYXRpb25QbGF5ZXJDUy8yMDIxLT' +
- 'A5LTEwI2FuZHJvaWRfcnVudGltZS1wcm9maWxlMSIsInRhZzpidC5jb20sMjAxOC0wNy0xMTp' +
- '1c2VyZ3JvdXAjR0JSLWJ0X25vd1RWX211bHRpY2FzdCIsInRhZzpidC5jb20sMjAyMS0xMC0y' +
- 'NTp1c2VyZ3JvdXAjR0JSLWJ0X2V1cm9zcG9ydCJdLCJyZWdpb25zIjpbIkFMTFJFR0lPTlMiL' +
- 'CJHQlIiLCJHQlItRU5HIiwiR0JSLUVORy1sb25kb24iLCJhbGwiXSwic3Vic2V0IjoiMy41Lj' +
- 'EvYW5kcm9pZF9ydW50aW1lLXByb2ZpbGUxL0JST0FEQ0FTVF9JUC9HQlItYnRfYnJvYWRiYW5' +
- 'kIiwic3Vic2V0cyI6WyIvLy8iLCIvL0JST0FEQ0FTVF9JUC8iLCIzLjUvLy8iXX0='
- const extensions = [
- 'LinearCategoriesExtension',
- 'LogicalChannelNumberExtension',
- 'BTSubscriptionCodesExtension'
- ]
- const result = await axios
- .get(`https://api.youview.tv/metadata/linear/v2/linear-services`, {
- params: {
- contentTargetingToken: token,
- extensions: extensions.join(',')
- },
- headers: module.exports.request.headers
- })
- .then(response => response.data)
- .catch(console.error)
-
- return result?.items
- .filter(channel => channel.contentTypes.indexOf('tv') >= 0)
- .map(channel => {
- return {
- lang: 'en',
- site_id: channel.serviceLocator,
- name: channel.fullName
- }
- }) || []
- }
-}
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+module.exports = {
+ site: 'player.ee.co.uk',
+ days: 2,
+ url({ date, channel, hour = 0 }) {
+ return `https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=${encodeURIComponent(
+ channel.site_id
+ )}&interval=${date.format('YYYY-MM-DD')}T${hour.toString().padStart(2, '0')}Z/PT12H`
+ },
+ request: {
+ headers: {
+ Referer: 'https://player.ee.co.uk/'
+ }
+ },
+ async parser({ content, channel, date }) {
+ const programs = []
+ if (content) {
+ const schedule = JSON.parse(content)
+ // fetch next 12 hours schedule
+ const { url, request } = module.exports
+ const nextSchedule = await axios
+ .get(url({ channel, date, hour: 12 }), { headers: request.headers })
+ .then(response => response.data)
+ .catch(console.error)
+
+ if (schedule?.items) {
+ // merge schedules
+ if (nextSchedule?.items) {
+ schedule.items.push(...nextSchedule.items)
+ }
+ schedule.items.forEach(item => {
+ let season, episode
+ const start = dayjs.utc(item.publishedStartTime)
+ const stop = start.add(item.publishedDuration, 's')
+ const description = item.synopsis
+ if (description) {
+ const matches = description.trim().match(/\(?S(\d+)[/\s]Ep(\d+)\)?/)
+ if (matches) {
+ if (matches[1]) {
+ season = parseInt(matches[1])
+ }
+ if (matches[2]) {
+ episode = parseInt(matches[2])
+ }
+ }
+ }
+ programs.push({
+ title: item.title,
+ description,
+ season,
+ episode,
+ start,
+ stop
+ })
+ })
+ }
+ }
+
+ return programs
+ },
+ async channels() {
+ const token =
+ 'eyJkaXNjb3ZlcnlVc2VyR3JvdXBzIjpbIkFMTFVTRVJTIiwiYWxsIiwiaHR0cDovL3JlZmRhd' +
+ 'GEueW91dmlldy5jb20vbXBlZzdjcy9Zb3VWaWV3QXBwbGljYXRpb25QbGF5ZXJDUy8yMDIxLT' +
+ 'A5LTEwI2FuZHJvaWRfcnVudGltZS1wcm9maWxlMSIsInRhZzpidC5jb20sMjAxOC0wNy0xMTp' +
+ '1c2VyZ3JvdXAjR0JSLWJ0X25vd1RWX211bHRpY2FzdCIsInRhZzpidC5jb20sMjAyMS0xMC0y' +
+ 'NTp1c2VyZ3JvdXAjR0JSLWJ0X2V1cm9zcG9ydCJdLCJyZWdpb25zIjpbIkFMTFJFR0lPTlMiL' +
+ 'CJHQlIiLCJHQlItRU5HIiwiR0JSLUVORy1sb25kb24iLCJhbGwiXSwic3Vic2V0IjoiMy41Lj' +
+ 'EvYW5kcm9pZF9ydW50aW1lLXByb2ZpbGUxL0JST0FEQ0FTVF9JUC9HQlItYnRfYnJvYWRiYW5' +
+ 'kIiwic3Vic2V0cyI6WyIvLy8iLCIvL0JST0FEQ0FTVF9JUC8iLCIzLjUvLy8iXX0='
+ const extensions = [
+ 'LinearCategoriesExtension',
+ 'LogicalChannelNumberExtension',
+ 'BTSubscriptionCodesExtension'
+ ]
+ const result = await axios
+ .get('https://api.youview.tv/metadata/linear/v2/linear-services', {
+ params: {
+ contentTargetingToken: token,
+ extensions: extensions.join(',')
+ },
+ headers: module.exports.request.headers
+ })
+ .then(response => response.data)
+ .catch(console.error)
+
+ return (
+ result?.items
+ .filter(channel => channel.contentTypes.indexOf('tv') >= 0)
+ .map(channel => {
+ return {
+ lang: 'en',
+ site_id: channel.serviceLocator,
+ name: channel.fullName
+ }
+ }) || []
+ )
+ }
+}
diff --git a/sites/player.ee.co.uk/player.ee.co.uk.test.js b/sites/player.ee.co.uk/player.ee.co.uk.test.js
index 19c90cda..30424e74 100644
--- a/sites/player.ee.co.uk/player.ee.co.uk.test.js
+++ b/sites/player.ee.co.uk/player.ee.co.uk.test.js
@@ -1,72 +1,74 @@
-const { parser, url } = require('./player.ee.co.uk.config.js')
-const fs = require('fs')
-const path = require('path')
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-jest.mock('axios')
-
-const date = dayjs.utc('2023-12-13').startOf('d')
-const channel = {
- site_id: 'dvb://233a..6d60',
- xmltv_id: 'HGTV.uk'
-}
-
-axios.get.mockImplementation((url, opts) => {
- if (url === 'https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=dvb%3A%2F%2F233a..6d60&interval=2023-12-13T12Z/PT12H') {
- return Promise.resolve({
- data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/data1.json')))
- })
- }
-
- return Promise.resolve({ data: '' })
-})
-
-it('can generate valid url', () => {
- expect(url({ date, channel })).toBe(
- 'https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=dvb%3A%2F%2F233a..6d60&interval=2023-12-13T00Z/PT12H'
- )
-})
-
-it('can parse response', async () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
- const result = (await parser({ content, channel, date }))
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: 'Bargain Mansions',
- description:
- 'Tamara and her dad help a recent widow who loves to cook for her family design her dream kitchen, perfect for entertaining and large gatherings. S4/Ep1',
- season: 4,
- episode: 1,
- start: '2023-12-13T13:00:00.000Z',
- stop: '2023-12-13T14:00:00.000Z'
- },
- {
- title: 'Flip Or Flop',
- description:
- 'Tarek and Christina are contacted by a cash strapped flipper who needs to unload a project house. S2/Ep2',
- season: 2,
- episode: 2,
- start: '2023-12-13T14:00:00.000Z',
- stop: '2023-12-13T14:30:00.000Z'
- }
- ])
-})
-
-it('can handle empty guide', async () => {
- const result = await parser({
- channel,
- date,
- content: ''
- })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./player.ee.co.uk.config.js')
+const fs = require('fs')
+const path = require('path')
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+jest.mock('axios')
+
+const date = dayjs.utc('2023-12-13').startOf('d')
+const channel = {
+ site_id: 'dvb://233a..6d60',
+ xmltv_id: 'HGTV.uk'
+}
+
+axios.get.mockImplementation(url => {
+ if (
+ url ===
+ 'https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=dvb%3A%2F%2F233a..6d60&interval=2023-12-13T12Z/PT12H'
+ ) {
+ return Promise.resolve({
+ data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/data1.json')))
+ })
+ }
+
+ return Promise.resolve({ data: '' })
+})
+
+it('can generate valid url', () => {
+ expect(url({ date, channel })).toBe(
+ 'https://api.youview.tv/metadata/linear/v2/schedule/by-servicelocator?serviceLocator=dvb%3A%2F%2F233a..6d60&interval=2023-12-13T00Z/PT12H'
+ )
+})
+
+it('can parse response', async () => {
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json'))
+ const result = (await parser({ content, channel, date })).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Bargain Mansions',
+ description:
+ 'Tamara and her dad help a recent widow who loves to cook for her family design her dream kitchen, perfect for entertaining and large gatherings. S4/Ep1',
+ season: 4,
+ episode: 1,
+ start: '2023-12-13T13:00:00.000Z',
+ stop: '2023-12-13T14:00:00.000Z'
+ },
+ {
+ title: 'Flip Or Flop',
+ description:
+ 'Tarek and Christina are contacted by a cash strapped flipper who needs to unload a project house. S2/Ep2',
+ season: 2,
+ episode: 2,
+ start: '2023-12-13T14:00:00.000Z',
+ stop: '2023-12-13T14:30:00.000Z'
+ }
+ ])
+})
+
+it('can handle empty guide', async () => {
+ const result = await parser({
+ channel,
+ date,
+ content: ''
+ })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/playtv.unifi.com.my/playtv.unifi.com.my.config.js b/sites/playtv.unifi.com.my/playtv.unifi.com.my.config.js
index 787d235e..d426eeb5 100644
--- a/sites/playtv.unifi.com.my/playtv.unifi.com.my.config.js
+++ b/sites/playtv.unifi.com.my/playtv.unifi.com.my.config.js
@@ -43,7 +43,7 @@ module.exports = {
const axios = require('axios')
const data = await axios
.post(
- `https://playtv.unifi.com.my:7053/VSP/V3/QueryAllChannel`,
+ 'https://playtv.unifi.com.my:7053/VSP/V3/QueryAllChannel',
{ isReturnAllMedia: '0' },
{
params: {
@@ -74,7 +74,7 @@ function parseItems(content, channel) {
const channelData = data.find(i => i.id == channel.site_id)
return channelData.items && Array.isArray(channelData.items) ? channelData.items : []
- } catch (err) {
+ } catch {
return []
}
}
diff --git a/sites/pluto.tv/pluto.tv.config.js b/sites/pluto.tv/pluto.tv.config.js
index ade3ea2c..294e130e 100644
--- a/sites/pluto.tv/pluto.tv.config.js
+++ b/sites/pluto.tv/pluto.tv.config.js
@@ -1,50 +1,49 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const axios = require('axios')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-
-module.exports = {
- site: 'pluto.tv',
- days: 3,
-
- url: function ({ date, channel }) {
- const channelId = channel.site_id
-
- const localTimezone = dayjs.tz.guess()
-
- const startTime = dayjs(date).tz(localTimezone).startOf('day').toISOString()
- const endTime = dayjs(date).tz(localTimezone).add(this.days, 'day').endOf('day').toISOString()
-
- const generatedUrl = `https://api.pluto.tv/v2/channels/${channelId}?start=${startTime}&stop=${endTime}`
- return generatedUrl
- },
-
- parser: function ({ content }) {
- const data = JSON.parse(content)
- const programs = []
-
- if (data.timelines) {
- data.timelines.forEach(item => {
- programs.push({
- title: item.title,
- subTitle: item.episode?.name || '',
- description: item.episode?.description || '',
- episode: item.episode?.number || '',
- season: item.episode?.season || '',
- actors: item.episode?.clip?.actors || [],
- categories: [item.episode?.genre, item.episode?.subGenre].filter(Boolean),
- rating: item.episode?.rating || '',
- date: item.episode?.clip?.originalReleaseDate || '',
- icon: item.episode?.series?.tile?.path || '',
- start: item.start,
- stop: item.stop
- })
- })
- }
-
- return programs
- }
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+
+module.exports = {
+ site: 'pluto.tv',
+ days: 3,
+
+ url: function ({ date, channel }) {
+ const channelId = channel.site_id
+
+ const localTimezone = dayjs.tz.guess()
+
+ const startTime = dayjs(date).tz(localTimezone).startOf('day').toISOString()
+ const endTime = dayjs(date).tz(localTimezone).add(this.days, 'day').endOf('day').toISOString()
+
+ const generatedUrl = `https://api.pluto.tv/v2/channels/${channelId}?start=${startTime}&stop=${endTime}`
+ return generatedUrl
+ },
+
+ parser: function ({ content }) {
+ const data = JSON.parse(content)
+ const programs = []
+
+ if (data.timelines) {
+ data.timelines.forEach(item => {
+ programs.push({
+ title: item.title,
+ subTitle: item.episode?.name || '',
+ description: item.episode?.description || '',
+ episode: item.episode?.number || '',
+ season: item.episode?.season || '',
+ actors: item.episode?.clip?.actors || [],
+ categories: [item.episode?.genre, item.episode?.subGenre].filter(Boolean),
+ rating: item.episode?.rating || '',
+ date: item.episode?.clip?.originalReleaseDate || '',
+ icon: item.episode?.series?.tile?.path || '',
+ start: item.start,
+ stop: item.stop
+ })
+ })
+ }
+
+ return programs
+ }
+}
diff --git a/sites/pluto.tv/pluto.tv.test.js b/sites/pluto.tv/pluto.tv.test.js
index eed3fbd5..37ec1a81 100644
--- a/sites/pluto.tv/pluto.tv.test.js
+++ b/sites/pluto.tv/pluto.tv.test.js
@@ -33,14 +33,17 @@ it('can parse response', () => {
start: '2024-12-28T00:21:00.000Z',
stop: '2024-12-28T00:48:00.000Z',
title: 'Naruto: El Tercer Hokage, Eternamente',
- description: 'Gaara y Naruto continúan combatiendo con todas sus fuerzas. Decidido a proteger a Sakura, Naruto ataca a Gaara una y otra vez.',
+ description:
+ 'Gaara y Naruto continúan combatiendo con todas sus fuerzas. Decidido a proteger a Sakura, Naruto ataca a Gaara una y otra vez.',
subTitle: 'El Tercer Hokage, Eternamente',
episode: 80,
season: 2,
- actors: ["Isabel Martion (Naruto Uzumaki)",
- "Christine Byrd (Sakura Haruno)",
- "Victor Ugarte (Sasuke Uchiha)",
- "Alfonso Obreg (Kakashi Hatake)"],
+ actors: [
+ 'Isabel Martion (Naruto Uzumaki)',
+ 'Christine Byrd (Sakura Haruno)',
+ 'Victor Ugarte (Sasuke Uchiha)',
+ 'Alfonso Obreg (Kakashi Hatake)'
+ ],
categories: ['Anime', 'Anime Action & Adventure'],
rating: 'TV-14',
date: '2004-04-21T00:00:00.000Z',
diff --git a/sites/pluto.tv/pluto.tv_ca.channels.xml b/sites/pluto.tv/pluto.tv_ca.channels.xml
index 980c61ad..1d714c33 100644
--- a/sites/pluto.tv/pluto.tv_ca.channels.xml
+++ b/sites/pluto.tv/pluto.tv_ca.channels.xml
@@ -1,4 +1,3 @@
-
Pluto TV Advent Calendar
diff --git a/sites/pluto.tv/pluto.tv_uk.channels.xml b/sites/pluto.tv/pluto.tv_uk.channels.xml
index ae052b92..23c413b5 100644
--- a/sites/pluto.tv/pluto.tv_uk.channels.xml
+++ b/sites/pluto.tv/pluto.tv_uk.channels.xml
@@ -1,4 +1,3 @@
-
Diane, femme flic
diff --git a/sites/programetv.ro/programetv.ro.config.js b/sites/programetv.ro/programetv.ro.config.js
index f55eea31..4a14f0e5 100644
--- a/sites/programetv.ro/programetv.ro.config.js
+++ b/sites/programetv.ro/programetv.ro.config.js
@@ -46,10 +46,10 @@ module.exports = {
return programs
},
- async channels({ country, lang }) {
+ async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://www.programetv.ro/api/station/index/`)
+ .get('https://www.programetv.ro/api/station/index/')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/programme-tv.net/programme-tv.net.config.js b/sites/programme-tv.net/programme-tv.net.config.js
index 21810bef..4d69ed6e 100644
--- a/sites/programme-tv.net/programme-tv.net.config.js
+++ b/sites/programme-tv.net/programme-tv.net.config.js
@@ -62,7 +62,7 @@ module.exports = {
$('.channelList-listItemsLink').each((i, el) => {
const name = $(el).attr('title')
const url = $(el).attr('href')
- const [, site_id] = url.match(/\/programme\-(.*)\.html$/i)
+ const [, site_id] = url.match(/\/programme-(.*)\.html$/i)
channels.push({
lang: 'fr',
diff --git a/sites/programme-tv.vini.pf/programme-tv.vini.pf.config.js b/sites/programme-tv.vini.pf/programme-tv.vini.pf.config.js
index 6d17bb8b..1e697583 100644
--- a/sites/programme-tv.vini.pf/programme-tv.vini.pf.config.js
+++ b/sites/programme-tv.vini.pf/programme-tv.vini.pf.config.js
@@ -51,7 +51,7 @@ module.exports = {
return data.programmes.map(item => {
const site_id = item.url.replace('/', '')
- const name = site_id.replace(/\-/gi, ' ')
+ const name = site_id.replace(/-/gi, ' ')
return {
lang: 'fr',
diff --git a/sites/programme.tvb.com/programme.tvb.com.config.js b/sites/programme.tvb.com/programme.tvb.com.config.js
index c487257e..87c3580e 100644
--- a/sites/programme.tvb.com/programme.tvb.com.config.js
+++ b/sites/programme.tvb.com/programme.tvb.com.config.js
@@ -13,19 +13,17 @@ module.exports = {
site: 'programme.tvb.com',
days: 2,
url({ channel, date, time = null }) {
- return `https://programme.tvb.com/api/schedule?input_date=${
- date.format('YYYYMMDD')
- }&network_code=${channel.site_id}&_t=${time ? time : parseInt(Date.now() / 1000)}`
+ return `https://programme.tvb.com/api/schedule?input_date=${date.format(
+ 'YYYYMMDD'
+ )}&network_code=${channel.site_id}&_t=${time ? time : parseInt(Date.now() / 1000)}`
},
parser({ content, channel, date }) {
const programs = []
const data = content ? JSON.parse(content) : {}
if (Array.isArray(data.data?.list)) {
- const dt = date.format('YYYY-MM-DD')
for (const d of data.data.list) {
if (Array.isArray(d.schedules)) {
- const schedules = d.schedules
- .filter(s => s.network_code === channel.site_id)
+ const schedules = d.schedules.filter(s => s.network_code === channel.site_id)
schedules.forEach((s, i) => {
const start = dayjs.tz(s.event_datetime, 'YYYY-MM-DD HH:mm:ss', tz)
let stop
@@ -64,7 +62,7 @@ module.exports = {
if (assets) {
queues.push(...assets.map(a => base + '/' + a))
} else {
- const metadata = content.match(/e\=(\[(.*?)\])/)
+ const metadata = content.match(/e=(\[(.*?)\])/)
if (metadata) {
const infos = eval(metadata[1])
if (Array.isArray(infos)) {
diff --git a/sites/programme.tvb.com/programme.tvb.com.test.js b/sites/programme.tvb.com/programme.tvb.com.test.js
index 8bcf56f7..558f4600 100644
--- a/sites/programme.tvb.com/programme.tvb.com.test.js
+++ b/sites/programme.tvb.com/programme.tvb.com.test.js
@@ -34,7 +34,7 @@ it('can parse response (en)', () => {
expect(results[1]).toMatchObject({
start: '2024-12-06T15:55:00.000Z',
stop: '2024-12-06T16:55:00.000Z',
- title: 'Line Walker: Bull Fight#16[Can][PG]',
+ title: 'Line Walker: Bull Fight#16[Can][PG]'
})
})
@@ -51,7 +51,7 @@ it('can parse response (zh)', () => {
stop: '2024-12-06T16:55:00.000Z',
title: '使徒行者3#16[粵][PG]',
description:
- '文鼎從淑梅手上救走大聖爺兒子,大聖爺還恩於歡喜,答允支持九指強。崇聯社定下選舉日子,恰巧是韋傑出獄之日,頭目們顧念舊日恩義,紛紛轉投浩洋。浩洋帶亞希逛傢俬店,憧憬二人未來。亞希向家強承認愛上浩洋,要求退出臥底任務。作榮與歡喜暗中會面,將國際犯罪組織「永恆幫」情報交給他。阿火遭家強出賣,到沐足店搶錢。家強逮住阿火,惟被合星誤會而受拘捕。家強把正植遺下的頸鏈和學生證交還,合星意識到家強已知悉正植身世。',
+ '文鼎從淑梅手上救走大聖爺兒子,大聖爺還恩於歡喜,答允支持九指強。崇聯社定下選舉日子,恰巧是韋傑出獄之日,頭目們顧念舊日恩義,紛紛轉投浩洋。浩洋帶亞希逛傢俬店,憧憬二人未來。亞希向家強承認愛上浩洋,要求退出臥底任務。作榮與歡喜暗中會面,將國際犯罪組織「永恆幫」情報交給他。阿火遭家強出賣,到沐足店搶錢。家強逮住阿火,惟被合星誤會而受拘捕。家強把正植遺下的頸鏈和學生證交還,合星意識到家強已知悉正植身世。'
})
})
diff --git a/sites/programtv.onet.pl/programtv.onet.pl.config.js b/sites/programtv.onet.pl/programtv.onet.pl.config.js
index 62e4c447..64ff12df 100644
--- a/sites/programtv.onet.pl/programtv.onet.pl.config.js
+++ b/sites/programtv.onet.pl/programtv.onet.pl.config.js
@@ -50,7 +50,7 @@ module.exports = {
$('ul.channelList a').each((i, el) => {
const name = $(el).text()
const url = $(el).attr('href')
- const [, site_id] = url.match(/^\/program\-tv\/(.*)$/i)
+ const [, site_id] = url.match(/^\/program-tv\/(.*)$/i)
channels.push({
lang: 'pl',
diff --git a/sites/rev.bs/rev.bs.config.js b/sites/rev.bs/rev.bs.config.js
index 67dcd7bd..c956fd1c 100644
--- a/sites/rev.bs/rev.bs.config.js
+++ b/sites/rev.bs/rev.bs.config.js
@@ -58,7 +58,7 @@ function parseItems(content, channel) {
let data
try {
data = JSON.parse(content)
- } catch (error) {
+ } catch {
return []
}
diff --git a/sites/rotana.net/rotana.net.config.js b/sites/rotana.net/rotana.net.config.js
index 9eb0b930..f38abbff 100644
--- a/sites/rotana.net/rotana.net.config.js
+++ b/sites/rotana.net/rotana.net.config.js
@@ -11,9 +11,7 @@ dayjs.extend(timezone)
dayjs.extend(utc)
dayjs.extend(customParseFormat)
-doFetch
- .setCheckResult(false)
- .setDebugger(debug)
+doFetch.setCheckResult(false).setDebugger(debug)
const tz = 'Asia/Riyadh'
const defaultHeaders = {
@@ -47,7 +45,7 @@ module.exports = {
headers: {
...defaultHeaders,
'X-Requested-With': 'XMLHttpRequest',
- cookie: cookies[channel.lang],
+ cookie: cookies[channel.lang]
}
}
queues.push({ i: item, url, params })
@@ -61,7 +59,7 @@ module.exports = {
},
async channels({ lang = 'en' }) {
const result = await axios
- .get(`https://rotana.net/api/channels`)
+ .get('https://rotana.net/api/channels')
.then(response => response.data)
.catch(console.error)
@@ -88,34 +86,37 @@ function parseProgram(item, result) {
item.description = desc
}
}
- break;
+ break
case 'Element':
if (el.name === 'span') {
- const [k, v] = $(el).text().split(':').map(a => a.trim())
+ const [k, v] = $(el)
+ .text()
+ .split(':')
+ .map(a => a.trim())
switch (k) {
case 'Category':
case 'التصنيف':
- item.category = v;
- break;
+ item.category = v
+ break
case 'Country':
case 'البلد':
- item.country = v;
- break;
+ item.country = v
+ break
case 'Director':
case 'المخرج':
- item.director = v;
- break;
+ item.director = v
+ break
case 'Language':
case 'اللغة':
- item.language = v;
- break;
+ item.language = v
+ break
case 'Release Year':
case 'سنة الإصدار':
- item.date = v;
- break;
+ item.date = v
+ break
}
}
- break;
+ break
}
}
}
@@ -142,7 +143,9 @@ function parseItems(content, date) {
const heading = top.find('.iq-accordion-title .big-title')
if (heading.length) {
const progId = top.attr('id')
- const title = heading.find('span:eq(1)').text()
+ const title = heading
+ .find('span:eq(1)')
+ .text()
.split('\n')
.map(a => a.trim())
.join(' ')
@@ -151,7 +154,7 @@ function parseItems(content, date) {
items.push({
program: progId.substr(progId.indexOf('-') + 1),
title: title ? title.trim() : title,
- start: `${y}-${m}-${d} ${time.trim()}`,
+ start: `${y}-${m}-${d} ${time.trim()}`
})
}
}
diff --git a/sites/rotana.net/rotana.net.test.js b/sites/rotana.net/rotana.net.test.js
index 17803fdd..ef49b147 100644
--- a/sites/rotana.net/rotana.net.test.js
+++ b/sites/rotana.net/rotana.net.test.js
@@ -19,7 +19,7 @@ const channel = {
}
const channelAr = Object.assign({}, channel, { lang: 'ar' })
-axios.get.mockImplementation((url, opts) => {
+axios.get.mockImplementation(url => {
if (url === 'https://rotana.net/en/streams?channel=439&itemId=736970') {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/program_en.html'))
@@ -52,11 +52,13 @@ it('can generate valid arabic url', () => {
})
it('can parse english response', async () => {
- const result = (await parser({
- channel,
- date,
- content: fs.readFileSync(path.join(__dirname, '/__data__/content_en.html'))
- })).map(a => {
+ const result = (
+ await parser({
+ channel,
+ date,
+ content: fs.readFileSync(path.join(__dirname, '/__data__/content_en.html'))
+ })
+ ).map(a => {
a.start = a.start.toJSON()
a.stop = a.stop.toJSON()
return a
@@ -69,17 +71,20 @@ it('can parse english response', async () => {
title: 'Khiyana Mashroua',
description:
'Hisham knows that his father has given all his wealth to his elder brother. This leads him to plan to kill his brother to make it look like a defense of honor, which he does by killing his wife along...',
- image: 'https://s3.eu-central-1.amazonaws.com/rotana.website/spider_storage/1398X1000/1687084565',
+ image:
+ 'https://s3.eu-central-1.amazonaws.com/rotana.website/spider_storage/1398X1000/1687084565',
category: 'Movie'
})
})
it('can parse arabic response', async () => {
- const result = (await parser({
- channel: channelAr,
- date,
- content: fs.readFileSync(path.join(__dirname, '/__data__/content_ar.html'))
- })).map(a => {
+ const result = (
+ await parser({
+ channel: channelAr,
+ date,
+ content: fs.readFileSync(path.join(__dirname, '/__data__/content_ar.html'))
+ })
+ ).map(a => {
a.start = a.start.toJSON()
a.stop = a.stop.toJSON()
return a
@@ -92,7 +97,8 @@ it('can parse arabic response', async () => {
title: 'خيانة مشروعة',
description:
'يعلم هشام البحيري أن والده قد حرمه من الميراث، ووهب كل ثروته لشقيقه اﻷكبر، وهو ما يدفعه لتدبير جريمة قتل شقيقه لتبدو وكأنها دفاع عن الشرف، وذلك حين يقتل هشام زوجته مع شقيقه.',
- image: 'https://s3.eu-central-1.amazonaws.com/rotana.website/spider_storage/1398X1000/1687084565',
+ image:
+ 'https://s3.eu-central-1.amazonaws.com/rotana.website/spider_storage/1398X1000/1687084565',
category: 'فيلم'
})
})
diff --git a/sites/rtb.gov.bn/rtb.gov.bn.config.js b/sites/rtb.gov.bn/rtb.gov.bn.config.js
index 3af095de..c560f224 100644
--- a/sites/rtb.gov.bn/rtb.gov.bn.config.js
+++ b/sites/rtb.gov.bn/rtb.gov.bn.config.js
@@ -53,7 +53,7 @@ async function parseItems(buffer) {
let data
try {
data = await pdf(buffer)
- } catch (err) {
+ } catch {
return []
}
diff --git a/sites/rtp.pt/rtp.pt.config.js b/sites/rtp.pt/rtp.pt.config.js
index a2f1e008..0108e255 100644
--- a/sites/rtp.pt/rtp.pt.config.js
+++ b/sites/rtp.pt/rtp.pt.config.js
@@ -1,5 +1,4 @@
const _ = require('lodash')
-const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
diff --git a/sites/s.mxtv.jp/s.mxtv.jp.config.js b/sites/s.mxtv.jp/s.mxtv.jp.config.js
index e676d826..d85d3c06 100644
--- a/sites/s.mxtv.jp/s.mxtv.jp.config.js
+++ b/sites/s.mxtv.jp/s.mxtv.jp.config.js
@@ -1,5 +1,5 @@
const dayjs = require('dayjs')
-const duration = require("dayjs/plugin/duration")
+const duration = require('dayjs/plugin/duration')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
@@ -10,72 +10,74 @@ dayjs.extend(customParseFormat)
dayjs.extend(duration)
module.exports = {
- site: 's.mxtv.jp',
- days: 1,
- lang: 'ja',
- url: function ({ date, channel }) {
- const id = `SV${channel.site_id}EPG${date.format('YYYYMMDD')}`
- return `https://s.mxtv.jp/bangumi_file/json01/${id}.json`
- },
- parser: function ({ content }) {
- let programs = []
- const items = parseItems(content)
- items.forEach(item => {
- programs.push({
- title: item.Event_name,
- description: item.Event_text,
- category: parseCategory(item),
- image: parseImage(item),
- start: parseStart(item),
- stop: parseStop(item)
- })
- })
- return programs
- },
- channels() {
- return [
- {
- lang: 'ja',
- site_id: '1',
- name: 'Tokyo MX1',
- xmltv_id: 'TokyoMX1.jp'
- },
- {
- lang: 'ja',
- site_id: '2',
- name: 'Tokyo MX2',
- xmltv_id: 'TokyoMX2.jp'
- }
- ]
- }
+ site: 's.mxtv.jp',
+ days: 1,
+ lang: 'ja',
+ url: function ({ date, channel }) {
+ const id = `SV${channel.site_id}EPG${date.format('YYYYMMDD')}`
+ return `https://s.mxtv.jp/bangumi_file/json01/${id}.json`
+ },
+ parser: function ({ content }) {
+ let programs = []
+ const items = parseItems(content)
+ items.forEach(item => {
+ programs.push({
+ title: item.Event_name,
+ description: item.Event_text,
+ category: parseCategory(item),
+ image: parseImage(item),
+ start: parseStart(item),
+ stop: parseStop(item)
+ })
+ })
+ return programs
+ },
+ channels() {
+ return [
+ {
+ lang: 'ja',
+ site_id: '1',
+ name: 'Tokyo MX1',
+ xmltv_id: 'TokyoMX1.jp'
+ },
+ {
+ lang: 'ja',
+ site_id: '2',
+ name: 'Tokyo MX2',
+ xmltv_id: 'TokyoMX2.jp'
+ }
+ ]
+ }
}
-function parseImage(item) {
- // Should return a string if we can output an image URL
- // Might be done with `https://s.mxtv.jp/bangumi/link/weblinkU.csv?1722421896752` ?
- return null
+function parseImage() {
+ // Should return a string if we can output an image URL
+ // Might be done with `https://s.mxtv.jp/bangumi/link/weblinkU.csv?1722421896752` ?
+ return null
}
-function parseCategory(item) {
- // Should return a string if we can determine the category
- // Might be done with `https://s.mxtv.jp/index_set/csv/ranking_bangumi_allU.csv` ?
- return null
+function parseCategory() {
+ // Should return a string if we can determine the category
+ // Might be done with `https://s.mxtv.jp/index_set/csv/ranking_bangumi_allU.csv` ?
+ return null
}
function parseStart(item) {
- return dayjs.tz(item.Start_time.toString(), 'YYYY年MM月DD日HH時mm分ss秒', 'Asia/Tokyo')
+ return dayjs.tz(item.Start_time.toString(), 'YYYY年MM月DD日HH時mm分ss秒', 'Asia/Tokyo')
}
function parseStop(item) {
- // Add the duration to the start time
- const durationDate = dayjs(item.Duration, 'HH:mm:ss');
- return parseStart(item).add(dayjs.duration({
- hours: durationDate.hour(),
- minutes: durationDate.minute(),
- seconds: durationDate.second()
- }))
+ // Add the duration to the start time
+ const durationDate = dayjs(item.Duration, 'HH:mm:ss')
+ return parseStart(item).add(
+ dayjs.duration({
+ hours: durationDate.hour(),
+ minutes: durationDate.minute(),
+ seconds: durationDate.second()
+ })
+ )
}
function parseItems(content) {
- return JSON.parse(content) || []
+ return JSON.parse(content) || []
}
diff --git a/sites/s.mxtv.jp/s.mxtv.jp.test.js b/sites/s.mxtv.jp/s.mxtv.jp.test.js
index f2219d31..b6891abc 100644
--- a/sites/s.mxtv.jp/s.mxtv.jp.test.js
+++ b/sites/s.mxtv.jp/s.mxtv.jp.test.js
@@ -11,7 +11,8 @@ const channel = {
name: 'Tokyo MX2',
xmltv_id: 'TokyoMX2.jp'
}
-const content = `[{ "Event_id": "0x6a57", "Start_time": "2024年07月27日05時00分00秒", "Duration": "01:00:00", "Event_name": "ヒーリングタイム&ヘッドラインニュース", "Event_text": "ねこの足跡", "Component": "480i 16:9 パンベクトルなし", "Sound": "ステレオ", "Event_detail": ""}]`
+const content =
+ '[{ "Event_id": "0x6a57", "Start_time": "2024年07月27日05時00分00秒", "Duration": "01:00:00", "Event_name": "ヒーリングタイム&ヘッドラインニュース", "Event_text": "ねこの足跡", "Component": "480i 16:9 パンベクトルなし", "Sound": "ステレオ", "Event_detail": ""}]'
it('can generate valid url', () => {
const result = url({ date, channel })
diff --git a/sites/sat.tv/sat.tv.config.js b/sites/sat.tv/sat.tv.config.js
index c0568c5a..8a011a33 100644
--- a/sites/sat.tv/sat.tv.config.js
+++ b/sites/sat.tv/sat.tv.config.js
@@ -114,7 +114,7 @@ module.exports = {
const $ = cheerio.load(data)
$('.main-container-channels-events > .container-channel-events').each((i, el) => {
const name = $(el).find('.channel-title').text().trim()
- const channelId = name.replace(/\s\&\s/gi, ' & ')
+ const channelId = name.replace(/\s&\s/gi, ' & ')
if (!name) return
diff --git a/sites/shahid.mbc.net/shahid.mbc.net.config.js b/sites/shahid.mbc.net/shahid.mbc.net.config.js
index 0e31cbc2..a847c769 100644
--- a/sites/shahid.mbc.net/shahid.mbc.net.config.js
+++ b/sites/shahid.mbc.net/shahid.mbc.net.config.js
@@ -1,74 +1,79 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-module.exports = {
- site: 'shahid.mbc.net',
- days: 2,
- url({ channel, date}) {
- return `https://api2.shahid.net/proxy/v2.1/shahid-epg-api/?csvChannelIds=${channel.site_id}&from=${date.format('YYYY-MM-DD')}T00:00:00.000Z&to=${date.format('YYYY-MM-DD')}T23:59:59.999Z&country=SA&language=${channel.lang}&Accept-Language=${channel.lang}`
- },
- parser({ content, channel }) {
- const programs = parseItems(content, channel)
- .map(item => {
- return {
- title: item.title,
- description: item.description,
- session: item.seasonNumber,
- episode: item.episodeNumber,
- start: dayjs.tz(item.actualFrom, 'Asia/Riyadh').toISOString(),
- stop: dayjs.tz(item.actualTo, 'Asia/Riyadh').toISOString()
- }
- })
-
- return programs
- },
- async channels({lang = 'en'}) {
- const axios = require('axios')
- const items = []
- let page = 0
- while (true) {
- const result = await axios
- .get(`https://api2.shahid.net/proxy/v2.1/product/filter?filter=%7B"pageNumber":${page},"pageSize":100,"productType":"LIVESTREAM","productSubType":"LIVE_CHANNEL"%7D&country=SA&language=${lang}&Accept-Language=${lang}`)
- .then(response => response.data)
- .catch(console.error)
- if (result.productList) {
- items.push(...result.productList.products)
- if (result.productList.hasMore) {
- page++
- continue
- }
- }
- break;
- }
- const channels = items.map(channel => {
- return {
- lang,
- site_id: channel.id,
- name: channel.title
- }
- })
-
- return channels
- }
-}
-
-function parseItems(content, channel) {
- const items = []
- content = content ? JSON.parse(content) : []
- if (content.items) {
- content.items.forEach(schedules => {
- if (schedules.channelId == channel.site_id) {
- items.push(...schedules.items)
- return true
- }
- })
- }
-
- return items
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'shahid.mbc.net',
+ days: 2,
+ url({ channel, date }) {
+ return `https://api2.shahid.net/proxy/v2.1/shahid-epg-api/?csvChannelIds=${
+ channel.site_id
+ }&from=${date.format('YYYY-MM-DD')}T00:00:00.000Z&to=${date.format(
+ 'YYYY-MM-DD'
+ )}T23:59:59.999Z&country=SA&language=${channel.lang}&Accept-Language=${channel.lang}`
+ },
+ parser({ content, channel }) {
+ const programs = parseItems(content, channel).map(item => {
+ return {
+ title: item.title,
+ description: item.description,
+ session: item.seasonNumber,
+ episode: item.episodeNumber,
+ start: dayjs.tz(item.actualFrom, 'Asia/Riyadh').toISOString(),
+ stop: dayjs.tz(item.actualTo, 'Asia/Riyadh').toISOString()
+ }
+ })
+
+ return programs
+ },
+ async channels({ lang = 'en' }) {
+ const axios = require('axios')
+ const items = []
+ let page = 0
+ while (true) {
+ const result = await axios
+ .get(
+ `https://api2.shahid.net/proxy/v2.1/product/filter?filter=%7B"pageNumber":${page},"pageSize":100,"productType":"LIVESTREAM","productSubType":"LIVE_CHANNEL"%7D&country=SA&language=${lang}&Accept-Language=${lang}`
+ )
+ .then(response => response.data)
+ .catch(console.error)
+ if (result.productList) {
+ items.push(...result.productList.products)
+ if (result.productList.hasMore) {
+ page++
+ continue
+ }
+ }
+ break
+ }
+ const channels = items.map(channel => {
+ return {
+ lang,
+ site_id: channel.id,
+ name: channel.title
+ }
+ })
+
+ return channels
+ }
+}
+
+function parseItems(content, channel) {
+ const items = []
+ content = content ? JSON.parse(content) : []
+ if (content.items) {
+ content.items.forEach(schedules => {
+ if (schedules.channelId == channel.site_id) {
+ items.push(...schedules.items)
+ return true
+ }
+ })
+ }
+
+ return items
+}
diff --git a/sites/shahid.mbc.net/shahid.mbc.net.test.js b/sites/shahid.mbc.net/shahid.mbc.net.test.js
index 920fff1e..7cc03032 100644
--- a/sites/shahid.mbc.net/shahid.mbc.net.test.js
+++ b/sites/shahid.mbc.net/shahid.mbc.net.test.js
@@ -1,36 +1,40 @@
-const { url, parser } = require('./shahid.mbc.net.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-
-dayjs.extend(utc)
-
-const date = dayjs.utc('2023-11-11').startOf('d')
-const channel = { site_id: '996520', xmltv_id: 'AlAanTV.ae', lang: 'en' }
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe(
- `https://api2.shahid.net/proxy/v2.1/shahid-epg-api/?csvChannelIds=${channel.site_id}&from=${date.format('YYYY-MM-DD')}T00:00:00.000Z&to=${date.format('YYYY-MM-DD')}T23:59:59.999Z&country=SA&language=${channel.lang}&Accept-Language=${channel.lang}`
- )
-})
-
-it('can parse response', () => {
- const content =
- '{"items":[{"channelId":"996520","items":[{"actualFrom":"2023-11-11T00:00:00.000+00:00","actualTo":"2023-11-11T00:30:00.000+00:00","description":"The presenter reviews the most prominent episodes of news programs produced by the channel\'s team on a weekly basis, which include the most important global updates and developments at all levels.","duration":null,"emptySlot":false,"episodeNumber":194,"from":"2023-11-11T00:00:00.000+00:00","genres":["TV Show"],"productId":null,"productionYear":null,"productPoster":"https://imagesmbc.whatsonindia.com/dasimages/landscape/1920x1080/F968D4A39DB25793E9EED1BDAFBAD2EA8A8F9B30Z.jpg","productSubType":null,"productType":null,"replay":false,"restritectContent":null,"seasonId":null,"seasonNumber":"1","showId":null,"streamInfo":null,"title":"Menassaatona Fi Osboo\'","to":"2023-11-11T00:30:00.000+00:00"}]}]}'
- const result = parser({ content, channel, date })
-
- expect(result).toMatchObject([
- {
- start: '2023-11-10T21:00:00.000Z',
- stop: '2023-11-10T21:30:00.000Z',
- title: 'Menassaatona Fi Osboo\'',
- description:
- 'The presenter reviews the most prominent episodes of news programs produced by the channel\'s team on a weekly basis, which include the most important global updates and developments at all levels.'
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({ content: '' })
-
- expect(result).toMatchObject([])
-})
+const { url, parser } = require('./shahid.mbc.net.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+
+dayjs.extend(utc)
+
+const date = dayjs.utc('2023-11-11').startOf('d')
+const channel = { site_id: '996520', xmltv_id: 'AlAanTV.ae', lang: 'en' }
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe(
+ `https://api2.shahid.net/proxy/v2.1/shahid-epg-api/?csvChannelIds=${
+ channel.site_id
+ }&from=${date.format('YYYY-MM-DD')}T00:00:00.000Z&to=${date.format(
+ 'YYYY-MM-DD'
+ )}T23:59:59.999Z&country=SA&language=${channel.lang}&Accept-Language=${channel.lang}`
+ )
+})
+
+it('can parse response', () => {
+ const content =
+ '{"items":[{"channelId":"996520","items":[{"actualFrom":"2023-11-11T00:00:00.000+00:00","actualTo":"2023-11-11T00:30:00.000+00:00","description":"The presenter reviews the most prominent episodes of news programs produced by the channel\'s team on a weekly basis, which include the most important global updates and developments at all levels.","duration":null,"emptySlot":false,"episodeNumber":194,"from":"2023-11-11T00:00:00.000+00:00","genres":["TV Show"],"productId":null,"productionYear":null,"productPoster":"https://imagesmbc.whatsonindia.com/dasimages/landscape/1920x1080/F968D4A39DB25793E9EED1BDAFBAD2EA8A8F9B30Z.jpg","productSubType":null,"productType":null,"replay":false,"restritectContent":null,"seasonId":null,"seasonNumber":"1","showId":null,"streamInfo":null,"title":"Menassaatona Fi Osboo\'","to":"2023-11-11T00:30:00.000+00:00"}]}]}'
+ const result = parser({ content, channel, date })
+
+ expect(result).toMatchObject([
+ {
+ start: '2023-11-10T21:00:00.000Z',
+ stop: '2023-11-10T21:30:00.000Z',
+ title: "Menassaatona Fi Osboo'",
+ description:
+ "The presenter reviews the most prominent episodes of news programs produced by the channel's team on a weekly basis, which include the most important global updates and developments at all levels."
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({ content: '' })
+
+ expect(result).toMatchObject([])
+})
diff --git a/sites/singtel.com/singtel.com.config.js b/sites/singtel.com/singtel.com.config.js
index 368e4ded..07d3a33e 100644
--- a/sites/singtel.com/singtel.com.config.js
+++ b/sites/singtel.com/singtel.com.config.js
@@ -40,7 +40,7 @@ module.exports = {
const cheerio = require('cheerio')
const data = await axios
- .get(`https://www.singtel.com/personal/products-services/tv/tv-programme-guide`)
+ .get('https://www.singtel.com/personal/products-services/tv/tv-programme-guide')
.then(r => r.data)
.catch(console.log)
@@ -62,7 +62,7 @@ function parseItems(content, channel) {
try {
const data = JSON.parse(content)
return data && data[channel.site_id] ? data[channel.site_id] : []
- } catch (err) {
+ } catch {
return []
}
}
diff --git a/sites/sjonvarp.is/sjonvarp.is.config.js b/sites/sjonvarp.is/sjonvarp.is.config.js
index 0721d0c0..7fd6c33f 100644
--- a/sites/sjonvarp.is/sjonvarp.is.config.js
+++ b/sites/sjonvarp.is/sjonvarp.is.config.js
@@ -44,7 +44,7 @@ module.exports = {
const cheerio = require('cheerio')
const data = await axios
- .get(`https://sjonvarp.is/`)
+ .get('https://sjonvarp.is/')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/sky.com/sky.com.config.js b/sites/sky.com/sky.com.config.js
index 7605600d..3be68669 100644
--- a/sites/sky.com/sky.com.config.js
+++ b/sites/sky.com/sky.com.config.js
@@ -12,9 +12,7 @@ module.exports = {
site: 'sky.com',
days: 2,
url({ date, channel }) {
- return `https://awk.epgsky.com/hawk/linear/schedule/${
- date.format('YYYYMMDD')
- }/${
+ return `https://awk.epgsky.com/hawk/linear/schedule/${date.format('YYYYMMDD')}/${
channel.site_id
}`
},
@@ -27,20 +25,19 @@ module.exports = {
.filter(schedule => schedule.sid === channel.site_id)
.forEach(schedule => {
if (Array.isArray(schedule.events)) {
- schedule.events
- .forEach(event => {
- const start = dayjs.utc(event.st * 1000)
- if (start.isSame(date, 'd')) {
- programs.push({
- title: event.t,
- description: event.sy,
- season: event.seasonnumber,
- episode: event.episodenumber,
- start,
- stop: start.add(event.d, 's')
- })
- }
- })
+ schedule.events.forEach(event => {
+ const start = dayjs.utc(event.st * 1000)
+ if (start.isSame(date, 'd')) {
+ programs.push({
+ title: event.t,
+ description: event.sy,
+ season: event.seasonnumber,
+ episode: event.episodenumber,
+ start,
+ stop: start.add(event.d, 's')
+ })
+ }
+ })
}
})
}
@@ -56,10 +53,12 @@ module.exports = {
if (queue.t === 'r') {
const $ = cheerio.load(res)
const initialData = JSON.parse(decodeURIComponent($('#initialData').text()))
- initialData.state.epgData.regions
- .forEach(region => {
- queues.push({ t: 'c', url: `https://awk.epgsky.com/hawk/linear/services/${region.bouquet}/${region.subBouquet}` })
+ initialData.state.epgData.regions.forEach(region => {
+ queues.push({
+ t: 'c',
+ url: `https://awk.epgsky.com/hawk/linear/services/${region.bouquet}/${region.subBouquet}`
})
+ })
}
// process channels
if (queue.t === 'c') {
diff --git a/sites/sky.com/sky.com.test.js b/sites/sky.com/sky.com.test.js
index 660a2667..4f349ea9 100644
--- a/sites/sky.com/sky.com.test.js
+++ b/sites/sky.com/sky.com.test.js
@@ -15,9 +15,7 @@ const channel = {
}
it('can generate valid url', () => {
- expect(url({ channel, date })).toBe(
- 'https://awk.epgsky.com/hawk/linear/schedule/20241214/4086'
- )
+ expect(url({ channel, date })).toBe('https://awk.epgsky.com/hawk/linear/schedule/20241214/4086')
})
it('can parse response', () => {
diff --git a/sites/skylife.co.kr/skylife.co.kr.test.js b/sites/skylife.co.kr/skylife.co.kr.test.js
index 8ac317ee..c35e85d4 100644
--- a/sites/skylife.co.kr/skylife.co.kr.test.js
+++ b/sites/skylife.co.kr/skylife.co.kr.test.js
@@ -1,4 +1,4 @@
-const { parser, url, request } = require('./skylife.co.kr.config.js')
+const { parser, url } = require('./skylife.co.kr.config.js')
const fs = require('fs')
const path = require('path')
const dayjs = require('dayjs')
diff --git a/sites/skyperfectv.co.jp/__data__/content.html b/sites/skyperfectv.co.jp/__data__/content.html
new file mode 100644
index 00000000..aa569a31
--- /dev/null
+++ b/sites/skyperfectv.co.jp/__data__/content.html
@@ -0,0 +1 @@
+番組表(アニメシアターX(AT-X))|スカパー!
現在マイリストを更新中です。
現在マイリストに登録中です。
現在マイリストから削除中です。
08/01(木)
08/02(金)
ヴァルキリードライヴマーメイド #06
・このサイトでは、当日から1週間分はEPGと同等の番組情報が表示され、その先1ヶ月後まではガイド誌(有料)と同等の番組情報が表示されます。番組や放送予定は予告なく変更される場合がありますのでご了承ください。 ・このサイトは、ウェブブラウザーMicrosoftEdge最新版、GoogleChrome最新版、Firefox最新版、Safari最新版での動作を確認しております。上記以外のウェブブラウザーで閲覧されますと、表示の乱れや予期せぬ動作を起こす場合がございますので、予めご了承ください。
©橋本悠/集英社・リリサ製作委員会/©鍋敷/アース・スターエンターテイメント/俺は全てを【パリイ】する製作委員会/©AT-X ©天原・masha/株式会社KADOKAWA/異種族レビュアーズ製作委員会/©THEMARGINALSERVICE PROJECT/©荒巻義雄・徳間書店/©2015上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者BURST」製作委員会/©中村力斗・野澤ゆき子/集英社・君のことが大大大大大好きな製作委員会/©2018上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者DEPARTURES」製作委員会/© 小林尽/講談社・マーベラス・キングレコード・創通
ログインをしてお気に入り番組を登録しよう! Myスカパー!にログインをすると、マイリストにお気に入り番組リストを作成することができます! マイリストに番組を登録できません ##ERROR_MSG##
\ No newline at end of file
diff --git a/sites/skyperfectv.co.jp/__data__/empty.html b/sites/skyperfectv.co.jp/__data__/empty.html
new file mode 100644
index 00000000..9560ec25
--- /dev/null
+++ b/sites/skyperfectv.co.jp/__data__/empty.html
@@ -0,0 +1 @@
+番組表(アニメシアターX(AT-X))|スカパー!
現在マイリストを更新中です。
現在マイリストに登録中です。
現在マイリストから削除中です。
・このサイトでは、当日から1週間分はEPGと同等の番組情報が表示され、その先1ヶ月後まではガイド誌(有料)と同等の番組情報が表示されます。番組や放送予定は予告なく変更される場合がありますのでご了承ください。 ・このサイトは、ウェブブラウザーMicrosoftEdge最新版、GoogleChrome最新版、Firefox最新版、Safari最新版での動作を確認しております。上記以外のウェブブラウザーで閲覧されますと、表示の乱れや予期せぬ動作を起こす場合がございますので、予めご了承ください。
©橋本悠/集英社・リリサ製作委員会/©鍋敷/アース・スターエンターテイメント/俺は全てを【パリイ】する製作委員会/©AT-X ©天原・masha/株式会社KADOKAWA/異種族レビュアーズ製作委員会/©THEMARGINALSERVICE PROJECT/©荒巻義雄・徳間書店/©2015上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者BURST」製作委員会/©中村力斗・野澤ゆき子/集英社・君のことが大大大大大好きな製作委員会/©2018上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者DEPARTURES」製作委員会/© 小林尽/講談社・マーベラス・キングレコード・創通
ログインをしてお気に入り番組を登録しよう! Myスカパー!にログインをすると、マイリストにお気に入り番組リストを作成することができます! マイリストに番組を登録できません ##ERROR_MSG##
\ No newline at end of file
diff --git a/sites/skyperfectv.co.jp/skyperfectv.co.jp.config.js b/sites/skyperfectv.co.jp/skyperfectv.co.jp.config.js
index c2d4aa23..1963124d 100644
--- a/sites/skyperfectv.co.jp/skyperfectv.co.jp.config.js
+++ b/sites/skyperfectv.co.jp/skyperfectv.co.jp.config.js
@@ -12,103 +12,110 @@ dayjs.extend(customParseFormat)
dayjs.extend(duration)
const exported = {
- site: 'skyperfectv.co.jp',
- days: 1,
- lang: 'ja',
- url: function ({ date, channel }) {
- let [type, ...code] = channel.site_id.split('_')
- code = code.join('_')
- return `https://www.skyperfectv.co.jp/program/schedule/${type}/channel:${code}/date:${date.format('YYMMDD')}`
- },
- logo: function ({ channel }) {
- return `https://www.skyperfectv.co.jp/library/common/img/channel/icon/basic/m_${channel.site_id.toLowerCase()}.gif`
- },
- // Specific function that permits to gather NSFW channels (needs confirmation)
- async fetchSchedule({ date, channel }) {
- const url = exported.url({ date, channel })
- const response = await axios.get(url, {
- headers: {
- 'Cookie': 'adult_auth=true'
- }
+ site: 'skyperfectv.co.jp',
+ days: 1,
+ lang: 'ja',
+ url: function ({ date, channel }) {
+ let [type, ...code] = channel.site_id.split('_')
+ code = code.join('_')
+ return `https://www.skyperfectv.co.jp/program/schedule/${type}/channel:${code}/date:${date.format(
+ 'YYMMDD'
+ )}`
+ },
+ logo: function ({ channel }) {
+ return `https://www.skyperfectv.co.jp/library/common/img/channel/icon/basic/m_${channel.site_id.toLowerCase()}.gif`
+ },
+ // Specific function that permits to gather NSFW channels (needs confirmation)
+ async fetchSchedule({ date, channel }) {
+ const url = exported.url({ date, channel })
+ const response = await axios.get(url, {
+ headers: {
+ Cookie: 'adult_auth=true'
+ }
+ })
+ return response.data
+ },
+ parser({ content, date }) {
+ const $ = cheerio.load(content)
+ const programs = []
+
+ const sections = [
+ { id: 'js-am', addition: 0 },
+ { id: 'js-pm', addition: 0 },
+ { id: 'js-md', addition: 1 }
+ ]
+
+ sections.forEach(({ id, addition }) => {
+ $(`#${id} > td`).each((index, element) => {
+ // `td` is a column for a day
+ // the next `td` will be the next day
+ const today = date.add(index + addition, 'd').tz('Asia/Tokyo')
+
+ const parseTime = timeString => {
+ // timeString is in the format "HH:mm"
+ // replace `today` with the time from timeString
+ const [hour, minute] = timeString.split(':').map(Number)
+ return today.hour(hour).minute(minute)
+ }
+
+ const $element = $(element) // Wrap element with Cheerio
+ $element.find('.p-program__item').each((itemIndex, itemElement) => {
+ const $itemElement = $(itemElement) // Wrap itemElement with Cheerio
+ const [start, stop] = $itemElement
+ .find('.p-program__range')
+ .first()
+ .text()
+ .split('〜')
+ .map(parseTime)
+ const title = $itemElement.find('.p-program__name').first().text()
+ const image = $itemElement.find('.js-program_thumbnail').first().attr('data-lazysrc')
+ programs.push({
+ title,
+ start,
+ stop,
+ image
+ })
})
- return response.data
- },
- parser({ content, date }) {
- const $ = cheerio.load(content)
- const programs = []
+ })
+ })
- const sections = [
- { id: 'js-am', addition: 0 },
- { id: 'js-pm', addition: 0 },
- { id: 'js-md', addition: 1 }
- ]
+ return programs
+ },
+ async channels() {
+ const pageParser = (content, type) => {
+ // type: "basic" | "premium"
+ // Returns an array of channel objects
- sections.forEach(({ id, addition }) => {
- $(`#${id} > td`).each((index, element) => {
- // `td` is a column for a day
- // the next `td` will be the next day
- const today = date.add(index + addition, 'd').tz('Asia/Tokyo')
+ const $ = cheerio.load(content)
+ const channels = []
- const parseTime = (timeString) => {
- // timeString is in the format "HH:mm"
- // replace `today` with the time from timeString
- const [hour, minute] = timeString.split(':').map(Number)
- return today.hour(hour).minute(minute)
- }
+ $('.p-channel').each((index, element) => {
+ const site_id = `${type}_${$(element).find('.p-channel__id').text()}`
+ const name = $(element).find('.p-channel__name').text()
+ channels.push({ site_id, name, lang: 'ja' })
+ })
- const $element = $(element) // Wrap element with Cheerio
- $element.find('.p-program__item').each((itemIndex, itemElement) => {
- const $itemElement = $(itemElement) // Wrap itemElement with Cheerio
- const [start, stop] = $itemElement.find('.p-program__range').first().text().split('〜').map(parseTime)
- const title = $itemElement.find('.p-program__name').first().text()
- const image = $itemElement.find('.js-program_thumbnail').first().attr('data-lazysrc')
- programs.push({
- title,
- start,
- stop,
- image
- })
- })
- })
- })
-
- return programs
- },
- async channels() {
- const pageParser = (content, type) => {
- // type: "basic" | "premium"
- // Returns an array of channel objects
-
- const $ = cheerio.load(content)
- const channels = []
-
- $('.p-channel').each((index, element) => {
- const site_id = `${type}_${$(element).find('.p-channel__id').text()}`
- const name = $(element).find('.p-channel__name').text()
- channels.push({ site_id, name, lang: 'ja' })
- })
-
- return channels
- }
-
- const getChannels = async (type) => {
- const response = await axios.get(`https://www.skyperfectv.co.jp/program/schedule/${type}/`, {
- headers: {
- 'Cookie': 'adult_auth=true;'
- }
- })
- return pageParser(response.data, type)
- }
-
- const fetchAllChannels = async () => {
- const basicChannels = await getChannels('basic')
- const premiumChannels = await getChannels('premium')
- const results = [...basicChannels, ...premiumChannels]
- return results
- }
-
- return await fetchAllChannels()
+ return channels
}
+
+ const getChannels = async type => {
+ const response = await axios.get(`https://www.skyperfectv.co.jp/program/schedule/${type}/`, {
+ headers: {
+ Cookie: 'adult_auth=true;'
+ }
+ })
+ return pageParser(response.data, type)
+ }
+
+ const fetchAllChannels = async () => {
+ const basicChannels = await getChannels('basic')
+ const premiumChannels = await getChannels('premium')
+ const results = [...basicChannels, ...premiumChannels]
+ return results
+ }
+
+ return await fetchAllChannels()
+ }
}
-module.exports = exported
\ No newline at end of file
+module.exports = exported
diff --git a/sites/skyperfectv.co.jp/skyperfectv.co.jp.test.js b/sites/skyperfectv.co.jp/skyperfectv.co.jp.test.js
index eae08e3f..c70ae27c 100644
--- a/sites/skyperfectv.co.jp/skyperfectv.co.jp.test.js
+++ b/sites/skyperfectv.co.jp/skyperfectv.co.jp.test.js
@@ -1,4 +1,6 @@
const { parser, url } = require('./skyperfectv.co.jp.config.js')
+const fs = require('fs')
+const path = require('path')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
@@ -12,13 +14,13 @@ const channel = {
xmltv_id: 'WOWOWCinema.jp'
}
-const content = `
-番組表(アニメシアターX(AT-X))|スカパー!
現在マイリストを更新中です。
現在マイリストに登録中です。
現在マイリストから削除中です。
08/01(木)
08/02(金)
ヴァルキリードライヴマーメイド #06
・このサイトでは、当日から1週間分はEPGと同等の番組情報が表示され、その先1ヶ月後まではガイド誌(有料)と同等の番組情報が表示されます。番組や放送予定は予告なく変更される場合がありますのでご了承ください。 ・このサイトは、ウェブブラウザーMicrosoftEdge最新版、GoogleChrome最新版、Firefox最新版、Safari最新版での動作を確認しております。上記以外のウェブブラウザーで閲覧されますと、表示の乱れや予期せぬ動作を起こす場合がございますので、予めご了承ください。
©橋本悠/集英社・リリサ製作委員会/©鍋敷/アース・スターエンターテイメント/俺は全てを【パリイ】する製作委員会/©AT-X ©天原・masha/株式会社KADOKAWA/異種族レビュアーズ製作委員会/©THEMARGINALSERVICE PROJECT/©荒巻義雄・徳間書店/©2015上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者BURST」製作委員会/©中村力斗・野澤ゆき子/集英社・君のことが大大大大大好きな製作委員会/©2018上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者DEPARTURES」製作委員会/© 小林尽/講談社・マーベラス・キングレコード・創通
ログインをしてお気に入り番組を登録しよう! Myスカパー!にログインをすると、マイリストにお気に入り番組リストを作成することができます! マイリストに番組を登録できません ##ERROR_MSG##
-`
+const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
it('can generate valid url', () => {
const result = url({ date, channel })
- expect(result).toBe('https://www.skyperfectv.co.jp/program/schedule/basic/channel:BS193/date:240801')
+ expect(result).toBe(
+ 'https://www.skyperfectv.co.jp/program/schedule/basic/channel:BS193/date:240801'
+ )
})
it('can parse response', async () => {
@@ -33,15 +35,13 @@ it('can parse response', async () => {
start: '2024-07-31T19:00:00.000Z', // UTC time
stop: '2024-07-31T19:30:00.000Z', // UTC
title: 'ヴァルキリードライヴマーメイド #06',
- image: 'https://pm-img-ap.skyperfectv.co.jp/uploads/thumbnail/image/11301805/S_BC929697780313_be7975d4e26a4cad9b89fc6c94807e38_20240613144158569.jpg'
+ image:
+ 'https://pm-img-ap.skyperfectv.co.jp/uploads/thumbnail/image/11301805/S_BC929697780313_be7975d4e26a4cad9b89fc6c94807e38_20240613144158569.jpg'
}
])
})
-
-const empty = `
-番組表(アニメシアターX(AT-X))|スカパー!
現在マイリストを更新中です。
現在マイリストに登録中です。
現在マイリストから削除中です。
・このサイトでは、当日から1週間分はEPGと同等の番組情報が表示され、その先1ヶ月後まではガイド誌(有料)と同等の番組情報が表示されます。番組や放送予定は予告なく変更される場合がありますのでご了承ください。 ・このサイトは、ウェブブラウザーMicrosoftEdge最新版、GoogleChrome最新版、Firefox最新版、Safari最新版での動作を確認しております。上記以外のウェブブラウザーで閲覧されますと、表示の乱れや予期せぬ動作を起こす場合がございますので、予めご了承ください。
©橋本悠/集英社・リリサ製作委員会/©鍋敷/アース・スターエンターテイメント/俺は全てを【パリイ】する製作委員会/©AT-X ©天原・masha/株式会社KADOKAWA/異種族レビュアーズ製作委員会/©THEMARGINALSERVICE PROJECT/©荒巻義雄・徳間書店/©2015上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者BURST」製作委員会/©中村力斗・野澤ゆき子/集英社・君のことが大大大大大好きな製作委員会/©2018上栖綴人・Nitroplus/KADOKAWA/「新妹魔王の契約者DEPARTURES」製作委員会/© 小林尽/講談社・マーベラス・キングレコード・創通
ログインをしてお気に入り番組を登録しよう! Myスカパー!にログインをすると、マイリストにお気に入り番組リストを作成することができます! マイリストに番組を登録できません ##ERROR_MSG##
-`
+const empty = fs.readFileSync(path.resolve(__dirname, '__data__/empty.html'))
it('can handle empty guide', async () => {
const result = parser({
diff --git a/sites/snrt.ma/snrt.ma.config.js b/sites/snrt.ma/snrt.ma.config.js
index f1251b4e..06b692f7 100644
--- a/sites/snrt.ma/snrt.ma.config.js
+++ b/sites/snrt.ma/snrt.ma.config.js
@@ -1,97 +1,86 @@
-const cheerio = require('cheerio')
-const { DateTime } = require('luxon')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-const channel = [{ site_id: '1208', xmltv_id: 'AlAoula.ma', lang: 'ar' },
- { site_id: '4069', xmltv_id: 'Laayoune.ma', lang: 'ar' },
- { site_id: '4070', xmltv_id: 'Arryadia.ma', lang: 'ar' },
- { site_id: '4071', xmltv_id: 'Athaqafia.ma', lang: 'ar' },
- { site_id: '4072', xmltv_id: 'AlMaghribia.ma', lang: 'ar' },
- { site_id: '4073', xmltv_id: 'Assadissa.ma', lang: 'ar' },
- { site_id: '4075', xmltv_id: 'Tamazight.ma', lang: 'ar' }]
-
-
-module.exports = {
- site: 'snrt.ma',
- channels: 'snrt.ma.channels.xml',
- days: 2,
- url: function ({ channel }) {
- return `https://www.snrt.ma/ar/node/${channel.site_id}`
- },
- request: {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- },
- data: function ({ date }) {
- const params = new URLSearchParams()
- params.append('_method', 'POST')
- params.append('data-date', date.format('YYYYMMDD'))
- params.append('current_date', date.format('YYYYMMDD'))
-
- return params
- }
- },
- parser: function ({ content, date }) {
- const programs = []
- const items = parseItems(content)
- items.forEach(item => {
- const prev = programs[programs.length - 1]
- const $item = cheerio.load(item)
- let start = parseStart($item, date)
- if (prev) {
- if (start.isBefore(prev.start)) {
- start = start.add(1, 'd')
- date = date.add(1, 'd')
- }
- prev.stop = start
- }
- const stop = start.add(30, 'm')
- programs.push({
- title: parseTitle($item),
- description: parseDescription($item),
- category: parseCategory($item),
- start,
- stop
- })
- })
-
- return programs
- }
-}
-
-function parseStart($item, date) {
- const timeString = $item('.grille-time').text().trim()
- const [hours, minutes] = timeString.split('H').map(Number)
- const formattedTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`
-
- const dateString = `${date.format('YYYY-MM-DD')} ${formattedTime}`
-
- return dayjs.tz(dateString, 'YYYY-MM-DD HH:mm:ss', 'Africa/Casablanca')
-}
-
-
-function parseTitle($item) {
- return $item('.program-title-sm').text().trim()
-}
-
-function parseDescription($item) {
- return $item('.program-description-sm').text().trim()
-}
-
-function parseCategory($item) {
- return $item('.genre-first').text().trim()
-}
-
-function parseItems(content) {
- const $ = cheerio.load(content)
-
- return $('.grille-line').toArray()
-}
\ No newline at end of file
+const cheerio = require('cheerio')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'snrt.ma',
+ channels: 'snrt.ma.channels.xml',
+ days: 2,
+ url: function ({ channel }) {
+ return `https://www.snrt.ma/ar/node/${channel.site_id}`
+ },
+ request: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ data: function ({ date }) {
+ const params = new URLSearchParams()
+ params.append('_method', 'POST')
+ params.append('data-date', date.format('YYYYMMDD'))
+ params.append('current_date', date.format('YYYYMMDD'))
+
+ return params
+ }
+ },
+ parser: function ({ content, date }) {
+ const programs = []
+ const items = parseItems(content)
+ items.forEach(item => {
+ const prev = programs[programs.length - 1]
+ const $item = cheerio.load(item)
+ let start = parseStart($item, date)
+ if (prev) {
+ if (start.isBefore(prev.start)) {
+ start = start.add(1, 'd')
+ date = date.add(1, 'd')
+ }
+ prev.stop = start
+ }
+ const stop = start.add(30, 'm')
+ programs.push({
+ title: parseTitle($item),
+ description: parseDescription($item),
+ category: parseCategory($item),
+ start,
+ stop
+ })
+ })
+
+ return programs
+ }
+}
+
+function parseStart($item, date) {
+ const timeString = $item('.grille-time').text().trim()
+ const [hours, minutes] = timeString.split('H').map(Number)
+ const formattedTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`
+
+ const dateString = `${date.format('YYYY-MM-DD')} ${formattedTime}`
+
+ return dayjs.tz(dateString, 'YYYY-MM-DD HH:mm:ss', 'Africa/Casablanca')
+}
+
+function parseTitle($item) {
+ return $item('.program-title-sm').text().trim()
+}
+
+function parseDescription($item) {
+ return $item('.program-description-sm').text().trim()
+}
+
+function parseCategory($item) {
+ return $item('.genre-first').text().trim()
+}
+
+function parseItems(content) {
+ const $ = cheerio.load(content)
+
+ return $('.grille-line').toArray()
+}
diff --git a/sites/snrt.ma/snrt.ma.test.js b/sites/snrt.ma/snrt.ma.test.js
index b97ac1f3..97dcf197 100644
--- a/sites/snrt.ma/snrt.ma.test.js
+++ b/sites/snrt.ma/snrt.ma.test.js
@@ -1,6 +1,4 @@
const { parser, url } = require('./snrt.ma.config.js')
-const cheerio = require('cheerio')
-const { DateTime } = require('luxon')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
@@ -25,16 +23,14 @@ it('can parse response', () => {
})
expect(results[0]).toMatchObject({
- "category": "القرآن الكريم",
- "description": "",
- "start": "2024-12-19T06:00:00.000Z",
- "stop": "2024-12-19T06:10:00.000Z",
- "stop": "2024-12-19T06:30:00.000Z",
- "title": "ﺍﻟﺴﻼﻡ ﺍﻟﻮﻃﻨﻲ + ﺍﻟﻘﺮﺁﻥ ﺍﻟﻜﺮﻳﻢ"
+ category: 'القرآن الكريم',
+ description: '',
+ start: '2024-12-19T06:00:00.000Z',
+ stop: '2024-12-19T06:30:00.000Z',
+ title: 'ﺍﻟﺴﻼﻡ ﺍﻟﻮﻃﻨﻲ + ﺍﻟﻘﺮﺁﻥ ﺍﻟﻜﺮﻳﻢ'
})
})
-
it('can handle empty guide', () => {
const result = parser({
date,
@@ -42,4 +38,4 @@ it('can handle empty guide', () => {
content: ''
})
expect(result).toMatchObject([])
-})
\ No newline at end of file
+})
diff --git a/sites/starhubtvplus.com/starhubtvplus.com.config.js b/sites/starhubtvplus.com/starhubtvplus.com.config.js
index c93af434..c9710bae 100644
--- a/sites/starhubtvplus.com/starhubtvplus.com.config.js
+++ b/sites/starhubtvplus.com/starhubtvplus.com.config.js
@@ -9,15 +9,9 @@ module.exports = {
url({ date, channel }) {
return `https://waf-starhub-metadata-api-p001.ifs.vubiquity.com/v3.1/epg/schedules?locale=${
languages[channel.lang]
- }&locale_default=${
- languages[channel.lang]
- }&device=1&in_channel_id=${
+ }&locale_default=${languages[channel.lang]}&device=1&in_channel_id=${
channel.site_id
- }>_end=${
- date.unix()
- }<_start=${
- date.add(1, 'd').unix()
- }&limit=100&page=1`
+ }>_end=${date.unix()}<_start=${date.add(1, 'd').unix()}&limit=100&page=1`
},
async parser({ content, date, channel }) {
const programs = []
@@ -29,7 +23,11 @@ module.exports = {
}
if (res.page && res.page.current < res.page.total) {
res = await axios
- .get(module.exports.url({ date, channel }).replace(/page=(\d+)/, `page=${res.page.current + 1}`))
+ .get(
+ module.exports
+ .url({ date, channel })
+ .replace(/page=(\d+)/, `page=${res.page.current + 1}`)
+ )
.then(r => r.data)
.catch(console.error)
} else {
@@ -39,7 +37,7 @@ module.exports = {
}
const season = s => {
if (s) {
- const [ , , n ] = s.match(/(S|Season )(\d+)/) || [null, null, null]
+ const [, , n] = s.match(/(S|Season )(\d+)/) || [null, null, null]
if (n) {
return parseInt(n)
}
@@ -66,11 +64,9 @@ module.exports = {
let page = 1
while (true) {
const items = await axios
- .get(`https://waf-starhub-metadata-api-p001.ifs.vubiquity.com/v3.1/epg/channels?locale=${
- languages[lang]
- }&locale_default=${
- languages[lang]
- }&device=1&limit=50&page=${page}`)
+ .get(
+ `https://waf-starhub-metadata-api-p001.ifs.vubiquity.com/v3.1/epg/channels?locale=${languages[lang]}&locale_default=${languages[lang]}&device=1&limit=50&page=${page}`
+ )
.then(r => r.data)
.catch(console.error)
if (items.resources) {
diff --git a/sites/starhubtvplus.com/starhubtvplus.com.test.js b/sites/starhubtvplus.com/starhubtvplus.com.test.js
index 71561072..78d97c5b 100644
--- a/sites/starhubtvplus.com/starhubtvplus.com.test.js
+++ b/sites/starhubtvplus.com/starhubtvplus.com.test.js
@@ -1,4 +1,4 @@
-const { parser, url, request } = require('./starhubtvplus.com.config.js')
+const { parser, url } = require('./starhubtvplus.com.config.js')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
@@ -36,9 +36,12 @@ it('can parse response', async () => {
title: 'Northern Rexposure',
subTitle: 'Hudson & Rex (Season 5)',
description:
- 'When Jesse\'s sister contacts him for help, he, Sarah and Rex head to Northern Ontario and find themselves in the middle of a deadly situation.',
+ "When Jesse's sister contacts him for help, he, Sarah and Rex head to Northern Ontario and find themselves in the middle of a deadly situation.",
category: ['Drama'],
- image: ['https://poster.starhubgo.com/poster/ch511_hudson_rex5.jpg?w=960&h=540', 'https://poster.starhubgo.com/poster/ch511_hudson_rex5.jpg?w=341&h=192'],
+ image: [
+ 'https://poster.starhubgo.com/poster/ch511_hudson_rex5.jpg?w=960&h=540',
+ 'https://poster.starhubgo.com/poster/ch511_hudson_rex5.jpg?w=341&h=192'
+ ],
season: 5,
episode: 15,
rating: 'PG13'
diff --git a/sites/startimestv.com/startimestv.com.config.js b/sites/startimestv.com/startimestv.com.config.js
index 83b6a4d4..214e28b1 100644
--- a/sites/startimestv.com/startimestv.com.config.js
+++ b/sites/startimestv.com/startimestv.com.config.js
@@ -8,9 +8,7 @@ const debug = require('debug')('site:startimestv.com')
dayjs.extend(utc)
dayjs.extend(customParseFormat)
-doFetch
- .setDebugger(debug)
- .setMaxWorker(5)
+doFetch.setDebugger(debug).setMaxWorker(5)
module.exports = {
site: 'startimestv.com',
@@ -24,7 +22,8 @@ module.exports = {
const programs = []
if (content) {
const $ = cheerio.load(content)
- $('.box .mask').toArray()
+ $('.box .mask')
+ .toArray()
.forEach(el => {
let title = parseText($(el).find('h4'))
const [s, e] = title.substr(0, title.indexOf(' ')).split('-') || [null, null]
@@ -53,7 +52,8 @@ module.exports = {
// process area-id
if (queue.t === 'a') {
const $ = cheerio.load(res)
- $('dd.update-areaID').toArray()
+ $('dd.update-areaID')
+ .toArray()
.forEach(el => {
const dd = $(el)
const areaId = dd.attr('area-id')
@@ -72,7 +72,8 @@ module.exports = {
if (queue.t === 's') {
if (res) {
const $ = cheerio.load(res)
- $(`.channl .c`).toArray()
+ $('.channl .c')
+ .toArray()
.forEach(el => {
// only process channel with schedule only
const clazz = $(el).attr('class')
@@ -98,13 +99,10 @@ module.exports = {
}
function parseText($item) {
- let text = $item.text()
- .replace(/\t/g, '')
- .replace(/\n/g, ' ')
- .trim()
+ let text = $item.text().replace(/\t/g, '').replace(/\n/g, ' ').trim()
while (true) {
- if (text.match(/ /)) {
- text = text.replace(/ /g, ' ')
+ if (text.match(/\s\s/)) {
+ text = text.replace(/\s\s/g, ' ')
continue
}
break
diff --git a/sites/stod2.is/stod2.is.config.js b/sites/stod2.is/stod2.is.config.js
index 6ae2d1d4..fc91355d 100644
--- a/sites/stod2.is/stod2.is.config.js
+++ b/sites/stod2.is/stod2.is.config.js
@@ -1,68 +1,67 @@
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const axios = require('axios')
-
-dayjs.extend(utc)
-
-module.exports = {
- site: 'stod2.is',
- channels: 'stod2.is.channels.xml',
- days: 7,
- request: {
- cache: {
- ttl: 60 * 60 * 1000 // 1 hour
- }
- },
- url({ channel, date }) {
- return `https://api.stod2.is/dagskra/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
- },
- parser: function ({ content }) {
- let data
- try {
- data = JSON.parse(content)
- } catch (error) {
- console.error('Error parsing JSON:', error)
- return []
- }
-
- const programs = []
-
- if (data && Array.isArray(data)) {
- data.forEach(item => {
- if (!item) return
- const start = dayjs.utc(item.upphaf)
- const stop = start.add(item.slott, 'm')
-
- programs.push({
- title: item.isltitill,
- sub_title: item.undirtitill,
- description: item.lysing,
- actors: item.adalhlutverk,
- directors: item.leikstjori,
- start,
- stop
- })
- })
- }
-
- return programs
- },
- async channels() {
- try {
- const response = await axios.get('https://api.stod2.is/dagskra/api')
- if (!response.data || !Array.isArray(response.data)) {
- console.error('Error: No channels data found')
- return []
- }
- return response.data.map(item => {
- return {
- lang: 'is',
- site_id: item
- }
- })
- } catch (error) {
- console.error('Error fetching channels:', error)
- return []
- }
- }
-}
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const axios = require('axios')
+
+dayjs.extend(utc)
+
+module.exports = {
+ site: 'stod2.is',
+ days: 7,
+ request: {
+ cache: {
+ ttl: 60 * 60 * 1000 // 1 hour
+ }
+ },
+ url({ channel, date }) {
+ return `https://api.stod2.is/dagskra/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
+ },
+ parser: function ({ content }) {
+ let data
+ try {
+ data = JSON.parse(content)
+ } catch (error) {
+ console.error('Error parsing JSON:', error)
+ return []
+ }
+
+ const programs = []
+
+ if (data && Array.isArray(data)) {
+ data.forEach(item => {
+ if (!item) return
+ const start = dayjs.utc(item.upphaf)
+ const stop = start.add(item.slott, 'm')
+
+ programs.push({
+ title: item.isltitill,
+ sub_title: item.undirtitill,
+ description: item.lysing,
+ actors: item.adalhlutverk,
+ directors: item.leikstjori,
+ start,
+ stop
+ })
+ })
+ }
+
+ return programs
+ },
+ async channels() {
+ try {
+ const response = await axios.get('https://api.stod2.is/dagskra/api')
+ if (!response.data || !Array.isArray(response.data)) {
+ console.error('Error: No channels data found')
+ return []
+ }
+ return response.data.map(item => {
+ return {
+ lang: 'is',
+ site_id: item
+ }
+ })
+ } catch (error) {
+ console.error('Error fetching channels:', error)
+ return []
+ }
+ }
+}
diff --git a/sites/stod2.is/stod2.is.test.js b/sites/stod2.is/stod2.is.test.js
index 2a9efee5..4dba9150 100644
--- a/sites/stod2.is/stod2.is.test.js
+++ b/sites/stod2.is/stod2.is.test.js
@@ -1,83 +1,80 @@
-const { parser, url } = require('./stod2.is.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const timezone = require('dayjs/plugin/timezone')
-const axios = require('axios')
-
-dayjs.extend(utc)
-dayjs.extend(customParseFormat)
-dayjs.extend(timezone)
-
-jest.mock('axios')
-
-const date = dayjs.utc('2025-01-03', 'YYYY-MM-DD').startOf('day')
-const channel = { site_id: 'stod2', xmltv_id: 'Stod2.is' }
-
-const mockEpgData = JSON.stringify([
- {
- midill: 'STOD2',
- midill_heiti: 'Stöð 2',
- dagsetning: '2025-01-03T00:00:00Z',
- upphaf: '2025-01-03T08:00:00Z',
- titill: 'Telma Borgþórsdóttir',
- isltitill: 'Heimsókn',
- undirtitill: 'Telma Borgþórsdóttir',
- seria: 8,
- thattur: 5,
- thattafjoldi: 10,
- birta_thatt: 1,
- opin: 0,
- beint: 0,
- frumsyning: 0,
- framundan_i_beinni: 0,
- tegund: 'SER',
- flokkur: 'Icelandic',
- adalhlutverk: '',
- leikstjori: '',
- ar: '2019',
- bannad: 'Green',
- recidefni: 592645105,
- recidlidur: 592645184,
- recidsyning: null,
- refno: null,
- frelsi: 0,
- netdagar: 0,
- lysing:
- 'Frábærir þættir með Sindra Sindrasyni sem lítur inn hjá íslenskum fagurkerum. Heimilin eru jafn ólík og þau eru mörg en eiga það þó eitt sameiginlegt að vera sett saman af alúð og smekklegheitum. Sindri hefur líka einstakt lag á að ná fram því besta í viðmælendum sínum.',
- slott: 15,
- slotlengd: '00:15'
- }
-])
-
-it('can generate valid url', () => {
- const generatedUrl = url({ date, channel })
- expect(generatedUrl).toBe('https://api.stod2.is/dagskra/api/stod2/2025-01-03')
-})
-
-it('can parse response', () => {
- const content = mockEpgData
- const result = parser({ content }).map(p => {
- p.start = p.start.toISOString()
- p.stop = p.stop.toISOString()
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: 'Heimsókn',
- sub_title: 'Telma Borgþórsdóttir',
- description:
- 'Frábærir þættir með Sindra Sindrasyni sem lítur inn hjá íslenskum fagurkerum. Heimilin eru jafn ólík og þau eru mörg en eiga það þó eitt sameiginlegt að vera sett saman af alúð og smekklegheitum. Sindri hefur líka einstakt lag á að ná fram því besta í viðmælendum sínum.',
- actors: '',
- directors: '',
- start: '2025-01-03T08:00:00.000Z',
- stop: '2025-01-03T08:15:00.000Z'
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({ content: '[]' })
- expect(result).toMatchObject([])
-})
+const { parser, url } = require('./stod2.is.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+const timezone = require('dayjs/plugin/timezone')
+
+dayjs.extend(utc)
+dayjs.extend(customParseFormat)
+dayjs.extend(timezone)
+
+const date = dayjs.utc('2025-01-03', 'YYYY-MM-DD').startOf('day')
+const channel = { site_id: 'stod2', xmltv_id: 'Stod2.is' }
+
+const mockEpgData = JSON.stringify([
+ {
+ midill: 'STOD2',
+ midill_heiti: 'Stöð 2',
+ dagsetning: '2025-01-03T00:00:00Z',
+ upphaf: '2025-01-03T08:00:00Z',
+ titill: 'Telma Borgþórsdóttir',
+ isltitill: 'Heimsókn',
+ undirtitill: 'Telma Borgþórsdóttir',
+ seria: 8,
+ thattur: 5,
+ thattafjoldi: 10,
+ birta_thatt: 1,
+ opin: 0,
+ beint: 0,
+ frumsyning: 0,
+ framundan_i_beinni: 0,
+ tegund: 'SER',
+ flokkur: 'Icelandic',
+ adalhlutverk: '',
+ leikstjori: '',
+ ar: '2019',
+ bannad: 'Green',
+ recidefni: 592645105,
+ recidlidur: 592645184,
+ recidsyning: null,
+ refno: null,
+ frelsi: 0,
+ netdagar: 0,
+ lysing:
+ 'Frábærir þættir með Sindra Sindrasyni sem lítur inn hjá íslenskum fagurkerum. Heimilin eru jafn ólík og þau eru mörg en eiga það þó eitt sameiginlegt að vera sett saman af alúð og smekklegheitum. Sindri hefur líka einstakt lag á að ná fram því besta í viðmælendum sínum.',
+ slott: 15,
+ slotlengd: '00:15'
+ }
+])
+
+it('can generate valid url', () => {
+ const generatedUrl = url({ date, channel })
+ expect(generatedUrl).toBe('https://api.stod2.is/dagskra/api/stod2/2025-01-03')
+})
+
+it('can parse response', () => {
+ const content = mockEpgData
+ const result = parser({ content }).map(p => {
+ p.start = p.start.toISOString()
+ p.stop = p.stop.toISOString()
+ return p
+ })
+
+ expect(result).toMatchObject([
+ {
+ title: 'Heimsókn',
+ sub_title: 'Telma Borgþórsdóttir',
+ description:
+ 'Frábærir þættir með Sindra Sindrasyni sem lítur inn hjá íslenskum fagurkerum. Heimilin eru jafn ólík og þau eru mörg en eiga það þó eitt sameiginlegt að vera sett saman af alúð og smekklegheitum. Sindri hefur líka einstakt lag á að ná fram því besta í viðmælendum sínum.',
+ actors: '',
+ directors: '',
+ start: '2025-01-03T08:00:00.000Z',
+ stop: '2025-01-03T08:15:00.000Z'
+ }
+ ])
+})
+
+it('can handle empty guide', () => {
+ const result = parser({ content: '[]' })
+ expect(result).toMatchObject([])
+})
diff --git a/sites/streamingtvguides.com/streamingtvguides.com.config.js b/sites/streamingtvguides.com/streamingtvguides.com.config.js
index 0807c0d6..440ca9e1 100644
--- a/sites/streamingtvguides.com/streamingtvguides.com.config.js
+++ b/sites/streamingtvguides.com/streamingtvguides.com.config.js
@@ -33,10 +33,10 @@ module.exports = {
return programs
},
- async channels({ country, lang }) {
+ async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://streamingtvguides.com/Preferences`)
+ .get('https://streamingtvguides.com/Preferences')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/telenet.tv/telenet.tv.config.js b/sites/telenet.tv/telenet.tv.config.js
index fa392183..7f286001 100644
--- a/sites/telenet.tv/telenet.tv.config.js
+++ b/sites/telenet.tv/telenet.tv.config.js
@@ -3,7 +3,7 @@ const dayjs = require('dayjs')
const API_STATIC_ENDPOINT = 'https://static.spark.telenet.tv/eng/web/epg-service-lite/be'
const API_PROD_ENDPOINT = 'https://spark-prod-be.gnp.cloud.telenet.tv/eng/web/linear-service/v2'
-const API_IMAGE_ENDPOINT = 'https://staticqbr-prod-be.gnp.cloud.telenet.tv/image-service';
+const API_IMAGE_ENDPOINT = 'https://staticqbr-prod-be.gnp.cloud.telenet.tv/image-service'
module.exports = {
site: 'telenet.tv',
@@ -94,7 +94,7 @@ module.exports = {
async function loadProgramDetails(item, channel) {
if (!item.id) return {}
- const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true&language=${channel.lang}`
+ const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true&language=${channel.lang}`
const data = await axios
.get(url)
.then(r => r.data)
@@ -134,5 +134,5 @@ function parseEpisode(detail) {
}
function parseIcon(item) {
- return `${API_IMAGE_ENDPOINT}/intent/${item.id}/posterTile`;
-}
\ No newline at end of file
+ return `${API_IMAGE_ENDPOINT}/intent/${item.id}/posterTile`
+}
diff --git a/sites/telkussa.fi/telkussa.fi.config.js b/sites/telkussa.fi/telkussa.fi.config.js
index d1b54f08..d9eeb6c2 100644
--- a/sites/telkussa.fi/telkussa.fi.config.js
+++ b/sites/telkussa.fi/telkussa.fi.config.js
@@ -27,10 +27,10 @@ module.exports = {
return programs
},
- async channels({ lang }) {
+ async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://telkussa.fi/API/Channels`)
+ .get('https://telkussa.fi/API/Channels')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/tivie.id/tivie.id.config.js b/sites/tivie.id/tivie.id.config.js
index cb6be07c..080a74e7 100644
--- a/sites/tivie.id/tivie.id.config.js
+++ b/sites/tivie.id/tivie.id.config.js
@@ -1,132 +1,134 @@
-const axios = require('axios')
-const cheerio = require('cheerio')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const timezone = require('dayjs/plugin/timezone')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-const doFetch = require('@ntlab/sfetch')
-const debug = require('debug')('site:tivie.id')
-
-dayjs.extend(utc)
-dayjs.extend(timezone)
-dayjs.extend(customParseFormat)
-
-doFetch
- .setDebugger(debug)
-
-const tz = 'Asia/Jakarta'
-
-module.exports = {
- site: 'tivie.id',
- days: 2,
- url({ channel, date }) {
- return `https://tivie.id/channel/${
- channel.site_id
- }/${
- date.format('YYYYMMDD')
- }`
- },
- async parser({ content, date }) {
- const programs = []
- if (content) {
- const $ = cheerio.load(content)
- const items = $('ul[x-data] > li[id*="event-"] > div.w-full').toArray()
- .map(item => {
- const $item = $(item)
- const time = $item.find('div:nth-child(1) span:nth-child(1)')
- const info = $item.find('div:nth-child(2) h5')
- const detail = info.find('a')
- const p = {
- start: dayjs.tz(`${date.format('YYYY-MM-DD')} ${time.html()}`, 'YYYY-MM-DD HH:mm', tz)
- }
- if (detail.length) {
- const subtitle = detail.find('div')
- p.title = parseText(subtitle.length ? subtitle : detail)
- p.url = detail.attr('href')
- } else {
- p.title = parseText(info)
- }
- if (p.title) {
- const [, , season, episode] = p.title.match(/( S(\d+))?, Ep\. (\d+)/) || [null, null, null, null]
- if (season) {
- p.season = parseInt(season)
- }
- if (episode) {
- p.episode = parseInt(episode)
- }
- }
- return p
- })
- // fetch detailed guide if necessary
- const queues = items
- .filter(i => i.url)
- .map(i => {
- const url = i.url
- delete i.url
- return {i, url}
- })
- if (queues.length) {
- await doFetch(queues, (queue, res) => {
- const $ = cheerio.load(res)
- const img = $('#main-content > div > div:nth-child(1) img')
- const info = $('#main-content > div > div:nth-child(2)')
- const title = parseText(info.find('h2:nth-child(2)'))
- if (!queue.i.title.startsWith(title)) {
- queue.i.subTitle = parseText(info.find('h2:nth-child(2)'))
- }
- queue.i.description = parseText(info.find('div[class=""]:nth-child(4)'))
- queue.i.date = parseText(info.find('h2:nth-child(3)'))
- queue.i.image = img.length ? img.attr('src') : null
- })
- }
- // fill start-stop
- for (let i = 0; i < items.length; i++) {
- if (i < items.length - 1) {
- items[i].stop = items[i + 1].start
- } else {
- items[i].stop = dayjs.tz(`${date.add(1, 'd').format('YYYY-MM-DD')} 00:00`, 'YYYY-MM-DD HH:mm', tz)
- }
- }
- // add programs
- programs.push(...items)
- }
-
- return programs
- },
- async channels({ lang = 'id' }) {
- const result = await axios
- .get('https://tivie.id/channel')
- .then(response => response.data)
- .catch(console.error)
-
- const $ = cheerio.load(result)
- const items = $('ul[x-data] li[x-data] div header h2 a').toArray()
- const channels = items.map(item => {
- const $item = $(item)
- const url = $item.attr('href')
- return {
- lang,
- site_id: url.substr(url.lastIndexOf('/') + 1),
- name: $item.find('strong').text()
- }
- })
-
- return channels
- }
-}
-
-function parseText($item) {
- let text = $item.text()
- .replace(/\t/g, '')
- .replace(/\n/g, ' ')
- .trim()
- while (true) {
- if (text.match(/ /)) {
- text = text.replace(/ /g, ' ')
- continue
- }
- break
- }
-
- return text
-}
+const axios = require('axios')
+const cheerio = require('cheerio')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+const doFetch = require('@ntlab/sfetch')
+const debug = require('debug')('site:tivie.id')
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+doFetch.setDebugger(debug)
+
+const tz = 'Asia/Jakarta'
+
+module.exports = {
+ site: 'tivie.id',
+ days: 2,
+ url({ channel, date }) {
+ return `https://tivie.id/channel/${channel.site_id}/${date.format('YYYYMMDD')}`
+ },
+ async parser({ content, date }) {
+ const programs = []
+ if (content) {
+ const $ = cheerio.load(content)
+ const items = $('ul[x-data] > li[id*="event-"] > div.w-full')
+ .toArray()
+ .map(item => {
+ const $item = $(item)
+ const time = $item.find('div:nth-child(1) span:nth-child(1)')
+ const info = $item.find('div:nth-child(2) h5')
+ const detail = info.find('a')
+ const p = {
+ start: dayjs.tz(`${date.format('YYYY-MM-DD')} ${time.html()}`, 'YYYY-MM-DD HH:mm', tz)
+ }
+ if (detail.length) {
+ const subtitle = detail.find('div')
+ p.title = parseText(subtitle.length ? subtitle : detail)
+ p.url = detail.attr('href')
+ } else {
+ p.title = parseText(info)
+ }
+ if (p.title) {
+ const [, , season, episode] = p.title.match(/( S(\d+))?, Ep\. (\d+)/) || [
+ null,
+ null,
+ null,
+ null
+ ]
+ if (season) {
+ p.season = parseInt(season)
+ }
+ if (episode) {
+ p.episode = parseInt(episode)
+ }
+ }
+ return p
+ })
+ // fetch detailed guide if necessary
+ const queues = items
+ .filter(i => i.url)
+ .map(i => {
+ const url = i.url
+ delete i.url
+ return { i, url }
+ })
+ if (queues.length) {
+ await doFetch(queues, (queue, res) => {
+ const $ = cheerio.load(res)
+ const img = $('#main-content > div > div:nth-child(1) img')
+ const info = $('#main-content > div > div:nth-child(2)')
+ const title = parseText(info.find('h2:nth-child(2)'))
+ if (!queue.i.title.startsWith(title)) {
+ queue.i.subTitle = parseText(info.find('h2:nth-child(2)'))
+ }
+ queue.i.description = parseText(info.find('div[class=""]:nth-child(4)'))
+ queue.i.date = parseText(info.find('h2:nth-child(3)'))
+ queue.i.image = img.length ? img.attr('src') : null
+ })
+ }
+ // fill start-stop
+ for (let i = 0; i < items.length; i++) {
+ if (i < items.length - 1) {
+ items[i].stop = items[i + 1].start
+ } else {
+ items[i].stop = dayjs.tz(
+ `${date.add(1, 'd').format('YYYY-MM-DD')} 00:00`,
+ 'YYYY-MM-DD HH:mm',
+ tz
+ )
+ }
+ }
+ // add programs
+ programs.push(...items)
+ }
+
+ return programs
+ },
+ async channels({ lang = 'id' }) {
+ const result = await axios
+ .get('https://tivie.id/channel')
+ .then(response => response.data)
+ .catch(console.error)
+
+ const $ = cheerio.load(result)
+ const items = $('ul[x-data] li[x-data] div header h2 a').toArray()
+ const channels = items.map(item => {
+ const $item = $(item)
+ const url = $item.attr('href')
+ return {
+ lang,
+ site_id: url.substr(url.lastIndexOf('/') + 1),
+ name: $item.find('strong').text()
+ }
+ })
+
+ return channels
+ }
+}
+
+function parseText($item) {
+ let text = $item.text().replace(/\t/g, '').replace(/\n/g, ' ').trim()
+ while (true) {
+ if (text.match(/\s\s/)) {
+ text = text.replace(/\s\s/g, ' ')
+ continue
+ }
+ break
+ }
+
+ return text
+}
diff --git a/sites/tivie.id/tivie.id.test.js b/sites/tivie.id/tivie.id.test.js
index e03247d2..dcc4e0ee 100644
--- a/sites/tivie.id/tivie.id.test.js
+++ b/sites/tivie.id/tivie.id.test.js
@@ -1,77 +1,75 @@
-const { parser, url } = require('./tivie.id.config')
-const fs = require('fs')
-const path = require('path')
-const axios = require('axios')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-jest.mock('axios')
-
-const date = dayjs.utc('2024-12-31').startOf('d')
-const channel = {
- site_id: 'axn',
- xmltv_id: 'AXN.id',
- lang: 'id'
-}
-
-axios.get.mockImplementation(url => {
- const urls = {
- 'https://tivie.id/film/white-house-down-nwzDnwz9nAv6':
- 'program01.html',
- 'https://tivie.id/program/hudson-rex-s6-e14-nwzDnwvBmQr9':
- 'program02.html',
- }
- let data = ''
- if (urls[url] !== undefined) {
- data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString()
- }
- return Promise.resolve({ data })
-})
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe('https://tivie.id/channel/axn/20241231')
-})
-
-it('can parse response', async () => {
- const content = fs.readFileSync(path.join(__dirname, '__data__', 'content.html'))
- const results = (
- await parser({ date, content, channel })
- ).map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(results.length).toBe(27)
- expect(results[0]).toMatchObject({
- start: '2024-12-30T17:00:00.000Z',
- stop: '2024-12-30T17:05:00.000Z',
- title: 'White House Down',
- description:
- 'Saat melakukan tur di Gedung Putih bersama putrinya yang masih kecil, seorang perwira polisi beraksi untuk melindungi anaknya dan presiden dari sekelompok penjajah paramiliter bersenjata lengkap.',
- image: 'https://i0.wp.com/is3.cloudhost.id/tivie/poster/2023/09/65116c78791c2-1695640694.jpg?resize=480,270',
- })
- expect(results[2]).toMatchObject({
- start: '2024-12-30T18:00:00.000Z',
- stop: '2024-12-30T18:55:00.000Z',
- title: 'Hudson & Rex S6, Ep. 14',
- description:
- 'Saat guru musik Jesse terbunuh di studio rekamannya, Charlie dan Rex menghubungkan kejahatan tersebut dengan pembunuhan yang tampaknya tak ada hubungannya.',
- image: 'https://i0.wp.com/is3.cloudhost.id/tivie/poster/2024/07/668b7ced47b25-1720417517.jpg?resize=480,270',
- season: 6,
- episode: 14,
- })
-})
-
-it('can handle empty guide', async () => {
- const results = await parser({
- date,
- channel,
- content: '',
- })
- expect(results).toMatchObject([])
-})
+const { parser, url } = require('./tivie.id.config')
+const fs = require('fs')
+const path = require('path')
+const axios = require('axios')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+jest.mock('axios')
+
+const date = dayjs.utc('2024-12-31').startOf('d')
+const channel = {
+ site_id: 'axn',
+ xmltv_id: 'AXN.id',
+ lang: 'id'
+}
+
+axios.get.mockImplementation(url => {
+ const urls = {
+ 'https://tivie.id/film/white-house-down-nwzDnwz9nAv6': 'program01.html',
+ 'https://tivie.id/program/hudson-rex-s6-e14-nwzDnwvBmQr9': 'program02.html'
+ }
+ let data = ''
+ if (urls[url] !== undefined) {
+ data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString()
+ }
+ return Promise.resolve({ data })
+})
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe('https://tivie.id/channel/axn/20241231')
+})
+
+it('can parse response', async () => {
+ const content = fs.readFileSync(path.join(__dirname, '__data__', 'content.html'))
+ const results = (await parser({ date, content, channel })).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
+
+ expect(results.length).toBe(27)
+ expect(results[0]).toMatchObject({
+ start: '2024-12-30T17:00:00.000Z',
+ stop: '2024-12-30T17:05:00.000Z',
+ title: 'White House Down',
+ description:
+ 'Saat melakukan tur di Gedung Putih bersama putrinya yang masih kecil, seorang perwira polisi beraksi untuk melindungi anaknya dan presiden dari sekelompok penjajah paramiliter bersenjata lengkap.',
+ image:
+ 'https://i0.wp.com/is3.cloudhost.id/tivie/poster/2023/09/65116c78791c2-1695640694.jpg?resize=480,270'
+ })
+ expect(results[2]).toMatchObject({
+ start: '2024-12-30T18:00:00.000Z',
+ stop: '2024-12-30T18:55:00.000Z',
+ title: 'Hudson & Rex S6, Ep. 14',
+ description:
+ 'Saat guru musik Jesse terbunuh di studio rekamannya, Charlie dan Rex menghubungkan kejahatan tersebut dengan pembunuhan yang tampaknya tak ada hubungannya.',
+ image:
+ 'https://i0.wp.com/is3.cloudhost.id/tivie/poster/2024/07/668b7ced47b25-1720417517.jpg?resize=480,270',
+ season: 6,
+ episode: 14
+ })
+})
+
+it('can handle empty guide', async () => {
+ const results = await parser({
+ date,
+ channel,
+ content: ''
+ })
+ expect(results).toMatchObject([])
+})
diff --git a/sites/turksatkablo.com.tr/turksatkablo.com.tr.config.js b/sites/turksatkablo.com.tr/turksatkablo.com.tr.config.js
index 64140b30..933b6513 100644
--- a/sites/turksatkablo.com.tr/turksatkablo.com.tr.config.js
+++ b/sites/turksatkablo.com.tr/turksatkablo.com.tr.config.js
@@ -73,7 +73,7 @@ function parseItems(content, channel) {
let parsed
try {
parsed = JSON.parse(content)
- } catch (error) {
+ } catch {
return []
}
if (!parsed || !parsed.k) return []
diff --git a/sites/tv.mail.ru/tv.mail.ru.config.js b/sites/tv.mail.ru/tv.mail.ru.config.js
index 25691c14..92c19623 100644
--- a/sites/tv.mail.ru/tv.mail.ru.config.js
+++ b/sites/tv.mail.ru/tv.mail.ru.config.js
@@ -70,7 +70,7 @@ module.exports = {
async function getTotalPageCount(region) {
const data = await axios
- .get(`https://tv.mail.ru/ajax/channel/list/`, {
+ .get('https://tv.mail.ru/ajax/channel/list/', {
params: { page: 0 },
headers: {
cookie: `s=fver=0|geo=${region};`
diff --git a/sites/tv.nu/tv.nu.config.js b/sites/tv.nu/tv.nu.config.js
index 9afa14ea..5dd28959 100644
--- a/sites/tv.nu/tv.nu.config.js
+++ b/sites/tv.nu/tv.nu.config.js
@@ -40,7 +40,7 @@ module.exports = {
let offset = 0
while (offset !== undefined) {
const data = await axios
- .get(`https://web-api.tv.nu/tableauLinearChannels`, {
+ .get('https://web-api.tv.nu/tableauLinearChannels', {
params: {
modules,
date: dayjs().format('YYYY-MM-DD'),
diff --git a/sites/tv.trueid.net/tv.trueid.net.config.js b/sites/tv.trueid.net/tv.trueid.net.config.js
index f0736044..2de101cf 100644
--- a/sites/tv.trueid.net/tv.trueid.net.config.js
+++ b/sites/tv.trueid.net/tv.trueid.net.config.js
@@ -24,7 +24,7 @@ module.exports = {
return programs
},
- async channels({ token, lang = en }) {
+ async channels({ token, lang = 'en' }) {
const axios = require('axios')
const ACCESS_TOKEN = token
? token
diff --git a/sites/tv.yandex.ru/tv.yandex.ru.config.js b/sites/tv.yandex.ru/tv.yandex.ru.config.js
index e12df5d0..0dd19c00 100644
--- a/sites/tv.yandex.ru/tv.yandex.ru.config.js
+++ b/sites/tv.yandex.ru/tv.yandex.ru.config.js
@@ -2,9 +2,7 @@ const dayjs = require('dayjs')
const doFetch = require('@ntlab/sfetch')
const debug = require('debug')('site:tv.yandex.ru')
-doFetch
- .setDebugger(debug)
- .setMaxWorker(10)
+doFetch.setDebugger(debug).setMaxWorker(10)
// enable to fetch guide description but its take a longer time
const detailedGuide = true
@@ -12,14 +10,16 @@ const detailedGuide = true
// update this data by heading to https://tv.yandex.ru and change the values accordingly
const cookies = {
i: 'eIUfSP+/mzQWXcH+Cuz8o1vY+D2K8fhBd6Sj0xvbPZeO4l3cY+BvMp8fFIuM17l6UE1Z5+R2a18lP00ex9iYVJ+VT+c=',
- spravka: 'dD0xNzM0MjA0NjM4O2k9MTI1LjE2NC4xNDkuMjAwO0Q9QTVCQ0IyOTI5RDQxNkU5NkEyOTcwMTNDMzZGMDAzNjRDNTFFNDM4QkE2Q0IyOTJDRjhCOTZDRDIzODdBQzk2MzRFRDc5QTk2Qjc2OEI1MUY5MTM5M0QzNkY3OEQ2OUY3OTUwNkQ3RjBCOEJGOEJDMjAwMTQ0RDUwRkFCMDNEQzJFMDI2OEI5OTk5OUJBNEFERUYwOEQ1MjUwQTE0QTI3RDU1MEQwM0U0O3U9MTczNDIwNDYzODUyNDYyNzg1NDtoPTIxNTc0ZTc2MDQ1ZjcwMDBkYmY0NTVkM2Q2ZWMyM2Y1',
+ spravka:
+ 'dD0xNzM0MjA0NjM4O2k9MTI1LjE2NC4xNDkuMjAwO0Q9QTVCQ0IyOTI5RDQxNkU5NkEyOTcwMTNDMzZGMDAzNjRDNTFFNDM4QkE2Q0IyOTJDRjhCOTZDRDIzODdBQzk2MzRFRDc5QTk2Qjc2OEI1MUY5MTM5M0QzNkY3OEQ2OUY3OTUwNkQ3RjBCOEJGOEJDMjAwMTQ0RDUwRkFCMDNEQzJFMDI2OEI5OTk5OUJBNEFERUYwOEQ1MjUwQTE0QTI3RDU1MEQwM0U0O3U9MTczNDIwNDYzODUyNDYyNzg1NDtoPTIxNTc0ZTc2MDQ1ZjcwMDBkYmY0NTVkM2Q2ZWMyM2Y1',
yandexuid: '1197179041732383499',
yashr: '4682342911732383504',
yuidss: '1197179041732383499',
- user_display: 824,
+ user_display: 824
}
const headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0',
+ 'User-Agent':
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0'
}
const caches = {}
@@ -50,7 +50,9 @@ module.exports = {
}
caches[cacheid].forEach(schedule => {
schedule.events
- .filter(event => event.channelFamilyId == channel.site_id && date.isSame(event.start, 'day'))
+ .filter(
+ event => event.channelFamilyId == channel.site_id && date.isSame(event.start, 'day')
+ )
.forEach(event => {
if (events.indexOf(event.id) < 0) {
events.push(event.id)
@@ -171,7 +173,10 @@ function parseContent(content, date, checkOnly = false) {
content = content.toString()
}
// got captcha, its look like our cookies has expired
- if (content?.type === 'captcha' || (typeof content === 'string' && content.match(/SmartCaptcha/))) {
+ if (
+ content?.type === 'captcha' ||
+ (typeof content === 'string' && content.match(/SmartCaptcha/))
+ ) {
throw new Error('Got captcha, please goto https://tv.yandex.ru and update cookies!')
}
if (typeof content === 'object') {
@@ -210,35 +215,41 @@ function parseContent(content, date, checkOnly = false) {
headers['X-User-Session-Id'] = sessionId
}
if (checkOnly && region && tvSk.key && sessionId) {
- valid = true;
+ valid = true
}
}
}
- return checkOnly ? valid : [queues, schedules]
+ return checkOnly ? valid : [queues, schedules]
}
function parseCookies(headers) {
if (Array.isArray(headers['set-cookie'])) {
- headers['set-cookie']
- .forEach(cookie => {
- const [key, value] = cookie.split('; ')[0].split('=')
- if (cookies[key] !== value) {
- cookies[key] = value
- debug(`Update cookie ${key}=${value}`)
- }
- })
+ headers['set-cookie'].forEach(cookie => {
+ const [key, value] = cookie.split('; ')[0].split('=')
+ if (cookies[key] !== value) {
+ cookies[key] = value
+ debug(`Update cookie ${key}=${value}`)
+ }
+ })
}
}
function getSchedules(schedules) {
- return schedules.filter(schedule => schedule.events.length);
+ return schedules.filter(schedule => schedule.events.length)
}
function getHeaders(data = {}) {
- return Object.assign({}, headers, {
- Cookie: Object.keys(cookies).map(cookie => `${cookie}=${cookies[cookie]}`).join('; ')
- }, data)
+ return Object.assign(
+ {},
+ headers,
+ {
+ Cookie: Object.keys(cookies)
+ .map(cookie => `${cookie}=${cookies[cookie]}`)
+ .join('; ')
+ },
+ data
+ )
}
function getUrl(date, region = null, page = null, event = null) {
@@ -253,7 +264,9 @@ function getUrl(date, region = null, page = null, event = null) {
url += `${url.endsWith('/') ? '' : '/'}event?eventId=${event.id}&programCoId=`
}
if (date) {
- url += `${url.indexOf('?') < 0 ? '?' : '&'}date=${date.format('YYYY-MM-DD')}${!page ? '&grid=all' : ''}&period=all-day`
+ url += `${url.indexOf('?') < 0 ? '?' : '&'}date=${date.format('YYYY-MM-DD')}${
+ !page ? '&grid=all' : ''
+ }&period=all-day`
}
if (page && page.id !== undefined && page.offset !== undefined) {
url += `${url.indexOf('?') < 0 ? '?' : '&'}offset=${page.offset}`
@@ -266,7 +279,7 @@ function getUrl(date, region = null, page = null, event = null) {
function getQueue(url, referer) {
const data = {
- 'Origin': 'https://tv.yandex.ru',
+ Origin: 'https://tv.yandex.ru'
}
if (referer) {
data['Referer'] = referer
@@ -279,4 +292,4 @@ function getQueue(url, referer) {
url,
params: { headers }
}
-}
\ No newline at end of file
+}
diff --git a/sites/tv.yandex.ru/tv.yandex.ru.test.js b/sites/tv.yandex.ru/tv.yandex.ru.test.js
index ea72df5b..9661089f 100644
--- a/sites/tv.yandex.ru/tv.yandex.ru.test.js
+++ b/sites/tv.yandex.ru/tv.yandex.ru.test.js
@@ -16,7 +16,7 @@ const channel = {
site_id: '16',
xmltv_id: 'ChannelOne.ru'
}
-axios.get.mockImplementation((url, opts) => {
+axios.get.mockImplementation(url => {
if (url === 'https://tv.yandex.ru/?date=2023-11-26&grid=all&period=all-day') {
return Promise.resolve({
headers: {},
@@ -29,7 +29,10 @@ axios.get.mockImplementation((url, opts) => {
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/schedule.json')))
})
}
- if (url === 'https://tv.yandex.ru/api/120809/main/chunk?page=0&date=2023-11-26&period=all-day&offset=0&limit=11') {
+ if (
+ url ===
+ 'https://tv.yandex.ru/api/120809/main/chunk?page=0&date=2023-11-26&period=all-day&offset=0&limit=11'
+ ) {
return Promise.resolve({
headers: {},
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/schedule0.json')))
@@ -44,9 +47,7 @@ axios.get.mockImplementation((url, opts) => {
})
it('can generate valid url', () => {
- expect(url({ date })).toBe(
- 'https://tv.yandex.ru/?date=2023-11-26&grid=all&period=all-day'
- )
+ expect(url({ date })).toBe('https://tv.yandex.ru/?date=2023-11-26&grid=all&period=all-day')
})
it('can generate valid request headers', () => {
@@ -63,9 +64,7 @@ it('can generate valid request headers', () => {
it('can parse response', async () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
- const result = (
- await parser({ content, date, channel })
- ).map(p => {
+ const result = (await parser({ content, date, channel })).map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
@@ -77,7 +76,8 @@ it('can parse response', async () => {
stop: '2023-11-26T02:10:00.000Z',
title: 'ПОДКАСТ.ЛАБ. Мелодии моей жизни',
category: 'досуг',
- description: 'Впереди вся ночь и есть о чем поговорить. Фильмы, музыка, любовь, звезды, еда, мода, анекдоты, спорт, деньги, настоящее, будущее - все это в творческом эксперименте.\nЛариса Гузеева читает любовные письма. Леонид Якубович рассказывает, кого не берут в пилоты. Арина Холина - какой секс способен довести до мужа или до развода. Валерий Сюткин на ходу сочиняет песню для Карины Кросс и Вали Карнавал. Дмитрий Дибров дарит новую жизнь любимой \"Антропологии\". Денис Казанский - все о футболе, хоккее и не только.\n\"ПОДКАСТЫ. ЛАБ\" - серия подкастов разной тематики, которые невозможно проспать. Интеллектуальные дискуссии после полуночи с самыми компетентными экспертами и актуальными спикерами.'
+ description:
+ 'Впереди вся ночь и есть о чем поговорить. Фильмы, музыка, любовь, звезды, еда, мода, анекдоты, спорт, деньги, настоящее, будущее - все это в творческом эксперименте.\nЛариса Гузеева читает любовные письма. Леонид Якубович рассказывает, кого не берут в пилоты. Арина Холина - какой секс способен довести до мужа или до развода. Валерий Сюткин на ходу сочиняет песню для Карины Кросс и Вали Карнавал. Дмитрий Дибров дарит новую жизнь любимой "Антропологии". Денис Казанский - все о футболе, хоккее и не только.\n"ПОДКАСТЫ. ЛАБ" - серия подкастов разной тематики, которые невозможно проспать. Интеллектуальные дискуссии после полуночи с самыми компетентными экспертами и актуальными спикерами.'
}
])
})
diff --git a/sites/tv2go.t-2.net/tv2go.t-2.net.config.js b/sites/tv2go.t-2.net/tv2go.t-2.net.config.js
index 9b77abec..2fc449f3 100644
--- a/sites/tv2go.t-2.net/tv2go.t-2.net.config.js
+++ b/sites/tv2go.t-2.net/tv2go.t-2.net.config.js
@@ -109,7 +109,7 @@ function parseItems(content) {
let data
try {
data = JSON.parse(content)
- } catch (e) {
+ } catch {
return []
}
if (!data || !Array.isArray(data.entries)) return []
diff --git a/sites/tvarenasport.com/tvarenasport.com.config.js b/sites/tvarenasport.com/tvarenasport.com.config.js
index f30d2efa..d2297d9c 100644
--- a/sites/tvarenasport.com/tvarenasport.com.config.js
+++ b/sites/tvarenasport.com/tvarenasport.com.config.js
@@ -26,22 +26,25 @@ module.exports = {
if (content) {
const dates = []
const $ = cheerio.load(content)
- const parent = $(`.tv-scheme-chanel-header img[src*="chanel-${channel.site_id}.png"]`)
- .parents('div')
+ const parent = $(
+ `.tv-scheme-chanel-header img[src*="chanel-${channel.site_id}.png"]`
+ ).parents('div')
parent
.siblings('.tv-scheme-days')
- .find('a').toArray()
- .forEach(el => {
- const a = $(el)
- const dt = a.find('span:nth-child(3)').text()
- dates.push(dayjs(dt + date.year(), 'DD.MM.YYYY'))
- })
+ .find('a')
+ .toArray()
+ .forEach(el => {
+ const a = $(el)
+ const dt = a.find('span:nth-child(3)').text()
+ dates.push(dayjs(dt + date.year(), 'DD.MM.YYYY'))
+ })
parent
.siblings('.tv-scheme-new-slider-wrapper')
- .find('.tv-scheme-new-slider-item').toArray()
- .forEach((el, i) => {
- programs.push(...parseSchedules($(el), dates[i], module.exports.tz))
- })
+ .find('.tv-scheme-new-slider-item')
+ .toArray()
+ .forEach((el, i) => {
+ programs.push(...parseSchedules($(el), dates[i], module.exports.tz))
+ })
programs.forEach((s, i) => {
if (i < programs.length - 2) {
s.stop = programs[i + 1].start
@@ -51,8 +54,11 @@ module.exports = {
})
}
- return programs
- .filter(p => p.start.format('YYYY-MM-DD') === expectedDate || p.stop.format('YYYY-MM-DD') === expectedDate)
+ return programs.filter(
+ p =>
+ p.start.format('YYYY-MM-DD') === expectedDate ||
+ p.stop.format('YYYY-MM-DD') === expectedDate
+ )
},
async channels() {
const channels = []
@@ -81,7 +87,9 @@ module.exports = {
const $ = cheerio.load(data)
const items = $('.tv-scheme-chanel-header img').toArray()
for (const item of items) {
- const [, id] = $(item).attr('src').match(/chanel-([a-z0-9]+)\.png/) || [null, null]
+ const [, id] = $(item)
+ .attr('src')
+ .match(/chanel-([a-z0-9]+)\.png/) || [null, null]
if (id) {
channels.push({
lang: this.lang,
@@ -99,7 +107,8 @@ module.exports = {
function parseSchedules($s, date, tz) {
const schedules = []
const $ = $s._make
- $s.find('.slider-content').toArray()
+ $s.find('.slider-content')
+ .toArray()
.forEach(el => {
schedules.push(parseSchedule($(el), date, tz))
})
diff --git a/sites/tvarenasport.com/tvarenasport.com.test.js b/sites/tvarenasport.com/tvarenasport.com.test.js
index 54ff2c33..1866f963 100644
--- a/sites/tvarenasport.com/tvarenasport.com.test.js
+++ b/sites/tvarenasport.com/tvarenasport.com.test.js
@@ -32,12 +32,12 @@ it('can parse response', () => {
stop: '2024-12-07T05:00:00.000Z',
title: 'EVROPSKO PRVENSTVO Ž',
description: 'Francuska - Crna Gora',
- category: 'Rukomet',
+ category: 'Rukomet'
})
expect(result[8]).toMatchObject({
start: '2024-12-07T11:00:00.000Z',
stop: '2024-12-07T11:05:00.000Z',
- title: 'Arena News',
+ title: 'Arena News'
})
})
diff --git a/sites/tvarenasport.hr/tvarenasport.hr.test.js b/sites/tvarenasport.hr/tvarenasport.hr.test.js
index eaf115da..9358952c 100644
--- a/sites/tvarenasport.hr/tvarenasport.hr.test.js
+++ b/sites/tvarenasport.hr/tvarenasport.hr.test.js
@@ -32,14 +32,14 @@ it('can parse response', () => {
stop: '2024-12-07T00:30:00.000Z',
title: 'MAGAZIN',
description: 'NBA ACTION',
- category: 'Košarka',
+ category: 'Košarka'
})
expect(result[4]).toMatchObject({
start: '2024-12-07T06:00:00.000Z',
stop: '2024-12-07T07:30:00.000Z',
title: 'EHF LIGA PRVAKA',
description: 'DINAMO BUKUREŠT - PSG',
- category: 'Rukomet',
+ category: 'Rukomet'
})
})
diff --git a/sites/tvcesoir.fr/tvcesoir.fr.config.js b/sites/tvcesoir.fr/tvcesoir.fr.config.js
index 937f6583..306f819f 100644
--- a/sites/tvcesoir.fr/tvcesoir.fr.config.js
+++ b/sites/tvcesoir.fr/tvcesoir.fr.config.js
@@ -49,7 +49,7 @@ module.exports = {
const channels = []
for (let provider of providers) {
const data = await axios
- .post(`https://www.tvcesoir.fr/guide/schedule`, null, {
+ .post('https://www.tvcesoir.fr/guide/schedule', null, {
params: {
provider,
region: 'France',
@@ -81,7 +81,7 @@ module.exports = {
}
}
-function parseStart($item, date, channel) {
+function parseStart($item, date) {
const timeString = $item('td:eq(0)').text().trim()
const dateString = `${date.format('YYYY-MM-DD')} ${timeString}`
diff --git a/sites/tvcubana.icrt.cu/tvcubana.icrt.cu.config.js b/sites/tvcubana.icrt.cu/tvcubana.icrt.cu.config.js
index 515da300..41edebca 100644
--- a/sites/tvcubana.icrt.cu/tvcubana.icrt.cu.config.js
+++ b/sites/tvcubana.icrt.cu/tvcubana.icrt.cu.config.js
@@ -39,7 +39,7 @@ function parseItems(content) {
let data
try {
data = JSON.parse(content)
- } catch (error) {
+ } catch {
return []
}
if (!data || !Array.isArray(data)) return []
diff --git a/sites/tvguide.com/tvguide.com.config.js b/sites/tvguide.com/tvguide.com.config.js
index 5ddddf8b..54b08bbb 100644
--- a/sites/tvguide.com/tvguide.com.config.js
+++ b/sites/tvguide.com/tvguide.com.config.js
@@ -82,7 +82,10 @@ function parseItems(content) {
}
async function loadProgramDetails(item) {
- item.programDetails = item.programDetails.replace('player1-backend-prod-internal.apigee.net', 'internal-prod.apigee.fandom.net')
+ item.programDetails = item.programDetails.replace(
+ 'player1-backend-prod-internal.apigee.net',
+ 'internal-prod.apigee.fandom.net'
+ )
const data = await axios
.get(item.programDetails)
.then(r => r.data)
diff --git a/sites/tvheute.at/tvheute.at.config.js b/sites/tvheute.at/tvheute.at.config.js
index 4862eec1..d73706c8 100644
--- a/sites/tvheute.at/tvheute.at.config.js
+++ b/sites/tvheute.at/tvheute.at.config.js
@@ -28,7 +28,7 @@ module.exports = {
async channels() {
const axios = require('axios')
const html = await axios
- .get(`https://tvheute.at/part/channel-selection`)
+ .get('https://tvheute.at/part/channel-selection')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/tvim.tv/tvim.tv.config.js b/sites/tvim.tv/tvim.tv.config.js
index 678291af..f67ac2ea 100644
--- a/sites/tvim.tv/tvim.tv.config.js
+++ b/sites/tvim.tv/tvim.tv.config.js
@@ -29,7 +29,7 @@ module.exports = {
async channels() {
const axios = require('axios')
const data = await axios
- .get(`https://www.tvim.tv/script/epg/category_channels?category=all&filter=playable`)
+ .get('https://www.tvim.tv/script/epg/category_channels?category=all&filter=playable')
.then(r => r.data)
.catch(console.log)
diff --git a/sites/tvireland.ie/tvireland.ie.config.js b/sites/tvireland.ie/tvireland.ie.config.js
index 93e712af..c28eb8c8 100644
--- a/sites/tvireland.ie/tvireland.ie.config.js
+++ b/sites/tvireland.ie/tvireland.ie.config.js
@@ -49,7 +49,7 @@ module.exports = {
const channels = []
for (let provider of providers) {
const data = await axios
- .post(`https://www.tvireland.ie/tv/schedule`, null, {
+ .post('https://www.tvireland.ie/tv/schedule', null, {
params: {
provider,
region: 'Ireland',
@@ -81,7 +81,7 @@ module.exports = {
}
}
-function parseStart($item, date, channel) {
+function parseStart($item, date) {
const timeString = $item('td:eq(0)').text().trim()
const dateString = `${date.format('YYYY-MM-DD')} ${timeString}`
diff --git a/sites/tvpassport.com/tvpassport.com.config.js b/sites/tvpassport.com/tvpassport.com.config.js
index c8d28d3f..fe95d1b4 100644
--- a/sites/tvpassport.com/tvpassport.com.config.js
+++ b/sites/tvpassport.com/tvpassport.com.config.js
@@ -70,7 +70,7 @@ module.exports = {
let i = 1
for (let el of elements) {
const url = $(el).text()
- const [, site_id] = url.match(/\/tv\-listings\/stations\/(.*)$/)
+ const [, site_id] = url.match(/\/tv-listings\/stations\/(.*)$/)
console.log(`[${i}/${total}]`, url)
diff --git a/sites/tvplus.com.tr/tvplus.com.tr.config.js b/sites/tvplus.com.tr/tvplus.com.tr.config.js
index 391f3929..60ed9aa2 100644
--- a/sites/tvplus.com.tr/tvplus.com.tr.config.js
+++ b/sites/tvplus.com.tr/tvplus.com.tr.config.js
@@ -24,15 +24,7 @@ module.exports = {
debug('Got build id', module.exports.buildId)
}
const channelId = channel.site_id.replace('/', '--')
- return `https://tvplus.com.tr/_next/data/${
- module.exports.buildId
- }/${
- channel.lang
- }/canli-tv/yayin-akisi/${
- channelId
- }.json?title=${
- channelId
- }`
+ return `https://tvplus.com.tr/_next/data/${module.exports.buildId}/${channel.lang}/canli-tv/yayin-akisi/${channelId}.json?title=${channelId}`
},
parser({ content, date }) {
const programs = []
@@ -43,7 +35,9 @@ module.exports = {
.filter(i => i.length && i[0].starttime.startsWith(date.format('YYYY-MM-DD')))
.forEach(i => {
for (const schedule of i) {
- const [, season, episode] = schedule.seasonInfo?.match(/(\d+)\. Sezon \- (\d+)\. Bölüm/) || [null, null, null]
+ const [, season, episode] = schedule.seasonInfo?.match(
+ /(\d+)\. Sezon - (\d+)\. Bölüm/
+ ) || [null, null, null]
programs.push({
title: schedule.name,
description: schedule.introduce,
@@ -69,14 +63,19 @@ module.exports = {
.catch(console.error)
const $ = cheerio.load(data)
- $('.channel-list-item a').toArray()
+ $('.channel-list-item a')
+ .toArray()
.forEach(el => {
const a = $(el)
channels.push({
lang: 'tr',
- name: a.attr('title').replace(/Yayın Akışı/, '').trim(),
- site_id: a.attr('href')
- .replace(/\/canli\-tv\/yayin\-akisi\//, '')
+ name: a
+ .attr('title')
+ .replace(/Yayın Akışı/, '')
+ .trim(),
+ site_id: a
+ .attr('href')
+ .replace(/\/canli-tv\/yayin-akisi\//, '')
.replace('--', '/') // change -- to / as it used in xml comment
})
})
diff --git a/sites/tvplus.com.tr/tvplus.com.tr.test.js b/sites/tvplus.com.tr/tvplus.com.tr.test.js
index c0f5c13e..d7586cda 100644
--- a/sites/tvplus.com.tr/tvplus.com.tr.test.js
+++ b/sites/tvplus.com.tr/tvplus.com.tr.test.js
@@ -18,7 +18,7 @@ const channel = {
xmltv_id: 'NickJr.tr'
}
-axios.get.mockImplementation((url, opts) => {
+axios.get.mockImplementation(url => {
if (url === 'https://tvplus.com.tr/canli-tv/yayin-akisi') {
return Promise.resolve({
data: fs.readFileSync(path.join(__dirname, '__data__', 'build.html')).toString()
@@ -27,17 +27,18 @@ axios.get.mockImplementation((url, opts) => {
})
it('can generate valid url', async () => {
- expect(await url({ channel })).toBe('https://tvplus.com.tr/_next/data/kUzvz_bbQJNaShlFUkrR3/tr/canli-tv/yayin-akisi/nick-jr--4353.json?title=nick-jr--4353')
+ expect(await url({ channel })).toBe(
+ 'https://tvplus.com.tr/_next/data/kUzvz_bbQJNaShlFUkrR3/tr/canli-tv/yayin-akisi/nick-jr--4353.json?title=nick-jr--4353'
+ )
})
it('can parse response', () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content.json'))
- const results = parser({ date, channel, content })
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ const results = parser({ date, channel, content }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(results.length).toBe(88)
expect(results[0]).toMatchObject({
@@ -45,7 +46,7 @@ it('can parse response', () => {
stop: '2024-12-14T21:20:00.000Z',
title: 'Camgöz (2020)',
description:
- 'Max\'in Camgöz adında yarı köpek balığı yarı köpek eşsiz bir evcil havyanı vardır. İlk başlarda Camgöz\'ü saklamaya çalışsa da Sisli Pınarlar\'da, en iyi arkadaşlar, meraklı komşular ve hatta Max\'in ailesi bile yaramaz yeni arkadaşını fark edecektir.',
+ "Max'in Camgöz adında yarı köpek balığı yarı köpek eşsiz bir evcil havyanı vardır. İlk başlarda Camgöz'ü saklamaya çalışsa da Sisli Pınarlar'da, en iyi arkadaşlar, meraklı komşular ve hatta Max'in ailesi bile yaramaz yeni arkadaşını fark edecektir.",
image:
'https://gbzeottvsc01.tvplus.com.tr:33207/CPS/images/universal/film/program/202412/20241209/21/2126356250845eb88428_0_XL.jpg',
category: 'Çocuk',
diff --git a/sites/tvtv.us/tvtv.us.config.js b/sites/tvtv.us/tvtv.us.config.js
index dec7fb9e..b1eb7629 100644
--- a/sites/tvtv.us/tvtv.us.config.js
+++ b/sites/tvtv.us/tvtv.us.config.js
@@ -1,4 +1,4 @@
-const dayjs = require('dayjs')
+const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
diff --git a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js
index a26c23fd..dba45f8d 100644
--- a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js
+++ b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js
@@ -18,11 +18,9 @@ module.exports = {
}
},
url({ date, segment = 0 }) {
- return `https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/${
- date.format('YYYYMMDD')
- }${
- segment.toString().padStart(2, '0')
- }0000`
+ return `https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/${date.format(
+ 'YYYYMMDD'
+ )}${segment.toString().padStart(2, '0')}0000`
},
async parser({ content, channel, date }) {
const programs = []
@@ -31,9 +29,9 @@ module.exports = {
if (Array.isArray(items.entries)) {
// fetch other segments
const queues = [
- module.exports.url({ date, segment: 6}),
- module.exports.url({ date, segment: 12}),
- module.exports.url({ date, segment: 18}),
+ module.exports.url({ date, segment: 6 }),
+ module.exports.url({ date, segment: 12 }),
+ module.exports.url({ date, segment: 18 })
]
await doFetch(queues, (url, res) => {
if (Array.isArray(res.entries)) {
@@ -43,13 +41,12 @@ module.exports = {
items.entries
.filter(item => item.channelId === channel.site_id)
.forEach(item => {
- if (Array.isArray(item.events)){
+ if (Array.isArray(item.events)) {
if (detailedGuide) {
- queues.push(...item.events
- .map(event =>
- `https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/${
- event.id
- }?returnLinearContent=true&forceLinearResponse=true&language=en`
+ queues.push(
+ ...item.events.map(
+ event =>
+ `https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/${event.id}?returnLinearContent=true&forceLinearResponse=true&language=en`
)
)
} else {
@@ -92,20 +89,23 @@ module.exports = {
const channels = []
const axios = require('axios')
const res = await axios
- .get('https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/channels?cityId=40980&language=en&productClass=Orion-DASH&platform=web')
+ .get(
+ 'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/channels?cityId=40980&language=en&productClass=Orion-DASH&platform=web'
+ )
.then(r => r.data)
.catch(console.error)
if (Array.isArray(res)) {
- channels.push(...res
- .filter(item => !item.isHidden)
- .map(item => {
- return {
- lang: 'en',
- site_id: item.id,
- name: item.name
- }
- })
+ channels.push(
+ ...res
+ .filter(item => !item.isHidden)
+ .map(item => {
+ return {
+ lang: 'en',
+ site_id: item.id,
+ name: item.name
+ }
+ })
)
}
diff --git a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js
index d2213198..1fbc3400 100644
--- a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js
+++ b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js
@@ -32,7 +32,7 @@ axios.get.mockImplementation(url => {
'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F17641069~~2FEP026460800059,imi:23c363d12af79f43134f4a15b96dd12df81b19ab?returnLinearContent=true&forceLinearResponse=true&language=en':
'program02.json',
'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458689,imi:f1060b3f63cd5399e0f97901b25a85ef71097891?returnLinearContent=true&forceLinearResponse=true&language=en':
- 'program03.json',
+ 'program03.json'
}
let data = ''
if (urls[url] !== undefined) {
@@ -50,16 +50,16 @@ it('can generate valid url', () => {
)
})
-it('can parse response', async() => {
- const content = await axios.get(url({ date }))
+it('can parse response', async () => {
+ const content = await axios
+ .get(url({ date }))
.then(response => response.data)
.catch(console.error)
- const result = (await parser({ content, channel, date }))
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ const result = (await parser({ content, channel, date })).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(result.length).toBe(3)
expect(result[0]).toMatchObject({
diff --git a/sites/visionplus.id/visionplus.id.config.js b/sites/visionplus.id/visionplus.id.config.js
index f2f5ca49..e4220ca4 100644
--- a/sites/visionplus.id/visionplus.id.config.js
+++ b/sites/visionplus.id/visionplus.id.config.js
@@ -13,11 +13,11 @@ module.exports = {
site: 'visionplus.id',
days: 2,
url({ date, channel }) {
- return `https://www.visionplus.id/managetv/tvinfo/events/schedule?language=${languages[channel.lang]}&serviceId=${channel.site_id}&start=${date.format(
- 'YYYY-MM-DD'
- )}T00%3A00%3A00Z&end=${date.add(1, 'd').format(
- 'YYYY-MM-DD'
- )}T00%3A00%3A00Z&view=cd-events-grid-view`
+ return `https://www.visionplus.id/managetv/tvinfo/events/schedule?language=${
+ languages[channel.lang]
+ }&serviceId=${channel.site_id}&start=${date.format('YYYY-MM-DD')}T00%3A00%3A00Z&end=${date
+ .add(1, 'd')
+ .format('YYYY-MM-DD')}T00%3A00%3A00Z&view=cd-events-grid-view`
},
parser({ content, channel }) {
const programs = []
@@ -26,7 +26,13 @@ module.exports = {
for (const ev of json.evs) {
if (ev.sid === channel.site_id) {
const title = ev.con && ev.con.loc ? ev.con.loc[0].tit : ev.con.oti
- const [, , season, , episode] = title.match(/( S(\d+))?(, Ep (\d+))/) || [null, null, null, null, null]
+ const [, , season, , episode] = title.match(/( S(\d+))?(, Ep (\d+))/) || [
+ null,
+ null,
+ null,
+ null,
+ null
+ ]
programs.push({
title,
description: ev.con && ev.con.loc ? ev.con.loc[0].syn : null,
diff --git a/sites/visionplus.id/visionplus.id.test.js b/sites/visionplus.id/visionplus.id.test.js
index 99b1398c..f71f7c6f 100644
--- a/sites/visionplus.id/visionplus.id.test.js
+++ b/sites/visionplus.id/visionplus.id.test.js
@@ -16,7 +16,7 @@ const channel = {
xmltv_id: 'AXN.id',
lang: 'en'
}
-const channelId = { ...channel, lang: 'id' }
+const channelId = { ...channel, lang: 'id' }
it('can generate valid url', () => {
expect(url({ channel, date })).toBe(
@@ -29,37 +29,37 @@ it('can generate valid url', () => {
it('can parse response', () => {
let content = fs.readFileSync(path.resolve(__dirname, '__data__/content_en.json'))
- let results = parser({ content, channel, date })
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ let results = parser({ content, channel, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(results.length).toBe(1)
expect(results[0]).toMatchObject({
start: '2024-11-23T23:30:00.000Z',
stop: '2024-11-24T00:15:00.000Z',
title: 'FBI: Most Wanted S4, Ep 18',
- description: 'After two agents from the Bureau of Land Management go missing while executing a land seizure warrant in Wyoming, the Fugitive Task Force heads west to track them down in an unwelcoming county.',
+ description:
+ 'After two agents from the Bureau of Land Management go missing while executing a land seizure warrant in Wyoming, the Fugitive Task Force heads west to track them down in an unwelcoming county.',
season: 4,
episode: 18
})
content = fs.readFileSync(path.resolve(__dirname, '__data__/content_id.json'))
- results = parser({ content, channel: channelId, date })
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ results = parser({ content, channel: channelId, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(results.length).toBe(1)
expect(results[0]).toMatchObject({
start: '2024-11-23T23:30:00.000Z',
stop: '2024-11-24T00:15:00.000Z',
title: 'FBI: Most Wanted S4, Ep 18',
- description: 'Satgas Buronan pergi ke wilayah barat untuk melacak keberadaan dua petugas Biro Pengelolaan Lahan yang menghilang saat menjalankan perintah penyitaan lahan di negara bagian yang tak ramah, Wyoming.',
+ description:
+ 'Satgas Buronan pergi ke wilayah barat untuk melacak keberadaan dua petugas Biro Pengelolaan Lahan yang menghilang saat menjalankan perintah penyitaan lahan di negara bagian yang tak ramah, Wyoming.',
season: 4,
episode: 18
})
diff --git a/sites/watch.sportsnet.ca/watch.sportsnet.ca.config.js b/sites/watch.sportsnet.ca/watch.sportsnet.ca.config.js
index 88e3db99..a3e956e9 100644
--- a/sites/watch.sportsnet.ca/watch.sportsnet.ca.config.js
+++ b/sites/watch.sportsnet.ca/watch.sportsnet.ca.config.js
@@ -29,11 +29,11 @@ module.exports = {
async channels() {
const axios = require('axios')
const html = await axios
- .get(`https://watch.sportsnet.ca/schedule/tvlistings`)
+ .get('https://watch.sportsnet.ca/schedule/tvlistings')
.then(r => r.data)
.catch(console.log)
- let [, __data] = html.match(/window\.__data \= ([^<]+)<\/script>/)
+ let [, __data] = html.match(/window\.__data = ([^<]+)<\/script>/)
const func = new Function(`"use strict";return ${__data}`)
const data = func()
diff --git a/sites/web.magentatv.de/web.magentatv.de.config.js b/sites/web.magentatv.de/web.magentatv.de.config.js
index 5aefde78..aadff1cf 100644
--- a/sites/web.magentatv.de/web.magentatv.de.config.js
+++ b/sites/web.magentatv.de/web.magentatv.de.config.js
@@ -28,7 +28,8 @@ module.exports = {
offset: 0,
properties: [
{
- include: 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
+ include:
+ 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
name: 'playbill'
}
],
@@ -111,15 +112,15 @@ function parseCategory(item) {
}
function parseDirectors(item) {
- if (!item.cast || !item.cast.director) return [];
+ if (!item.cast || !item.cast.director) return []
return item.cast.director
.replace('und', ',')
.split(',')
- .map(i => i.trim());
+ .map(i => i.trim())
}
function parseProducers(item) {
- if (!item.cast || !item.cast.producer) return [];
+ if (!item.cast || !item.cast.producer) return []
return item.cast.producer
.replace('und', ',')
.split(',')
@@ -127,7 +128,7 @@ function parseProducers(item) {
}
function parseAdapters(item) {
- if (!item.cast || !item.cast.adaptor) return [];
+ if (!item.cast || !item.cast.adaptor) return []
return item.cast.adaptor
.replace('und', ',')
.split(',')
@@ -136,7 +137,7 @@ function parseAdapters(item) {
function parseUrls(item) {
// currently only a imdb id is returned by the api, thus we can construct the url here
- if (!item.externalIds) return [];
+ if (!item.externalIds) return []
return JSON.parse(item.externalIds)
.filter(externalId => externalId.type === 'imdb' && externalId.id)
.map(externalId => ({ system: 'imdb', value: `https://www.imdb.com/title/${externalId.id}` }))
diff --git a/sites/web.magentatv.de/web.magentatv.de.test.js b/sites/web.magentatv.de/web.magentatv.de.test.js
index 935b0828..95332580 100644
--- a/sites/web.magentatv.de/web.magentatv.de.test.js
+++ b/sites/web.magentatv.de/web.magentatv.de.test.js
@@ -41,7 +41,8 @@ it('can generate valid request data', () => {
offset: 0,
properties: [
{
- include: 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
+ include:
+ 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
name: 'playbill'
}
],
@@ -78,20 +79,27 @@ it('can parse response', () => {
sub_title: 'Tritte unter dem Tisch',
description:
'Amy arbeitet für eine Weile in Sheldons Universität, er freut sich darüber, doch sie warnt ihn, dass sie sich jetzt häufiger zu Gesicht bekommen. Als Leonard, Sheldon, Raj und Howard zusammen sitzen, diskutieren sie darüber. Sheldon lässt auf sich einreden und informiert Amy, dass er ein Problem mit ihr auf seiner Arbeit hat. Sie ist enttäuscht, während Bernadette mit Howard darüber spricht, warum er auf Sheldon eingeredet hat.',
- season: "7",
- episode: "5",
+ season: '7',
+ episode: '5',
image:
'http://ngiss.t-online.de/cm1s/media/gracenote/1/0/p10262968_e_h9_ah_2021-10-20T07_16_16.jpg',
category: ['Sitcom'],
- directors: ["Mark Cendrowski"],
- producers: ["Chuck Lorre","Bill Prady","Steven Molaro"],
- adapters: ["Steven Molaro","Steve Holland","Maria Ferrari","Chuck Lorre","Eric Kaplan","Jim Reynolds"],
+ directors: ['Mark Cendrowski'],
+ producers: ['Chuck Lorre', 'Bill Prady', 'Steven Molaro'],
+ adapters: [
+ 'Steven Molaro',
+ 'Steve Holland',
+ 'Maria Ferrari',
+ 'Chuck Lorre',
+ 'Eric Kaplan',
+ 'Jim Reynolds'
+ ],
country: 'US',
- date: "2013-01-01",
+ date: '2013-01-01',
urls: [
{
- system: "imdb",
- value: "https://www.imdb.com/title/tt0898266"
+ system: 'imdb',
+ value: 'https://www.imdb.com/title/tt0898266'
}
]
}
diff --git a/sites/winplay.co/winplay.co.config.js b/sites/winplay.co/winplay.co.config.js
index 39375208..831fecc7 100644
--- a/sites/winplay.co/winplay.co.config.js
+++ b/sites/winplay.co/winplay.co.config.js
@@ -1,4 +1,3 @@
-const axios = require('axios')
const dayjs = require('dayjs')
module.exports = {
diff --git a/sites/ziggogo.tv/ziggogo.tv.config.js b/sites/ziggogo.tv/ziggogo.tv.config.js
index 0de4cc63..480904dc 100644
--- a/sites/ziggogo.tv/ziggogo.tv.config.js
+++ b/sites/ziggogo.tv/ziggogo.tv.config.js
@@ -18,11 +18,9 @@ module.exports = {
}
},
url({ date, segment = 0 }) {
- return `https://static.spark.ziggogo.tv/eng/web/epg-service-lite/nl/en/events/segments/${
- date.format('YYYYMMDD')
- }${
- segment.toString().padStart(2, '0')
- }0000`
+ return `https://static.spark.ziggogo.tv/eng/web/epg-service-lite/nl/en/events/segments/${date.format(
+ 'YYYYMMDD'
+ )}${segment.toString().padStart(2, '0')}0000`
},
async parser({ content, channel, date }) {
const programs = []
@@ -31,9 +29,9 @@ module.exports = {
if (Array.isArray(items.entries)) {
// fetch other segments
const queues = [
- module.exports.url({ date, segment: 6}),
- module.exports.url({ date, segment: 12}),
- module.exports.url({ date, segment: 18}),
+ module.exports.url({ date, segment: 6 }),
+ module.exports.url({ date, segment: 12 }),
+ module.exports.url({ date, segment: 18 })
]
await doFetch(queues, (url, res) => {
if (Array.isArray(res.entries)) {
@@ -43,13 +41,12 @@ module.exports = {
items.entries
.filter(item => item.channelId === channel.site_id)
.forEach(item => {
- if (Array.isArray(item.events)){
+ if (Array.isArray(item.events)) {
if (detailedGuide) {
- queues.push(...item.events
- .map(event =>
- `https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/replayEvent/${
- event.id
- }?returnLinearContent=true&forceLinearResponse=true&language=nl`
+ queues.push(
+ ...item.events.map(
+ event =>
+ `https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/replayEvent/${event.id}?returnLinearContent=true&forceLinearResponse=true&language=nl`
)
)
} else {
@@ -92,20 +89,23 @@ module.exports = {
const channels = []
const axios = require('axios')
const res = await axios
- .get('https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/channels?cityId=65535&language=en&productClass=Orion-DASH&platform=web')
+ .get(
+ 'https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/channels?cityId=65535&language=en&productClass=Orion-DASH&platform=web'
+ )
.then(r => r.data)
.catch(console.error)
if (Array.isArray(res)) {
- channels.push(...res
- .filter(item => !item.isHidden)
- .map(item => {
- return {
- lang: 'nl',
- site_id: item.id,
- name: item.name
- }
- })
+ channels.push(
+ ...res
+ .filter(item => !item.isHidden)
+ .map(item => {
+ return {
+ lang: 'nl',
+ site_id: item.id,
+ name: item.name
+ }
+ })
)
}
diff --git a/sites/ziggogo.tv/ziggogo.tv.test.js b/sites/ziggogo.tv/ziggogo.tv.test.js
index e4d9aef1..bfc5b2d4 100644
--- a/sites/ziggogo.tv/ziggogo.tv.test.js
+++ b/sites/ziggogo.tv/ziggogo.tv.test.js
@@ -32,7 +32,7 @@ axios.get.mockImplementation(url => {
'https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F28842707~~2FEP022675661065,imi:33138a61bfa639696f386a5b8da9052e98cffdf8?returnLinearContent=true&forceLinearResponse=true&language=nl':
'program02.json',
'https://spark-prod-nl.gnp.cloud.ziggogo.tv/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F28728829~~2FEP052397600066,imi:34a0b026912de96e3546b15ad2983070a250dfd5?returnLinearContent=true&forceLinearResponse=true&language=nl':
- 'program03.json',
+ 'program03.json'
}
let data = ''
if (urls[url] !== undefined) {
@@ -51,15 +51,15 @@ it('can generate valid url', () => {
})
it('can parse response', async () => {
- const content = await axios.get(url({ date }))
+ const content = await axios
+ .get(url({ date }))
.then(response => response.data)
.catch(console.error)
- const result = (await parser({ content, channel, date }))
- .map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
+ const result = (await parser({ content, channel, date })).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+ return p
+ })
expect(result.length).toBe(3)
expect(result[0]).toMatchObject({
@@ -91,11 +91,7 @@ it('can parse response', async () => {
category: ['Talkshow'],
season: 1,
episode: 65,
- actor: [
- 'Sophie Hilbrand',
- 'Jeroen Pauw',
- 'Tim de Wit'
- ]
+ actor: ['Sophie Hilbrand', 'Jeroen Pauw', 'Tim de Wit']
})
})
diff --git a/tests/__data__/expected/_sites.md b/tests/__data__/expected/_sites.md
index ede49778..bd63aa62 100644
--- a/tests/__data__/expected/_sites.md
+++ b/tests/__data__/expected/_sites.md
@@ -1,210 +1,13 @@
-# Sites
-
-
-
+# Sites
+
+
+
diff --git a/tests/__data__/input/.sites/template.md b/tests/__data__/input/.sites/template.md
index b91bd031..c630b91b 100644
--- a/tests/__data__/input/.sites/template.md
+++ b/tests/__data__/input/.sites/template.md
@@ -1,4 +1,4 @@
-# Sites
-
-
-#include "tests/__data__/output/.sites/_table.md"
+# Sites
+
+
+#include "tests/__data__/output/.sites/_table.md"
diff --git a/tests/__data__/input/channels-lint/channels-lint.channels.xml b/tests/__data__/input/channels-lint/error.channels.xml
similarity index 100%
rename from tests/__data__/input/channels-lint/channels-lint.channels.xml
rename to tests/__data__/input/channels-lint/error.channels.xml
diff --git a/tests/__data__/input/channels-lint/invalid.channels.xml b/tests/__data__/input/channels-lint/invalid.channels.xml
new file mode 100644
index 00000000..f69d9631
--- /dev/null
+++ b/tests/__data__/input/channels-lint/invalid.channels.xml
@@ -0,0 +1,5 @@
+
+
+
+ Bravo
+
\ No newline at end of file
diff --git a/tests/__data__/input/issues/broken_guide_down.js b/tests/__data__/input/issues/broken_guide_down.mjs
similarity index 97%
rename from tests/__data__/input/issues/broken_guide_down.js
rename to tests/__data__/input/issues/broken_guide_down.mjs
index 331bf671..9f069689 100644
--- a/tests/__data__/input/issues/broken_guide_down.js
+++ b/tests/__data__/input/issues/broken_guide_down.mjs
@@ -1,1551 +1,1551 @@
-module.exports = [
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2547',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2547',
- id: 2760418979,
- node_id: 'I_kwDOFLVvtM6kiKaj',
- number: 2547,
- title: 'digiturk.com.tr',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2024-12-27T05:33:47Z',
- updated_at: '2024-12-28T20:37:53Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ndigiturk.com.tr\n\n### Description\n\n```sh\r\nnpm run grab --- --site=digiturk.com.tr\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=digiturk.com.tr\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: digiturk.com.tr\r\nloading channels...\r\n found 139 channel(s)\r\nrun #1:\r\n [1/278] digiturk.com.tr (en) - AlJazeeraEnglish.qa - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/278] digiturk.com.tr (en) - AlJazeeraEnglish.qa - Dec 28, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/278] digiturk.com.tr (tr) - Yaban.tr - Dec 28, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/reactions',
- total_count: 1,
- '+1': 1,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2542',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2542',
- id: 2759639980,
- node_id: 'I_kwDOFLVvtM6kfMOs',
- number: 2542,
- title: 'tvguide.com not working',
- user: {
- login: 'SiWafer',
- id: 10903014,
- node_id: 'MDQ6VXNlcjEwOTAzMDE0',
- avatar_url: 'https://avatars.githubusercontent.com/u/10903014?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/SiWafer',
- html_url: 'https://github.com/SiWafer',
- followers_url: 'https://api.github.com/users/SiWafer/followers',
- following_url: 'https://api.github.com/users/SiWafer/following{/other_user}',
- gists_url: 'https://api.github.com/users/SiWafer/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/SiWafer/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/SiWafer/subscriptions',
- organizations_url: 'https://api.github.com/users/SiWafer/orgs',
- repos_url: 'https://api.github.com/users/SiWafer/repos',
- events_url: 'https://api.github.com/users/SiWafer/events{/privacy}',
- received_events_url: 'https://api.github.com/users/SiWafer/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-12-26T11:11:24Z',
- updated_at: '2024-12-27T05:28:55Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\ntvguide.com\n\n### Description\n\n```\r\nepg@rpi:~/epg$ npm run grab --- --site=tvguide.com\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tvguide.com\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tvguide.com\r\nloading channels...\r\n found 39 channel(s)\r\nrun #1:\r\n [1/78] tvguide.com (en) - AEEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [2/78] tvguide.com (en) - AEEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [3/78] tvguide.com (en) - AMCEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [4/78] tvguide.com (en) - AMCEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [5/78] tvguide.com (en) - BravoEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [6/78] tvguide.com (en) - BravoEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [7/78] tvguide.com (en) - BBCAmericaEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [8/78] tvguide.com (en) - CNBC.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [9/78] tvguide.com (en) - CNBC.us - Dec 26, 2024 (0 programs)\r\n...\r\n...\r\n...\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2541',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2541',
- id: 2758749907,
- node_id: 'I_kwDOFLVvtM6kby7T',
- number: 2541,
- title: 'elcinema.com grab error 403',
- user: {
- login: 'xercessss',
- id: 189765257,
- node_id: 'U_kgDOC0-WiQ',
- avatar_url: 'https://avatars.githubusercontent.com/u/189765257?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/xercessss',
- html_url: 'https://github.com/xercessss',
- followers_url: 'https://api.github.com/users/xercessss/followers',
- following_url: 'https://api.github.com/users/xercessss/following{/other_user}',
- gists_url: 'https://api.github.com/users/xercessss/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/xercessss/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/xercessss/subscriptions',
- organizations_url: 'https://api.github.com/users/xercessss/orgs',
- repos_url: 'https://api.github.com/users/xercessss/repos',
- events_url: 'https://api.github.com/users/xercessss/events{/privacy}',
- received_events_url: 'https://api.github.com/users/xercessss/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-12-25T11:34:16Z',
- updated_at: '2024-12-27T05:28:07Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\nelcinema.com\n\n### Description\n\ngrabbing elcinema.com epg return error 403 for both ar and en language:\r\nERR: Request failed with status code 403\r\n',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2509',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2509',
- id: 2740938968,
- node_id: 'I_kwDOFLVvtM6jX2jY',
- number: 2509,
- title: 'ssl problem maxtv.hrvatskitelekom.hr',
- user: {
- login: 'uploadkom',
- id: 130712472,
- node_id: 'U_kgDOB8qDmA',
- avatar_url: 'https://avatars.githubusercontent.com/u/130712472?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/uploadkom',
- html_url: 'https://github.com/uploadkom',
- followers_url: 'https://api.github.com/users/uploadkom/followers',
- following_url: 'https://api.github.com/users/uploadkom/following{/other_user}',
- gists_url: 'https://api.github.com/users/uploadkom/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/uploadkom/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/uploadkom/subscriptions',
- organizations_url: 'https://api.github.com/users/uploadkom/orgs',
- repos_url: 'https://api.github.com/users/uploadkom/repos',
- events_url: 'https://api.github.com/users/uploadkom/events{/privacy}',
- received_events_url: 'https://api.github.com/users/uploadkom/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 3,
- created_at: '2024-12-15T22:21:22Z',
- updated_at: '2024-12-27T05:26:26Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\nmaxtv.hrvatskitelekom.hr\n\n### Description\n\nssl problem',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2498',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2498',
- id: 2728188494,
- node_id: 'I_kwDOFLVvtM6inNpO',
- number: 2498,
- title: 'movistarplus.es',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-12-09T20:26:07Z',
- updated_at: '2024-12-27T05:23:48Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nmovistarplus.es\n\n### Description\n\n```sh\r\nnpm run grab -- --site=movistarplus.es\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=movistarplus.es\r\n\r\n(node:22362) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:\r\n--import \'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("file%3A///Users/Arhey/Code/iptv-org/epg/node_modules/tsx/dist/loader.mjs", pathToFileURL("./"));\'\r\n(Use `node --trace-warnings ...` to show where the warning was created)\r\n(node:22362) UnsupportedWarning: `globalPreload` has been removed; use `initialize` instead.\r\n(Use `node --trace-warnings ...` to show where the warning was created)\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: movistarplus.es\r\nloading channels...\r\n(node:22362) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.\r\n found 186 channel(s)\r\nrun #1:\r\n [1/372] movistarplus.es (es) - ANTV - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/372] movistarplus.es (es) - ANTV - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/372] movistarplus.es (es) - ARAGTV - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [4/372] movistarplus.es (es) - CANSUR - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [5/372] movistarplus.es (es) - DAZNL2 - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [6/372] movistarplus.es (es) - MLIGS - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [7/372] movistarplus.es (es) - AMC.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [8/372] movistarplus.es (es) - ComediaporMovistarPlusPlus.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [9/372] movistarplus.es (es) - LasEstrellasEuropa.mx - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [10/372] movistarplus.es (es) - LasEstrellasEuropa.mx - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [11/372] movistarplus.es (es) - ComediaporMovistarPlusPlus.es - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [12/372] movistarplus.es (es) - LaResistencia.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [13/372] movistarplus.es (es) - LaResistencia.es - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2445',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2445',
- id: 2567652015,
- node_id: 'I_kwDOFLVvtM6ZC0Kv',
- number: 2445,
- title: 'EPG from dishtv.in stopped with error code 404',
- user: {
- login: 'dheer99',
- id: 20639130,
- node_id: 'MDQ6VXNlcjIwNjM5MTMw',
- avatar_url: 'https://avatars.githubusercontent.com/u/20639130?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/dheer99',
- html_url: 'https://github.com/dheer99',
- followers_url: 'https://api.github.com/users/dheer99/followers',
- following_url: 'https://api.github.com/users/dheer99/following{/other_user}',
- gists_url: 'https://api.github.com/users/dheer99/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/dheer99/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/dheer99/subscriptions',
- organizations_url: 'https://api.github.com/users/dheer99/orgs',
- repos_url: 'https://api.github.com/users/dheer99/repos',
- events_url: 'https://api.github.com/users/dheer99/events{/privacy}',
- received_events_url: 'https://api.github.com/users/dheer99/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 2,
- created_at: '2024-10-05T04:30:52Z',
- updated_at: '2024-12-27T05:20:11Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\ndishtv.in\n\n### Description\n\nEPG from dishtv.in stopped with error code 404\r\n\r\n [91/98] dishtv.in (en) - StarPlus.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [92/98] dishtv.in (en) - SET.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [93/98] dishtv.in (en) - ZeeCinema.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [94/98] dishtv.in (en) - SonySportsTen5.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [95/98] dishtv.in (en) - StarSports1.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [96/98] dishtv.in (en) - SET.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [97/98] dishtv.in (en) - SonySportsTen3.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [98/98] dishtv.in (en) - Colors.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n done in 00h 00m 03s\r\n',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2339',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2339',
- id: 2172864415,
- node_id: 'I_kwDOFLVvtM6Bg0ef',
- number: 2339,
- title:
- 'directv.com.ar and directv.com.uy not working ERR: Unexpected token \'<\', " grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=kan.org.il --output=kan.org.il.xml\r\n\r\nstarting...\r\nconfig:\r\n output: kan.org.il.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: kan.org.il\r\nloading channels...\r\n found 3 channel(s)\r\nrun #1:\r\n [1/6] kan.org.il (ar) - Makan33.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/6] kan.org.il (ar) - Makan33.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/6] kan.org.il (he) - KanEducational.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [4/6] kan.org.il (he) - KanEducational.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [5/6] kan.org.il (he) - Kan11.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [6/6] kan.org.il (he) - Kan11.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n done in 00h 00m 01s\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2273/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2273/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2270',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2270',
- id: 2022018570,
- node_id: 'I_kwDOFLVvtM54hY4K',
- number: 2270,
- title: 'vivacom.bg is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-12-02T12:16:22Z',
- updated_at: '2024-12-27T05:00:36Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nvivacom.bg\n\n### Description\n\n```sh\r\nnpm run grab -- --site=vivacom.bg\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=vivacom.bg\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: vivacom.bg\r\nloading channels...\r\n found 154 channel(s)\r\nrun #1:\r\n [1/308] vivacom.bg (bg) - 24Kitchen.bg - Dec 2, 2023 (0 programs)\r\n [2/308] vivacom.bg (bg) - 24Kitchen.bg - Dec 3, 2023 (0 programs)\r\n [3/308] vivacom.bg (bg) - 78TV.bg - Dec 3, 2023 (0 programs)\r\n [4/308] vivacom.bg (bg) - AlfaTV.bg - Dec 3, 2023 (0 programs)\r\n [5/308] vivacom.bg (bg) - AXNEurope.gr - Dec 3, 2023 (0 programs)\r\n [6/308] vivacom.bg (bg) - BNT3.bg - Dec 3, 2023 (0 programs)\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2264',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2264',
- id: 2019407629,
- node_id: 'I_kwDOFLVvtM54XbcN',
- number: 2264,
- title: 'tva.tv is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-11-30T20:00:18Z',
- updated_at: '2024-12-27T05:00:24Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ntva.tv\n\n### Description\n\n```sh\r\nnpm run grab -- --site=tva.tv\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tva.tv\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tva.tv\r\nloading channels...\r\n found 28 channel(s)\r\nrun #1:\r\n [1/56] tva.tv (fa) - DocTV.ir - Nov 30, 2023 (0 programs)\r\n ERR: Connection timeout\r\n [2/56] tva.tv (fa) - DocTV.ir - Dec 1, 2023 (0 programs)\r\n ERR: Connection timeout\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2263',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2263',
- id: 2019376043,
- node_id: 'I_kwDOFLVvtM54XTur',
- number: 2263,
- title: 'tv.yettel.hu is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-11-30T19:38:28Z',
- updated_at: '2024-12-27T04:59:14Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ntv.yettel.hu\n\n### Description\n\n```sh\r\nnpm run grab -- --site=tv.yettel.hu\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tv.yettel.hu\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tv.yettel.hu\r\nloading channels...\r\n found 74 channel(s)\r\nrun #1:\r\n [1/148] tv.yettel.hu (en) - BBCNewsEurope.uk - Nov 30, 2023 (0 programs)\r\n ERR: Client network socket disconnected before secure TLS connection was established\r\n [2/148] tv.yettel.hu (en) - BBCNewsEurope.uk - Dec 1, 2023 (0 programs)\r\n ERR: Client network socket disconnected before secure TLS connection was established\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2257',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2257',
- id: 2011054011,
- node_id: 'I_kwDOFLVvtM533j-7',
- number: 2257,
- title: 'rtb.gov.bn is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-11-26T14:02:13Z',
- updated_at: '2024-12-27T04:59:29Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nrtb.gov.bn\n\n### Description\n\n```sh\r\nnpm run grab -- --site=rtb.gov.bn\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=rtb.gov.bn\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: rtb.gov.bn\r\nloading channels...\r\n found 3 channel(s)\r\nrun #1:\r\n [1/6] rtb.gov.bn (ms) - RTBAneka.bn - Nov 26, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n [2/6] rtb.gov.bn (ms) - RTBAneka.bn - Nov 27, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n [3/6] rtb.gov.bn (ms) - RTBPerdana.bn - Nov 27, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n```\r\n\r\nThere is no link to the guide on the website at the moment either: https://www.rtb.gov.bn/SitePages/Programme%20Guide.aspx',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2255',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2255',
- id: 2011043202,
- node_id: 'I_kwDOFLVvtM533hWC',
- number: 2255,
- title: 'rev.bs is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2023-11-26T13:31:22Z',
- updated_at: '2024-12-27T22:02:28Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nrev.bs\n\n### Description\n\n```sh\r\nnpm run grab -- --site=rev.bs\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=rev.bs\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: rev.bs\r\nloading channels...\r\n found 179 channel(s)\r\nrun #1:\r\n [1/358] rev.bs (en) - 3ABNEnglish.us - Nov 26, 2023 (0 programs)\r\n [2/358] rev.bs (en) - 3ABNEnglish.us - Nov 27, 2023 (0 programs)\r\n [3/358] rev.bs (en) - AEEast.us - Nov 27, 2023 (0 programs)\r\n [4/358] rev.bs (en) - AMCEast.us - Nov 27, 2023 (0 programs)\r\n```\r\n---\r\n\r\n```json\r\n{\r\n\t"status": "OK",\r\n\t"data": {\r\n\t\t"schedule": [],\r\n\t\t"dateTime": {\r\n\t\t\t"date": "2023-11-27",\r\n\t\t\t"page": 0\r\n\t\t},\r\n\t\t"runtimes": [\r\n\t\t\t{\r\n\t\t\t\t"Rev class loaded": 1700899490.604637\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"TVGuide Class Loaded": 1700899490.638891\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"Validated form": 1700899490.640116\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"Pulled schedules": 1700899490.642099\r\n\t\t\t}\r\n\t\t]\r\n\t}\r\n}\r\n```\r\n\r\nhttps://www.rev.bs/wp-content/uploads/tv-guide/2023-11-27_0.json\r\n\r\n---\r\n\r\n \r\n\r\nhttps://www.rev.bs/tv-guide-404/',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2241',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2241',
- id: 2002096969,
- node_id: 'I_kwDOFLVvtM53VZNJ',
- number: 2241,
- title: 'm.tv.sms.cz is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 4,
- created_at: '2023-11-20T12:28:47Z',
- updated_at: '2024-12-27T04:58:41Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nm.tv.sms.cz\n\n### Description\n\n```sh\r\nnpm run grab -- --site=m.tv.sms.cz\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=m.tv.sms.cz\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: m.tv.sms.cz\r\nloading channels...\r\n found 525 channel(s)\r\nrun #1:\r\n [1/1050] m.tv.sms.cz (bs) - BNTV.ba - Nov 20, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n\r\n [2/1050] m.tv.sms.cz (bs) - BNTV.ba - Nov 21, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n\r\n [3/1050] m.tv.sms.cz (cs) - AMC.cz - Nov 21, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n```\r\n\r\nhttps://check-host.net/check-report/135d7e05kb9d',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2240',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2240',
- id: 2001847449,
- node_id: 'I_kwDOFLVvtM53UcSZ',
- number: 2240,
- title: 'kplus.vn is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-11-20T10:19:23Z',
- updated_at: '2024-12-27T04:57:49Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\nkplus.vn\n\n### Description\n\n```sh\r\nnpm run grab -- --site=kplus.vn\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=kplus.vn\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: kplus.vn\r\nloading channels...\r\n found 26 channel(s)\r\nrun #1:\r\n [1/52] kplus.vn (vi) - AsianFoodNetwork.sg - Nov 20, 2023 (0 programs)\r\n [2/52] kplus.vn (vi) - AsianFoodNetwork.sg - Nov 21, 2023 (0 programs)\r\n [3/52] kplus.vn (vi) - AXN.vn - Nov 21, 2023 (0 programs)\r\n [4/52] kplus.vn (vi) - DiscoveryChannelSoutheastAsia.sg - Nov 21, 2023 (0 programs)\r\n```\r\n\r\nThe site also currently does not display the guide:\r\n \r\nhttps://www.kplus.vn/highlights/broadcast-schedule',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2239',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2239',
- id: 2000457187,
- node_id: 'I_kwDOFLVvtM53PI3j',
- number: 2239,
- title: 'comteco.com.bo is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 3,
- created_at: '2023-11-18T15:03:48Z',
- updated_at: '2024-12-27T21:25:41Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ncomteco.com.bo\n\n### Description\n\n```sh\r\nnpm run grab -- --site=comteco.com.bo\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=comteco.com.bo\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: comteco.com.bo\r\nloading channels...\r\n found 72 channel(s)\r\nrun #1:\r\n [1/144] comteco.com.bo (es) - AbyaYalaTV.bo - Nov 18, 2023 (0 programs)\r\n [2/144] comteco.com.bo (es) - AbyaYalaTV.bo - Nov 19, 2023 (0 programs)\r\n [3/144] comteco.com.bo (es) - AEPanregional.us - Nov 19, 2023 (0 programs)\r\n [4/144] comteco.com.bo (es) - AnimalPlanetLatinAmerica.us - Nov 19, 2023 (0 programs)\r\n [5/144] comteco.com.bo (es) - BoliviaTV72.bo - Nov 19, 2023 (0 programs)\r\n```\r\n\r\nhttps://comteco.com.bo/pages/canales-y-programacion-tv/paquete-oro/ABYA%20YALA\r\n ',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2237',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2237',
- id: 2000349577,
- node_id: 'I_kwDOFLVvtM53OumJ',
- number: 2237,
- title: 'canalplus-haiti.com is broken',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2023-11-18T09:46:29Z',
- updated_at: '2024-12-27T04:57:02Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ncanalplus-haiti.com\n\n### Description\n\n```sh\r\nnpm run grab -- --site=canalplus-haiti.com\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=canalplus-haiti.com\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: canalplus-haiti.com\r\nloading channels...\r\n found 111 channel(s)\r\nrun #1:\r\n [1/222] canalplus-haiti.com (fr) - 13emeRue.fr - Nov 18, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [2/222] canalplus-haiti.com (fr) - 13emeRue.fr - Nov 19, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [3/222] canalplus-haiti.com (fr) - ZoukTV.mq - Nov 19, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [4/222] canalplus-haiti.com (fr) - ZoukTV.mq - Nov 18, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n```\r\n\r\nhttps://check-host.net/check-report/134fc56bk333',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2173',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2173',
- id: 1903824500,
- node_id: 'I_kwDOFLVvtM5xeg50',
- number: 2173,
- title: 'hd-plus.de - 0 programs on all channels',
- user: {
- login: 'x011',
- id: 4313821,
- node_id: 'MDQ6VXNlcjQzMTM4MjE=',
- avatar_url: 'https://avatars.githubusercontent.com/u/4313821?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/x011',
- html_url: 'https://github.com/x011',
- followers_url: 'https://api.github.com/users/x011/followers',
- following_url: 'https://api.github.com/users/x011/following{/other_user}',
- gists_url: 'https://api.github.com/users/x011/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/x011/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/x011/subscriptions',
- organizations_url: 'https://api.github.com/users/x011/orgs',
- repos_url: 'https://api.github.com/users/x011/repos',
- events_url: 'https://api.github.com/users/x011/events{/privacy}',
- received_events_url: 'https://api.github.com/users/x011/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710795,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
- name: 'status:down',
- color: 'df3a4a',
- default: false,
- description: "The guide doesn't work"
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2023-09-19T22:45:56Z',
- updated_at: '2024-12-27T04:54:11Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\r\n\r\nhd-plus.de\r\n\r\n### Description\r\n\r\nAll channels on hd-plus.de have 0 programs:\r\n```\r\n[1/60] hd-plus.de - 123tv.de - Sep 19, 2023 (0 programs)\r\n[2/60] hd-plus.de - 123tv.de - Sep 20, 2023 (0 programs)\r\n[3/60] hd-plus.de - ZDF.de - Sep 20, 2023 (0 programs)\r\n[4/60] hd-plus.de - ZDF.de - Sep 19, 2023 (0 programs)\r\n...\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/reactions',
- total_count: 6,
- '+1': 6,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/timeline',
- performed_via_github_app: null,
- state_reason: null
- }
-]
+export default [
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2547',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2547',
+ id: 2760418979,
+ node_id: 'I_kwDOFLVvtM6kiKaj',
+ number: 2547,
+ title: 'digiturk.com.tr',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2024-12-27T05:33:47Z',
+ updated_at: '2024-12-28T20:37:53Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ndigiturk.com.tr\n\n### Description\n\n```sh\r\nnpm run grab --- --site=digiturk.com.tr\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=digiturk.com.tr\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: digiturk.com.tr\r\nloading channels...\r\n found 139 channel(s)\r\nrun #1:\r\n [1/278] digiturk.com.tr (en) - AlJazeeraEnglish.qa - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/278] digiturk.com.tr (en) - AlJazeeraEnglish.qa - Dec 28, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/278] digiturk.com.tr (tr) - Yaban.tr - Dec 28, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/reactions',
+ total_count: 1,
+ '+1': 1,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2547/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2542',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2542',
+ id: 2759639980,
+ node_id: 'I_kwDOFLVvtM6kfMOs',
+ number: 2542,
+ title: 'tvguide.com not working',
+ user: {
+ login: 'SiWafer',
+ id: 10903014,
+ node_id: 'MDQ6VXNlcjEwOTAzMDE0',
+ avatar_url: 'https://avatars.githubusercontent.com/u/10903014?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/SiWafer',
+ html_url: 'https://github.com/SiWafer',
+ followers_url: 'https://api.github.com/users/SiWafer/followers',
+ following_url: 'https://api.github.com/users/SiWafer/following{/other_user}',
+ gists_url: 'https://api.github.com/users/SiWafer/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/SiWafer/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/SiWafer/subscriptions',
+ organizations_url: 'https://api.github.com/users/SiWafer/orgs',
+ repos_url: 'https://api.github.com/users/SiWafer/repos',
+ events_url: 'https://api.github.com/users/SiWafer/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/SiWafer/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-12-26T11:11:24Z',
+ updated_at: '2024-12-27T05:28:55Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\ntvguide.com\n\n### Description\n\n```\r\nepg@rpi:~/epg$ npm run grab --- --site=tvguide.com\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tvguide.com\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tvguide.com\r\nloading channels...\r\n found 39 channel(s)\r\nrun #1:\r\n [1/78] tvguide.com (en) - AEEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [2/78] tvguide.com (en) - AEEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [3/78] tvguide.com (en) - AMCEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [4/78] tvguide.com (en) - AMCEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [5/78] tvguide.com (en) - BravoEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [6/78] tvguide.com (en) - BravoEast.us - Dec 26, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [7/78] tvguide.com (en) - BBCAmericaEast.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [8/78] tvguide.com (en) - CNBC.us - Dec 27, 2024 (0 programs)\r\n ERR: Request failed with status code 403\r\n [9/78] tvguide.com (en) - CNBC.us - Dec 26, 2024 (0 programs)\r\n...\r\n...\r\n...\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2542/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2541',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2541',
+ id: 2758749907,
+ node_id: 'I_kwDOFLVvtM6kby7T',
+ number: 2541,
+ title: 'elcinema.com grab error 403',
+ user: {
+ login: 'xercessss',
+ id: 189765257,
+ node_id: 'U_kgDOC0-WiQ',
+ avatar_url: 'https://avatars.githubusercontent.com/u/189765257?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/xercessss',
+ html_url: 'https://github.com/xercessss',
+ followers_url: 'https://api.github.com/users/xercessss/followers',
+ following_url: 'https://api.github.com/users/xercessss/following{/other_user}',
+ gists_url: 'https://api.github.com/users/xercessss/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/xercessss/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/xercessss/subscriptions',
+ organizations_url: 'https://api.github.com/users/xercessss/orgs',
+ repos_url: 'https://api.github.com/users/xercessss/repos',
+ events_url: 'https://api.github.com/users/xercessss/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/xercessss/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-12-25T11:34:16Z',
+ updated_at: '2024-12-27T05:28:07Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\nelcinema.com\n\n### Description\n\ngrabbing elcinema.com epg return error 403 for both ar and en language:\r\nERR: Request failed with status code 403\r\n',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2541/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2509',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2509',
+ id: 2740938968,
+ node_id: 'I_kwDOFLVvtM6jX2jY',
+ number: 2509,
+ title: 'ssl problem maxtv.hrvatskitelekom.hr',
+ user: {
+ login: 'uploadkom',
+ id: 130712472,
+ node_id: 'U_kgDOB8qDmA',
+ avatar_url: 'https://avatars.githubusercontent.com/u/130712472?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/uploadkom',
+ html_url: 'https://github.com/uploadkom',
+ followers_url: 'https://api.github.com/users/uploadkom/followers',
+ following_url: 'https://api.github.com/users/uploadkom/following{/other_user}',
+ gists_url: 'https://api.github.com/users/uploadkom/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/uploadkom/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/uploadkom/subscriptions',
+ organizations_url: 'https://api.github.com/users/uploadkom/orgs',
+ repos_url: 'https://api.github.com/users/uploadkom/repos',
+ events_url: 'https://api.github.com/users/uploadkom/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/uploadkom/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 3,
+ created_at: '2024-12-15T22:21:22Z',
+ updated_at: '2024-12-27T05:26:26Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\nmaxtv.hrvatskitelekom.hr\n\n### Description\n\nssl problem',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2509/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2498',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2498',
+ id: 2728188494,
+ node_id: 'I_kwDOFLVvtM6inNpO',
+ number: 2498,
+ title: 'movistarplus.es',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-12-09T20:26:07Z',
+ updated_at: '2024-12-27T05:23:48Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nmovistarplus.es\n\n### Description\n\n```sh\r\nnpm run grab -- --site=movistarplus.es\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=movistarplus.es\r\n\r\n(node:22362) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:\r\n--import \'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("file%3A///Users/Arhey/Code/iptv-org/epg/node_modules/tsx/dist/loader.mjs", pathToFileURL("./"));\'\r\n(Use `node --trace-warnings ...` to show where the warning was created)\r\n(node:22362) UnsupportedWarning: `globalPreload` has been removed; use `initialize` instead.\r\n(Use `node --trace-warnings ...` to show where the warning was created)\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: movistarplus.es\r\nloading channels...\r\n(node:22362) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.\r\n found 186 channel(s)\r\nrun #1:\r\n [1/372] movistarplus.es (es) - ANTV - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/372] movistarplus.es (es) - ANTV - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/372] movistarplus.es (es) - ARAGTV - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [4/372] movistarplus.es (es) - CANSUR - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [5/372] movistarplus.es (es) - DAZNL2 - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [6/372] movistarplus.es (es) - MLIGS - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [7/372] movistarplus.es (es) - AMC.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [8/372] movistarplus.es (es) - ComediaporMovistarPlusPlus.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [9/372] movistarplus.es (es) - LasEstrellasEuropa.mx - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [10/372] movistarplus.es (es) - LasEstrellasEuropa.mx - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [11/372] movistarplus.es (es) - ComediaporMovistarPlusPlus.es - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [12/372] movistarplus.es (es) - LaResistencia.es - Dec 10, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [13/372] movistarplus.es (es) - LaResistencia.es - Dec 9, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2498/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2445',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2445',
+ id: 2567652015,
+ node_id: 'I_kwDOFLVvtM6ZC0Kv',
+ number: 2445,
+ title: 'EPG from dishtv.in stopped with error code 404',
+ user: {
+ login: 'dheer99',
+ id: 20639130,
+ node_id: 'MDQ6VXNlcjIwNjM5MTMw',
+ avatar_url: 'https://avatars.githubusercontent.com/u/20639130?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/dheer99',
+ html_url: 'https://github.com/dheer99',
+ followers_url: 'https://api.github.com/users/dheer99/followers',
+ following_url: 'https://api.github.com/users/dheer99/following{/other_user}',
+ gists_url: 'https://api.github.com/users/dheer99/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/dheer99/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/dheer99/subscriptions',
+ organizations_url: 'https://api.github.com/users/dheer99/orgs',
+ repos_url: 'https://api.github.com/users/dheer99/repos',
+ events_url: 'https://api.github.com/users/dheer99/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/dheer99/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 2,
+ created_at: '2024-10-05T04:30:52Z',
+ updated_at: '2024-12-27T05:20:11Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\ndishtv.in\n\n### Description\n\nEPG from dishtv.in stopped with error code 404\r\n\r\n [91/98] dishtv.in (en) - StarPlus.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [92/98] dishtv.in (en) - SET.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [93/98] dishtv.in (en) - ZeeCinema.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [94/98] dishtv.in (en) - SonySportsTen5.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [95/98] dishtv.in (en) - StarSports1.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [96/98] dishtv.in (en) - SET.in - Oct 5, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [97/98] dishtv.in (en) - SonySportsTen3.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n [98/98] dishtv.in (en) - Colors.in - Oct 6, 2024 (0 programs)\r\n ERR: Request failed with status code 404\r\n done in 00h 00m 03s\r\n',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2445/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2339',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2339/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2339',
+ id: 2172864415,
+ node_id: 'I_kwDOFLVvtM6Bg0ef',
+ number: 2339,
+ title:
+ 'directv.com.ar and directv.com.uy not working ERR: Unexpected token \'<\', " grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=kan.org.il --output=kan.org.il.xml\r\n\r\nstarting...\r\nconfig:\r\n output: kan.org.il.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: kan.org.il\r\nloading channels...\r\n found 3 channel(s)\r\nrun #1:\r\n [1/6] kan.org.il (ar) - Makan33.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [2/6] kan.org.il (ar) - Makan33.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [3/6] kan.org.il (he) - KanEducational.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [4/6] kan.org.il (he) - KanEducational.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [5/6] kan.org.il (he) - Kan11.il - Dec 3, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n [6/6] kan.org.il (he) - Kan11.il - Dec 2, 2023 (0 programs)\r\n ERR: Request failed with status code 404\r\n done in 00h 00m 01s\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2273/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2273/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2270',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2270',
+ id: 2022018570,
+ node_id: 'I_kwDOFLVvtM54hY4K',
+ number: 2270,
+ title: 'vivacom.bg is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-12-02T12:16:22Z',
+ updated_at: '2024-12-27T05:00:36Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nvivacom.bg\n\n### Description\n\n```sh\r\nnpm run grab -- --site=vivacom.bg\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=vivacom.bg\r\n\r\nstarting...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: vivacom.bg\r\nloading channels...\r\n found 154 channel(s)\r\nrun #1:\r\n [1/308] vivacom.bg (bg) - 24Kitchen.bg - Dec 2, 2023 (0 programs)\r\n [2/308] vivacom.bg (bg) - 24Kitchen.bg - Dec 3, 2023 (0 programs)\r\n [3/308] vivacom.bg (bg) - 78TV.bg - Dec 3, 2023 (0 programs)\r\n [4/308] vivacom.bg (bg) - AlfaTV.bg - Dec 3, 2023 (0 programs)\r\n [5/308] vivacom.bg (bg) - AXNEurope.gr - Dec 3, 2023 (0 programs)\r\n [6/308] vivacom.bg (bg) - BNT3.bg - Dec 3, 2023 (0 programs)\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2270/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2264',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2264',
+ id: 2019407629,
+ node_id: 'I_kwDOFLVvtM54XbcN',
+ number: 2264,
+ title: 'tva.tv is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-11-30T20:00:18Z',
+ updated_at: '2024-12-27T05:00:24Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ntva.tv\n\n### Description\n\n```sh\r\nnpm run grab -- --site=tva.tv\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tva.tv\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tva.tv\r\nloading channels...\r\n found 28 channel(s)\r\nrun #1:\r\n [1/56] tva.tv (fa) - DocTV.ir - Nov 30, 2023 (0 programs)\r\n ERR: Connection timeout\r\n [2/56] tva.tv (fa) - DocTV.ir - Dec 1, 2023 (0 programs)\r\n ERR: Connection timeout\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2264/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2263',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2263',
+ id: 2019376043,
+ node_id: 'I_kwDOFLVvtM54XTur',
+ number: 2263,
+ title: 'tv.yettel.hu is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-11-30T19:38:28Z',
+ updated_at: '2024-12-27T04:59:14Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ntv.yettel.hu\n\n### Description\n\n```sh\r\nnpm run grab -- --site=tv.yettel.hu\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=tv.yettel.hu\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: tv.yettel.hu\r\nloading channels...\r\n found 74 channel(s)\r\nrun #1:\r\n [1/148] tv.yettel.hu (en) - BBCNewsEurope.uk - Nov 30, 2023 (0 programs)\r\n ERR: Client network socket disconnected before secure TLS connection was established\r\n [2/148] tv.yettel.hu (en) - BBCNewsEurope.uk - Dec 1, 2023 (0 programs)\r\n ERR: Client network socket disconnected before secure TLS connection was established\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2263/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2257',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2257',
+ id: 2011054011,
+ node_id: 'I_kwDOFLVvtM533j-7',
+ number: 2257,
+ title: 'rtb.gov.bn is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-11-26T14:02:13Z',
+ updated_at: '2024-12-27T04:59:29Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nrtb.gov.bn\n\n### Description\n\n```sh\r\nnpm run grab -- --site=rtb.gov.bn\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=rtb.gov.bn\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: rtb.gov.bn\r\nloading channels...\r\n found 3 channel(s)\r\nrun #1:\r\n [1/6] rtb.gov.bn (ms) - RTBAneka.bn - Nov 26, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n [2/6] rtb.gov.bn (ms) - RTBAneka.bn - Nov 27, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n [3/6] rtb.gov.bn (ms) - RTBPerdana.bn - Nov 27, 2023 (0 programs)\r\n ERR: read ECONNRESET\r\n```\r\n\r\nThere is no link to the guide on the website at the moment either: https://www.rtb.gov.bn/SitePages/Programme%20Guide.aspx',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2257/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2255',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2255',
+ id: 2011043202,
+ node_id: 'I_kwDOFLVvtM533hWC',
+ number: 2255,
+ title: 'rev.bs is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2023-11-26T13:31:22Z',
+ updated_at: '2024-12-27T22:02:28Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nrev.bs\n\n### Description\n\n```sh\r\nnpm run grab -- --site=rev.bs\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=rev.bs\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: rev.bs\r\nloading channels...\r\n found 179 channel(s)\r\nrun #1:\r\n [1/358] rev.bs (en) - 3ABNEnglish.us - Nov 26, 2023 (0 programs)\r\n [2/358] rev.bs (en) - 3ABNEnglish.us - Nov 27, 2023 (0 programs)\r\n [3/358] rev.bs (en) - AEEast.us - Nov 27, 2023 (0 programs)\r\n [4/358] rev.bs (en) - AMCEast.us - Nov 27, 2023 (0 programs)\r\n```\r\n---\r\n\r\n```json\r\n{\r\n\t"status": "OK",\r\n\t"data": {\r\n\t\t"schedule": [],\r\n\t\t"dateTime": {\r\n\t\t\t"date": "2023-11-27",\r\n\t\t\t"page": 0\r\n\t\t},\r\n\t\t"runtimes": [\r\n\t\t\t{\r\n\t\t\t\t"Rev class loaded": 1700899490.604637\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"TVGuide Class Loaded": 1700899490.638891\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"Validated form": 1700899490.640116\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\t"Pulled schedules": 1700899490.642099\r\n\t\t\t}\r\n\t\t]\r\n\t}\r\n}\r\n```\r\n\r\nhttps://www.rev.bs/wp-content/uploads/tv-guide/2023-11-27_0.json\r\n\r\n---\r\n\r\n \r\n\r\nhttps://www.rev.bs/tv-guide-404/',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2255/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2241',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2241',
+ id: 2002096969,
+ node_id: 'I_kwDOFLVvtM53VZNJ',
+ number: 2241,
+ title: 'm.tv.sms.cz is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 4,
+ created_at: '2023-11-20T12:28:47Z',
+ updated_at: '2024-12-27T04:58:41Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nm.tv.sms.cz\n\n### Description\n\n```sh\r\nnpm run grab -- --site=m.tv.sms.cz\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=m.tv.sms.cz\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: m.tv.sms.cz\r\nloading channels...\r\n found 525 channel(s)\r\nrun #1:\r\n [1/1050] m.tv.sms.cz (bs) - BNTV.ba - Nov 20, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n\r\n [2/1050] m.tv.sms.cz (bs) - BNTV.ba - Nov 21, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n\r\n [3/1050] m.tv.sms.cz (cs) - AMC.cz - Nov 21, 2023 (0 programs)\r\n ERR: write EPROTO C04D101B01000000:error:0A000172:SSL routines:tls12_check_peer_sigalg:wrong signature type:ssl/t1_lib.c:1594:\r\n```\r\n\r\nhttps://check-host.net/check-report/135d7e05kb9d',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2241/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2240',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2240',
+ id: 2001847449,
+ node_id: 'I_kwDOFLVvtM53UcSZ',
+ number: 2240,
+ title: 'kplus.vn is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-11-20T10:19:23Z',
+ updated_at: '2024-12-27T04:57:49Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\nkplus.vn\n\n### Description\n\n```sh\r\nnpm run grab -- --site=kplus.vn\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=kplus.vn\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: kplus.vn\r\nloading channels...\r\n found 26 channel(s)\r\nrun #1:\r\n [1/52] kplus.vn (vi) - AsianFoodNetwork.sg - Nov 20, 2023 (0 programs)\r\n [2/52] kplus.vn (vi) - AsianFoodNetwork.sg - Nov 21, 2023 (0 programs)\r\n [3/52] kplus.vn (vi) - AXN.vn - Nov 21, 2023 (0 programs)\r\n [4/52] kplus.vn (vi) - DiscoveryChannelSoutheastAsia.sg - Nov 21, 2023 (0 programs)\r\n```\r\n\r\nThe site also currently does not display the guide:\r\n \r\nhttps://www.kplus.vn/highlights/broadcast-schedule',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2240/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2239',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2239',
+ id: 2000457187,
+ node_id: 'I_kwDOFLVvtM53PI3j',
+ number: 2239,
+ title: 'comteco.com.bo is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 3,
+ created_at: '2023-11-18T15:03:48Z',
+ updated_at: '2024-12-27T21:25:41Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ncomteco.com.bo\n\n### Description\n\n```sh\r\nnpm run grab -- --site=comteco.com.bo\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=comteco.com.bo\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: comteco.com.bo\r\nloading channels...\r\n found 72 channel(s)\r\nrun #1:\r\n [1/144] comteco.com.bo (es) - AbyaYalaTV.bo - Nov 18, 2023 (0 programs)\r\n [2/144] comteco.com.bo (es) - AbyaYalaTV.bo - Nov 19, 2023 (0 programs)\r\n [3/144] comteco.com.bo (es) - AEPanregional.us - Nov 19, 2023 (0 programs)\r\n [4/144] comteco.com.bo (es) - AnimalPlanetLatinAmerica.us - Nov 19, 2023 (0 programs)\r\n [5/144] comteco.com.bo (es) - BoliviaTV72.bo - Nov 19, 2023 (0 programs)\r\n```\r\n\r\nhttps://comteco.com.bo/pages/canales-y-programacion-tv/paquete-oro/ABYA%20YALA\r\n ',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2239/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2237',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2237',
+ id: 2000349577,
+ node_id: 'I_kwDOFLVvtM53OumJ',
+ number: 2237,
+ title: 'canalplus-haiti.com is broken',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2023-11-18T09:46:29Z',
+ updated_at: '2024-12-27T04:57:02Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ncanalplus-haiti.com\n\n### Description\n\n```sh\r\nnpm run grab -- --site=canalplus-haiti.com\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=canalplus-haiti.com\r\n\r\nstaring...\r\nconfig:\r\n output: guide.xml\r\n maxConnections: 1\r\n gzip: false\r\n site: canalplus-haiti.com\r\nloading channels...\r\n found 111 channel(s)\r\nrun #1:\r\n [1/222] canalplus-haiti.com (fr) - 13emeRue.fr - Nov 18, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [2/222] canalplus-haiti.com (fr) - 13emeRue.fr - Nov 19, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [3/222] canalplus-haiti.com (fr) - ZoukTV.mq - Nov 19, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n [4/222] canalplus-haiti.com (fr) - ZoukTV.mq - Nov 18, 2023 (0 programs)\r\n ERR: Request failed with status code 403\r\n```\r\n\r\nhttps://check-host.net/check-report/134fc56bk333',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2237/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2173',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2173',
+ id: 1903824500,
+ node_id: 'I_kwDOFLVvtM5xeg50',
+ number: 2173,
+ title: 'hd-plus.de - 0 programs on all channels',
+ user: {
+ login: 'x011',
+ id: 4313821,
+ node_id: 'MDQ6VXNlcjQzMTM4MjE=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/4313821?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/x011',
+ html_url: 'https://github.com/x011',
+ followers_url: 'https://api.github.com/users/x011/followers',
+ following_url: 'https://api.github.com/users/x011/following{/other_user}',
+ gists_url: 'https://api.github.com/users/x011/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/x011/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/x011/subscriptions',
+ organizations_url: 'https://api.github.com/users/x011/orgs',
+ repos_url: 'https://api.github.com/users/x011/repos',
+ events_url: 'https://api.github.com/users/x011/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/x011/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710795,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NOPiw',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:down',
+ name: 'status:down',
+ color: 'df3a4a',
+ default: false,
+ description: "The guide doesn't work"
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2023-09-19T22:45:56Z',
+ updated_at: '2024-12-27T04:54:11Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\r\n\r\nhd-plus.de\r\n\r\n### Description\r\n\r\nAll channels on hd-plus.de have 0 programs:\r\n```\r\n[1/60] hd-plus.de - 123tv.de - Sep 19, 2023 (0 programs)\r\n[2/60] hd-plus.de - 123tv.de - Sep 20, 2023 (0 programs)\r\n[3/60] hd-plus.de - ZDF.de - Sep 20, 2023 (0 programs)\r\n[4/60] hd-plus.de - ZDF.de - Sep 19, 2023 (0 programs)\r\n...\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/reactions',
+ total_count: 6,
+ '+1': 6,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2173/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ }
+]
diff --git a/tests/__data__/input/issues/broken_guide_warning.js b/tests/__data__/input/issues/broken_guide_warning.mjs
similarity index 98%
rename from tests/__data__/input/issues/broken_guide_warning.js
rename to tests/__data__/input/issues/broken_guide_warning.mjs
index e7f3bcfa..d8828b90 100644
--- a/tests/__data__/input/issues/broken_guide_warning.js
+++ b/tests/__data__/input/issues/broken_guide_warning.mjs
@@ -1,974 +1,974 @@
-module.exports = [
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2543',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2543',
- id: 2759693796,
- node_id: 'I_kwDOFLVvtM6kfZXk',
- number: 2543,
- title: 'flixed.io is downloding old programming',
- user: {
- login: 'SiWafer',
- id: 10903014,
- node_id: 'MDQ6VXNlcjEwOTAzMDE0',
- avatar_url: 'https://avatars.githubusercontent.com/u/10903014?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/SiWafer',
- html_url: 'https://github.com/SiWafer',
- followers_url: 'https://api.github.com/users/SiWafer/followers',
- following_url: 'https://api.github.com/users/SiWafer/following{/other_user}',
- gists_url: 'https://api.github.com/users/SiWafer/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/SiWafer/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/SiWafer/subscriptions',
- organizations_url: 'https://api.github.com/users/SiWafer/orgs',
- repos_url: 'https://api.github.com/users/SiWafer/repos',
- events_url: 'https://api.github.com/users/SiWafer/events{/privacy}',
- received_events_url: 'https://api.github.com/users/SiWafer/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-12-26T12:09:43Z',
- updated_at: '2024-12-27T05:29:58Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Describe your issue\r\n\r\nJust ran and updated, and seems the output is loading old programming and it also is not complete\r\n\r\nExample is Bravo channel\r\n\r\n```\r\nepg@rpi:~/epg$ npm run grab --- --site=flixed.io --maxConnections=10 -o "flixed.xml"\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=flixed.io --maxConnections=10 -o flixed.xml\r\n\r\nstarting...\r\nconfig:\r\n output: flixed.xml\r\n maxConnections: 10\r\n gzip: false\r\n site: flixed.io\r\nloading channels...\r\n found 94 channel(s)\r\nrun #1:\r\n [1/94] flixed.io (en) - BravoEast.us - Dec 26, 2024 (2 programs)\r\n [2/94] flixed.io (en) - ComedyCentralEast.us - Dec 26, 2024 (5 programs)\r\n [3/94] flixed.io (en) - ACCNetwork.us - Dec 26, 2024 (26 programs)\r\n [4/94] flixed.io (en) - CNN.us - Dec 26, 2024 (25 programs)\r\n [5/94] flixed.io (en) - BloombergTV.us - Dec 26, 2024 (21 programs)\r\n [6/94] flixed.io (en) - AEEast.us - Dec 26, 2024 (6 programs)\r\n [7/94] flixed.io (en) - CNBC.us - Dec 26, 2024 (3 programs)\r\n [8/94] flixed.io (en) - CinemaxEast.us - Dec 26, 2024 (14 programs)\r\n [9/94] flixed.io (en) - AMCEast.us - Dec 26, 2024 (19 programs)\r\n [10/94] flixed.io (en) - BigTenNetwork.us - Dec 26, 2024 (3 programs)\r\n [11/94] flixed.io (en) - FoxWest.us - Dec 26, 2024 (8 programs)\r\n [12/94] flixed.io (en) - FreeformEast.us - Dec 26, 2024 (2 programs)\r\n [13/94] flixed.io (en) - FoxSports2.us - Dec 26, 2024 (2 programs)\r\n [14/94] flixed.io (en) - FoodNetworkEast.us - Dec 26, 2024 (3 programs)\r\n...\r\n...\r\n...\r\n\r\n```\r\nSnip from xml file out\r\n\r\n\r\nThe date is September 26, 2024, 01:00:00 for Bravo\r\n\r\n',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2516',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2516',
- id: 2745387354,
- node_id: 'I_kwDOFLVvtM6jo0la',
- number: 2516,
- title: 'Duplicate programmes with sky.com grab',
- user: {
- login: 'misar1',
- id: 69795879,
- node_id: 'MDQ6VXNlcjY5Nzk1ODc5',
- avatar_url: 'https://avatars.githubusercontent.com/u/69795879?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/misar1',
- html_url: 'https://github.com/misar1',
- followers_url: 'https://api.github.com/users/misar1/followers',
- following_url: 'https://api.github.com/users/misar1/following{/other_user}',
- gists_url: 'https://api.github.com/users/misar1/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/misar1/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/misar1/subscriptions',
- organizations_url: 'https://api.github.com/users/misar1/orgs',
- repos_url: 'https://api.github.com/users/misar1/repos',
- events_url: 'https://api.github.com/users/misar1/events{/privacy}',
- received_events_url: 'https://api.github.com/users/misar1/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2024-12-17T16:19:36Z',
- updated_at: '2024-12-27T05:27:44Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\nsky.com\n\n### Description\n\n\r\nI changed to the recently updated sky.com script a couple of days ago (using a completely new install as in the readme) and have found an anomaly. This does not occur with an identical grab using my previous installation. The grabs are for about 60 UK FTA channels which I can list if it would be helpful.\r\n\r\nA number of programmes have two identical blocks in the XML, including their start and finish times. This occurs only from around approximately 22:00 each day and up to about midnight GMT. During this period most channels are affected and it is consistent between successive grabs. In case of a timing issue I tested delays of 100, 1000, 3000 and 5000 msec but the XML was unchanged.',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2501',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2501',
- id: 2738899005,
- node_id: 'I_kwDOFLVvtM6jQEg9',
- number: 2501,
- title: 'Sky.com',
- user: {
- login: 'Chris230291',
- id: 5328818,
- node_id: 'MDQ6VXNlcjUzMjg4MTg=',
- avatar_url: 'https://avatars.githubusercontent.com/u/5328818?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/Chris230291',
- html_url: 'https://github.com/Chris230291',
- followers_url: 'https://api.github.com/users/Chris230291/followers',
- following_url: 'https://api.github.com/users/Chris230291/following{/other_user}',
- gists_url: 'https://api.github.com/users/Chris230291/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/Chris230291/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/Chris230291/subscriptions',
- organizations_url: 'https://api.github.com/users/Chris230291/orgs',
- repos_url: 'https://api.github.com/users/Chris230291/repos',
- events_url: 'https://api.github.com/users/Chris230291/events{/privacy}',
- received_events_url: 'https://api.github.com/users/Chris230291/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 2,
- created_at: '2024-12-13T17:45:02Z',
- updated_at: '2024-12-27T05:25:49Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\nsky.com\n\n### Description\n\n```\r\n Viaplay 1 HD \r\n Viaplay 2 HD \r\n```\r\n\r\nThese should be "Premier Sports 1 HD" and "Premier Sports 2 HD".\r\nAlso, the UK and ROI have different schedules for these 2 channels.',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2446',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2446',
- id: 2568624116,
- node_id: 'I_kwDOFLVvtM6ZGhf0',
- number: 2446,
- title: 'Eleven channels returning 0 programs on meo.pt',
- user: {
- login: 'jonatasgz',
- id: 78122211,
- node_id: 'MDQ6VXNlcjc4MTIyMjEx',
- avatar_url: 'https://avatars.githubusercontent.com/u/78122211?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/jonatasgz',
- html_url: 'https://github.com/jonatasgz',
- followers_url: 'https://api.github.com/users/jonatasgz/followers',
- following_url: 'https://api.github.com/users/jonatasgz/following{/other_user}',
- gists_url: 'https://api.github.com/users/jonatasgz/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/jonatasgz/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/jonatasgz/subscriptions',
- organizations_url: 'https://api.github.com/users/jonatasgz/orgs',
- repos_url: 'https://api.github.com/users/jonatasgz/repos',
- events_url: 'https://api.github.com/users/jonatasgz/events{/privacy}',
- received_events_url: 'https://api.github.com/users/jonatasgz/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 2,
- created_at: '2024-10-06T12:00:48Z',
- updated_at: '2024-12-27T05:23:16Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\n\nmeo.pt\n\n### Description\n\nEleven (DAZN) channels return 0 programs.',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2400',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2400',
- id: 2370209498,
- node_id: 'I_kwDOFLVvtM6NRoba',
- number: 2400,
- title: 'tvgids.nl',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-06-24T13:05:05Z',
- updated_at: '2024-12-27T05:19:25Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: "### Site\n\ntvgids.nl\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- tvgids.nl \r\n\r\n> test\r\n> run-script-os tvgids.nl\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand tvgids.nl\r\n\r\n FAIL sites/tvgids.nl/tvgids.nl.test.js\r\n ✓ can generate valid url (29 ms)\r\n ✕ can generate valid url for today (4 ms)\r\n ✓ can parse response (307 ms)\r\n ✓ can handle empty guide (3 ms)\r\n\r\n ● can generate valid url for today\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: \"https://www.tvgids.nl/gids/npo1\"\r\n Received: \"https://www.tvgids.nl/gids/25-06-2024/npo1\"\r\n\r\n 21 | const today = dayjs().startOf('d')\r\n 22 |\r\n > 23 | expect(url({ date: today, channel })).toBe('https://www.tvgids.nl/gids/npo1')\r\n | ^\r\n 24 | })\r\n 25 |\r\n 26 | it('can parse response', () => {\r\n\r\n at Object. (sites/tvgids.nl/tvgids.nl.test.js:23:41)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 3 passed, 4 total\r\nSnapshots: 0 total\r\nTime: 3.52 s\r\nRan all test suites matching /tvgids.nl/i.\r\n```",
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2399',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2399',
- id: 2370207356,
- node_id: 'I_kwDOFLVvtM6NRn58',
- number: 2399,
- title: 'tvprofil.com',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2024-06-24T13:04:08Z',
- updated_at: '2024-12-27T05:18:50Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\ntvprofil.com\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- tvprofil.com\r\n\r\n> test\r\n> run-script-os tvprofil.com\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand tvprofil.com\r\n\r\n FAIL sites/tvprofil.com/tvprofil.com.test.js\r\n ✕ can generate valid url (14 ms)\r\n ✓ can generate valid request headers (1 ms)\r\n ✓ can parse response (76 ms)\r\n ✓ can handle empty guide (2 ms)\r\n\r\n ● can generate valid url\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: "https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b51=818933"\r\n Received: "https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b49=819461"\r\n\r\n 15 |\r\n 16 | it(\'can generate valid url\', () => {\r\n > 17 | expect(url({ channel, date })).toBe(\r\n | ^\r\n 18 | \'https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b51=818933\'\r\n 19 | )\r\n 20 | })\r\n\r\n at Object. (sites/tvprofil.com/tvprofil.com.test.js:17:34)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 3 passed, 4 total\r\nSnapshots: 0 total\r\nTime: 3.307 s\r\nRan all test suites matching /tvprofil.com/i.\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2396',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2396',
- id: 2370189473,
- node_id: 'I_kwDOFLVvtM6NRjih',
- number: 2396,
- title: 'iltalehti.fi',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-06-24T12:56:45Z',
- updated_at: '2024-12-27T05:18:16Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\n\niltalehti.fi\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- iltalehti.fi \r\n\r\n> test\r\n> run-script-os iltalehti.fi\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand iltalehti.fi\r\n\r\n FAIL sites/iltalehti.fi/iltalehti.fi.test.js\r\n ✕ can generate valid url (10 ms)\r\n ✓ can parse response (28 ms)\r\n ✓ can handle empty guide (1 ms)\r\n\r\n ● can generate valid url\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: "https://telkku.com/api/channel-groups/default_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails"\r\n Received: "https://telkku.com/api/channel-groups/default_builtin_channelgroupdefault_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails"\r\n\r\n 15 |\r\n 16 | it(\'can generate valid url\', () => {\r\n > 17 | expect(url({ channel, date })).toBe(\r\n | ^\r\n 18 | \'https://telkku.com/api/channel-groups/default_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails\'\r\n 19 | )\r\n 20 | })\r\n\r\n at Object. (sites/iltalehti.fi/iltalehti.fi.test.js:17:34)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 2 passed, 3 total\r\nSnapshots: 0 total\r\nTime: 3.193 s\r\nRan all test suites matching /iltalehti.fi/i.\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2395',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2395',
- id: 2370186157,
- node_id: 'I_kwDOFLVvtM6NRiut',
- number: 2395,
- title: 'chaines-tv.orange.fr',
- user: {
- login: 'freearhey',
- id: 7253922,
- node_id: 'MDQ6VXNlcjcyNTM5MjI=',
- avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/freearhey',
- html_url: 'https://github.com/freearhey',
- followers_url: 'https://api.github.com/users/freearhey/followers',
- following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
- gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
- organizations_url: 'https://api.github.com/users/freearhey/orgs',
- repos_url: 'https://api.github.com/users/freearhey/repos',
- events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
- received_events_url: 'https://api.github.com/users/freearhey/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 2,
- created_at: '2024-06-24T12:55:21Z',
- updated_at: '2024-12-27T05:17:25Z',
- closed_at: null,
- author_association: 'COLLABORATOR',
- active_lock_reason: null,
- body: '### Site\r\n\r\nchaines-tv.orange.fr\r\n\r\n### Description\r\n\r\nTest failed:\r\n\r\n```sh\r\nnpm test -- chaines-tv.orange.fr\r\n\r\n> test\r\n> run-script-os chaines-tv.orange.fr\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand chaines-tv.orange.fr\r\n\r\n FAIL sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js\r\n ✓ can generate valid url (5 ms)\r\n ✕ can parse response (12 ms)\r\n ✓ can handle empty guide (1 ms)\r\n\r\n ● can parse response\r\n\r\n expect(received).toMatchObject(expected)\r\n\r\n - Expected - 1\r\n + Received + 1\r\n\r\n @@ -3,8 +3,8 @@\r\n "category": "Série Suspense",\r\n "description": "Un tueur en série prend un plaisir pervers à prévenir les autorités de Tallahassee avant chaque nouveau meurtre. Rossi apprend le décès d\'un de ses vieux amis.",\r\n "icon": "https://proxymedia.woopic.com/340/p/169_EMI_9697669.jpg",\r\n "start": "2021-11-07T23:35:00.000Z",\r\n "stop": "2021-11-08T00:20:00.000Z",\r\n - "title": "Tête de liste",\r\n + "title": "Esprits criminels",\r\n },\r\n ]\r\n\r\n 23 | it(\'can parse response\', () => {\r\n 24 | const result = parser({ date, channel, content })\r\n > 25 | expect(result).toMatchObject([\r\n | ^\r\n 26 | {\r\n 27 | start: \'2021-11-07T23:35:00.000Z\',\r\n 28 | stop: \'2021-11-08T00:20:00.000Z\',\r\n\r\n at Object. (sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js:25:18)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 2 passed, 3 total\r\nSnapshots: 0 total\r\nTime: 4.003 s\r\nRan all test suites matching /chaines-tv.orange.fr/i.\r\n```',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2304',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2304',
- id: 2064638324,
- node_id: 'I_kwDOFLVvtM57D-F0',
- number: 2304,
- title: 'digiturk.com.tr Missing Channel Identifications',
- user: {
- login: 'UzunMuhalefet',
- id: 80906858,
- node_id: 'MDQ6VXNlcjgwOTA2ODU4',
- avatar_url: 'https://avatars.githubusercontent.com/u/80906858?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/UzunMuhalefet',
- html_url: 'https://github.com/UzunMuhalefet',
- followers_url: 'https://api.github.com/users/UzunMuhalefet/followers',
- following_url: 'https://api.github.com/users/UzunMuhalefet/following{/other_user}',
- gists_url: 'https://api.github.com/users/UzunMuhalefet/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/UzunMuhalefet/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/UzunMuhalefet/subscriptions',
- organizations_url: 'https://api.github.com/users/UzunMuhalefet/orgs',
- repos_url: 'https://api.github.com/users/UzunMuhalefet/repos',
- events_url: 'https://api.github.com/users/UzunMuhalefet/events{/privacy}',
- received_events_url: 'https://api.github.com/users/UzunMuhalefet/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 0,
- created_at: '2024-01-03T20:57:58Z',
- updated_at: '2024-12-27T05:32:37Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\r\n\r\ndigiturk.com.tr\r\n\r\n### Describe your issue\r\n\r\nThe following channels can be corrected as follows. (I added the TVG-IDs if they exist in https://iptv-org.github.io/)\r\n\r\n```\r\nKANAL 24 HD \r\nTARIH TV HD \r\nSÖZCÜ TV HD \r\n```\r\n\r\nLet me clarify the cases:\r\n- SZC changed its name to Sözcü TV\r\n- 24 TV often called as Kanal (Channel) 24\r\n- Tarih TV is straightforward.\r\n',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2303',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2303',
- id: 2064633657,
- node_id: 'I_kwDOFLVvtM57D885',
- number: 2303,
- title: 'dsmart.com.tr Channel Identifications',
- user: {
- login: 'UzunMuhalefet',
- id: 80906858,
- node_id: 'MDQ6VXNlcjgwOTA2ODU4',
- avatar_url: 'https://avatars.githubusercontent.com/u/80906858?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/UzunMuhalefet',
- html_url: 'https://github.com/UzunMuhalefet',
- followers_url: 'https://api.github.com/users/UzunMuhalefet/followers',
- following_url: 'https://api.github.com/users/UzunMuhalefet/following{/other_user}',
- gists_url: 'https://api.github.com/users/UzunMuhalefet/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/UzunMuhalefet/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/UzunMuhalefet/subscriptions',
- organizations_url: 'https://api.github.com/users/UzunMuhalefet/orgs',
- repos_url: 'https://api.github.com/users/UzunMuhalefet/repos',
- events_url: 'https://api.github.com/users/UzunMuhalefet/events{/privacy}',
- received_events_url: 'https://api.github.com/users/UzunMuhalefet/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 1,
- created_at: '2024-01-03T20:53:34Z',
- updated_at: '2024-12-27T05:44:16Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Describe your issue\r\n\r\nThe following channels can be corrected as follows. (I added the TVG-IDs if they exist in https://iptv-org.github.io/)\r\n\r\n```\r\nNR1 \r\nNR1 Türk \r\nTRT EBA TV İlkokul \r\nTRT EBA TV Ortaokul \r\nTRT EBA TV Lise \r\nÇifçi TV \r\nKanal 16 \r\nFlash Haber \r\nYeni Kocaeli TV \r\nATV Turkiye SD \r\nTRT EBA TV İlkokul SD \r\nTRT EBA TV Ortaokul SD \r\nTRT EBA TV Lise SD \r\nTarih Tv \r\nSZC \r\nTRT 3 Spor \r\n``` \r\n\r\nLet me clarify the cases: \r\n\r\n- NR1 stands for Number One\r\n- Cifci TV - Çiftçi TV - misspelling\r\n- The number 16 is spelled as onaltı (on -> 10, altı->6, on6 -> 16) in Turkish so on6 - Kanal 16\r\n- Flash TV changed its name to Flash Haber TV\r\n- SZC changed its name to Sözcü TV\r\n- TRT 3 is a strange channel that usually streams the same content as TRT Spor but when there is a Turkish parliament event it switches to that event. So, the channel is both called TRT 3 and TRT 3 Spor.\r\n',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2272',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2272',
- id: 2022135766,
- node_id: 'I_kwDOFLVvtM54h1fW',
- number: 2272,
- title: 'Film titles with numbers only in the title (as in "1900" or "1917") don\'t show up',
- user: {
- login: 'GlamoramaAttack',
- id: 116585465,
- node_id: 'U_kgDOBvLz-Q',
- avatar_url: 'https://avatars.githubusercontent.com/u/116585465?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/GlamoramaAttack',
- html_url: 'https://github.com/GlamoramaAttack',
- followers_url: 'https://api.github.com/users/GlamoramaAttack/followers',
- following_url: 'https://api.github.com/users/GlamoramaAttack/following{/other_user}',
- gists_url: 'https://api.github.com/users/GlamoramaAttack/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/GlamoramaAttack/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/GlamoramaAttack/subscriptions',
- organizations_url: 'https://api.github.com/users/GlamoramaAttack/orgs',
- repos_url: 'https://api.github.com/users/GlamoramaAttack/repos',
- events_url: 'https://api.github.com/users/GlamoramaAttack/events{/privacy}',
- received_events_url: 'https://api.github.com/users/GlamoramaAttack/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 2,
- created_at: '2023-12-02T17:29:50Z',
- updated_at: '2024-12-27T05:02:05Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\r\n\r\ntvpassport.com\r\n\r\n### Describe your issue\r\n\r\nFilm titles with numbers only in the title -as in "1900" or "1917"- don\'t show up at all.\r\n\r\nSorry, I don\'t understand anything about how to write a script or fix it but I see there is notable difference in the **guide.xml** file - the examples are excerpts from tvpassport.com. This isn\'t a new bug I think, it\'s just that I thought for a long time it\'s a Kodi problem before looking into the guide.xml file...\r\n\r\n```\r\nchannel="Showtime2East.us">The Caine Mutiny Court-Martial A \r\nchannel="Showtime2East.us">Two British soldiers receive seemingly impossible orders \r\nchannel="Showtime2East.us">There Will Be Blood Daniel \r\n```\r\nor:\r\n\r\n```\r\nchannel="MGMPlusEast.us">A Fistful of Dynamite A thief \r\nchannel="MGMPlusEast.us">The son (Robert De Niro) of a landowner and the son \r\nchannel="MGMPlusEast.us">Indecent Proposal A Las Vegas \r\n```\r\n\r\nFor some reason "title lang" gets replaced by "desc lang" and the film title is nowhere displayed.\r\n\r\nOn Kodi it looks like this for the films and you can also see it\'s not a problem if the film title includes more than numbers (see "88 Minutes" or "Resistance: 1942"). But titles as "1900", "1917" or "1408" (Horror with John Cusack) appear blank.\r\n\r\n\r\n\r\nI\'m not sure whether the problem also exists with other sources than tvpassport.com because I use only two other (German language) EPG sources that have currently no film titles with numbers only. But I assume it\'s a bug if it\'s not reduced to tvpassport.',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/timeline',
- performed_via_github_app: null,
- state_reason: null
- },
- {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2176',
- repository_url: 'https://api.github.com/repos/iptv-org/epg',
- labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/labels{/name}',
- comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/comments',
- events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/events',
- html_url: 'https://github.com/iptv-org/epg/issues/2176',
- id: 1915947653,
- node_id: 'I_kwDOFLVvtM5yMwqF',
- number: 2176,
- title: 'tvtv',
- user: {
- login: 'jvdillon',
- id: 1137078,
- node_id: 'MDQ6VXNlcjExMzcwNzg=',
- avatar_url: 'https://avatars.githubusercontent.com/u/1137078?v=4',
- gravatar_id: '',
- url: 'https://api.github.com/users/jvdillon',
- html_url: 'https://github.com/jvdillon',
- followers_url: 'https://api.github.com/users/jvdillon/followers',
- following_url: 'https://api.github.com/users/jvdillon/following{/other_user}',
- gists_url: 'https://api.github.com/users/jvdillon/gists{/gist_id}',
- starred_url: 'https://api.github.com/users/jvdillon/starred{/owner}{/repo}',
- subscriptions_url: 'https://api.github.com/users/jvdillon/subscriptions',
- organizations_url: 'https://api.github.com/users/jvdillon/orgs',
- repos_url: 'https://api.github.com/users/jvdillon/repos',
- events_url: 'https://api.github.com/users/jvdillon/events{/privacy}',
- received_events_url: 'https://api.github.com/users/jvdillon/received_events',
- type: 'User',
- user_view_type: 'public',
- site_admin: false
- },
- labels: [
- {
- id: 4542348869,
- node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
- name: 'broken guide',
- color: 'eaeaea',
- default: false,
- description: "There's a problem with the guide"
- },
- {
- id: 7932710318,
- node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
- url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
- name: 'status:warning',
- color: 'fbca06',
- default: false,
- description: 'The guide downloads, but contains errors'
- }
- ],
- state: 'open',
- locked: false,
- assignee: null,
- assignees: [],
- milestone: null,
- comments: 6,
- created_at: '2023-09-27T16:34:00Z',
- updated_at: '2024-12-27T04:55:00Z',
- closed_at: null,
- author_association: 'NONE',
- active_lock_reason: null,
- body: '### Site\r\n\r\ntvtv.us\r\n\r\n### Description\r\n\r\nStarts getting error 429 after several 100 scrapes. I tried setting the delay to 1000ms, 1500ms, and 2000ms but keep seeing the issue.\r\n\r\nIt almost appears to happen after a sequence of 0 program scrapes. I wonder if the delay is not happening when nothing is downloaded which causes tvtv.us to throttle which triggers 0 programs downloaded. (Ie a feedback loop)',
- closed_by: null,
- reactions: {
- url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/reactions',
- total_count: 0,
- '+1': 0,
- '-1': 0,
- laugh: 0,
- hooray: 0,
- confused: 0,
- heart: 0,
- rocket: 0,
- eyes: 0
- },
- timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/timeline',
- performed_via_github_app: null,
- state_reason: null
- }
-]
+export default [
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2543',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2543',
+ id: 2759693796,
+ node_id: 'I_kwDOFLVvtM6kfZXk',
+ number: 2543,
+ title: 'flixed.io is downloding old programming',
+ user: {
+ login: 'SiWafer',
+ id: 10903014,
+ node_id: 'MDQ6VXNlcjEwOTAzMDE0',
+ avatar_url: 'https://avatars.githubusercontent.com/u/10903014?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/SiWafer',
+ html_url: 'https://github.com/SiWafer',
+ followers_url: 'https://api.github.com/users/SiWafer/followers',
+ following_url: 'https://api.github.com/users/SiWafer/following{/other_user}',
+ gists_url: 'https://api.github.com/users/SiWafer/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/SiWafer/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/SiWafer/subscriptions',
+ organizations_url: 'https://api.github.com/users/SiWafer/orgs',
+ repos_url: 'https://api.github.com/users/SiWafer/repos',
+ events_url: 'https://api.github.com/users/SiWafer/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/SiWafer/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-12-26T12:09:43Z',
+ updated_at: '2024-12-27T05:29:58Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Describe your issue\r\n\r\nJust ran and updated, and seems the output is loading old programming and it also is not complete\r\n\r\nExample is Bravo channel\r\n\r\n```\r\nepg@rpi:~/epg$ npm run grab --- --site=flixed.io --maxConnections=10 -o "flixed.xml"\r\n\r\n> grab\r\n> npx tsx scripts/commands/epg/grab.ts --site=flixed.io --maxConnections=10 -o flixed.xml\r\n\r\nstarting...\r\nconfig:\r\n output: flixed.xml\r\n maxConnections: 10\r\n gzip: false\r\n site: flixed.io\r\nloading channels...\r\n found 94 channel(s)\r\nrun #1:\r\n [1/94] flixed.io (en) - BravoEast.us - Dec 26, 2024 (2 programs)\r\n [2/94] flixed.io (en) - ComedyCentralEast.us - Dec 26, 2024 (5 programs)\r\n [3/94] flixed.io (en) - ACCNetwork.us - Dec 26, 2024 (26 programs)\r\n [4/94] flixed.io (en) - CNN.us - Dec 26, 2024 (25 programs)\r\n [5/94] flixed.io (en) - BloombergTV.us - Dec 26, 2024 (21 programs)\r\n [6/94] flixed.io (en) - AEEast.us - Dec 26, 2024 (6 programs)\r\n [7/94] flixed.io (en) - CNBC.us - Dec 26, 2024 (3 programs)\r\n [8/94] flixed.io (en) - CinemaxEast.us - Dec 26, 2024 (14 programs)\r\n [9/94] flixed.io (en) - AMCEast.us - Dec 26, 2024 (19 programs)\r\n [10/94] flixed.io (en) - BigTenNetwork.us - Dec 26, 2024 (3 programs)\r\n [11/94] flixed.io (en) - FoxWest.us - Dec 26, 2024 (8 programs)\r\n [12/94] flixed.io (en) - FreeformEast.us - Dec 26, 2024 (2 programs)\r\n [13/94] flixed.io (en) - FoxSports2.us - Dec 26, 2024 (2 programs)\r\n [14/94] flixed.io (en) - FoodNetworkEast.us - Dec 26, 2024 (3 programs)\r\n...\r\n...\r\n...\r\n\r\n```\r\nSnip from xml file out\r\n\r\n\r\nThe date is September 26, 2024, 01:00:00 for Bravo\r\n\r\n',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2543/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2516',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2516',
+ id: 2745387354,
+ node_id: 'I_kwDOFLVvtM6jo0la',
+ number: 2516,
+ title: 'Duplicate programmes with sky.com grab',
+ user: {
+ login: 'misar1',
+ id: 69795879,
+ node_id: 'MDQ6VXNlcjY5Nzk1ODc5',
+ avatar_url: 'https://avatars.githubusercontent.com/u/69795879?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/misar1',
+ html_url: 'https://github.com/misar1',
+ followers_url: 'https://api.github.com/users/misar1/followers',
+ following_url: 'https://api.github.com/users/misar1/following{/other_user}',
+ gists_url: 'https://api.github.com/users/misar1/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/misar1/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/misar1/subscriptions',
+ organizations_url: 'https://api.github.com/users/misar1/orgs',
+ repos_url: 'https://api.github.com/users/misar1/repos',
+ events_url: 'https://api.github.com/users/misar1/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/misar1/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2024-12-17T16:19:36Z',
+ updated_at: '2024-12-27T05:27:44Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\nsky.com\n\n### Description\n\n\r\nI changed to the recently updated sky.com script a couple of days ago (using a completely new install as in the readme) and have found an anomaly. This does not occur with an identical grab using my previous installation. The grabs are for about 60 UK FTA channels which I can list if it would be helpful.\r\n\r\nA number of programmes have two identical blocks in the XML, including their start and finish times. This occurs only from around approximately 22:00 each day and up to about midnight GMT. During this period most channels are affected and it is consistent between successive grabs. In case of a timing issue I tested delays of 100, 1000, 3000 and 5000 msec but the XML was unchanged.',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2516/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2501',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2501',
+ id: 2738899005,
+ node_id: 'I_kwDOFLVvtM6jQEg9',
+ number: 2501,
+ title: 'Sky.com',
+ user: {
+ login: 'Chris230291',
+ id: 5328818,
+ node_id: 'MDQ6VXNlcjUzMjg4MTg=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/5328818?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/Chris230291',
+ html_url: 'https://github.com/Chris230291',
+ followers_url: 'https://api.github.com/users/Chris230291/followers',
+ following_url: 'https://api.github.com/users/Chris230291/following{/other_user}',
+ gists_url: 'https://api.github.com/users/Chris230291/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/Chris230291/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/Chris230291/subscriptions',
+ organizations_url: 'https://api.github.com/users/Chris230291/orgs',
+ repos_url: 'https://api.github.com/users/Chris230291/repos',
+ events_url: 'https://api.github.com/users/Chris230291/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/Chris230291/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 2,
+ created_at: '2024-12-13T17:45:02Z',
+ updated_at: '2024-12-27T05:25:49Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\nsky.com\n\n### Description\n\n```\r\n Viaplay 1 HD \r\n Viaplay 2 HD \r\n```\r\n\r\nThese should be "Premier Sports 1 HD" and "Premier Sports 2 HD".\r\nAlso, the UK and ROI have different schedules for these 2 channels.',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2501/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2446',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2446',
+ id: 2568624116,
+ node_id: 'I_kwDOFLVvtM6ZGhf0',
+ number: 2446,
+ title: 'Eleven channels returning 0 programs on meo.pt',
+ user: {
+ login: 'jonatasgz',
+ id: 78122211,
+ node_id: 'MDQ6VXNlcjc4MTIyMjEx',
+ avatar_url: 'https://avatars.githubusercontent.com/u/78122211?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/jonatasgz',
+ html_url: 'https://github.com/jonatasgz',
+ followers_url: 'https://api.github.com/users/jonatasgz/followers',
+ following_url: 'https://api.github.com/users/jonatasgz/following{/other_user}',
+ gists_url: 'https://api.github.com/users/jonatasgz/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/jonatasgz/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/jonatasgz/subscriptions',
+ organizations_url: 'https://api.github.com/users/jonatasgz/orgs',
+ repos_url: 'https://api.github.com/users/jonatasgz/repos',
+ events_url: 'https://api.github.com/users/jonatasgz/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/jonatasgz/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 2,
+ created_at: '2024-10-06T12:00:48Z',
+ updated_at: '2024-12-27T05:23:16Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\n\nmeo.pt\n\n### Description\n\nEleven (DAZN) channels return 0 programs.',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2446/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2400',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2400',
+ id: 2370209498,
+ node_id: 'I_kwDOFLVvtM6NRoba',
+ number: 2400,
+ title: 'tvgids.nl',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-06-24T13:05:05Z',
+ updated_at: '2024-12-27T05:19:25Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: "### Site\n\ntvgids.nl\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- tvgids.nl \r\n\r\n> test\r\n> run-script-os tvgids.nl\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand tvgids.nl\r\n\r\n FAIL sites/tvgids.nl/tvgids.nl.test.js\r\n ✓ can generate valid url (29 ms)\r\n ✕ can generate valid url for today (4 ms)\r\n ✓ can parse response (307 ms)\r\n ✓ can handle empty guide (3 ms)\r\n\r\n ● can generate valid url for today\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: \"https://www.tvgids.nl/gids/npo1\"\r\n Received: \"https://www.tvgids.nl/gids/25-06-2024/npo1\"\r\n\r\n 21 | const today = dayjs().startOf('d')\r\n 22 |\r\n > 23 | expect(url({ date: today, channel })).toBe('https://www.tvgids.nl/gids/npo1')\r\n | ^\r\n 24 | })\r\n 25 |\r\n 26 | it('can parse response', () => {\r\n\r\n at Object. (sites/tvgids.nl/tvgids.nl.test.js:23:41)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 3 passed, 4 total\r\nSnapshots: 0 total\r\nTime: 3.52 s\r\nRan all test suites matching /tvgids.nl/i.\r\n```",
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2400/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2399',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2399',
+ id: 2370207356,
+ node_id: 'I_kwDOFLVvtM6NRn58',
+ number: 2399,
+ title: 'tvprofil.com',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2024-06-24T13:04:08Z',
+ updated_at: '2024-12-27T05:18:50Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\ntvprofil.com\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- tvprofil.com\r\n\r\n> test\r\n> run-script-os tvprofil.com\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand tvprofil.com\r\n\r\n FAIL sites/tvprofil.com/tvprofil.com.test.js\r\n ✕ can generate valid url (14 ms)\r\n ✓ can generate valid request headers (1 ms)\r\n ✓ can parse response (76 ms)\r\n ✓ can handle empty guide (2 ms)\r\n\r\n ● can generate valid url\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: "https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b51=818933"\r\n Received: "https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b49=819461"\r\n\r\n 15 |\r\n 16 | it(\'can generate valid url\', () => {\r\n > 17 | expect(url({ channel, date })).toBe(\r\n | ^\r\n 18 | \'https://tvprofil.com/bg/tv-programa/program/?datum=2023-01-12&kanal=24kitchen-bg&callback=cb&b51=818933\'\r\n 19 | )\r\n 20 | })\r\n\r\n at Object. (sites/tvprofil.com/tvprofil.com.test.js:17:34)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 3 passed, 4 total\r\nSnapshots: 0 total\r\nTime: 3.307 s\r\nRan all test suites matching /tvprofil.com/i.\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2399/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2396',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2396',
+ id: 2370189473,
+ node_id: 'I_kwDOFLVvtM6NRjih',
+ number: 2396,
+ title: 'iltalehti.fi',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-06-24T12:56:45Z',
+ updated_at: '2024-12-27T05:18:16Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\n\niltalehti.fi\n\n### Description\n\nTest failed:\r\n\r\n```sh\r\nnpm test -- iltalehti.fi \r\n\r\n> test\r\n> run-script-os iltalehti.fi\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand iltalehti.fi\r\n\r\n FAIL sites/iltalehti.fi/iltalehti.fi.test.js\r\n ✕ can generate valid url (10 ms)\r\n ✓ can parse response (28 ms)\r\n ✓ can handle empty guide (1 ms)\r\n\r\n ● can generate valid url\r\n\r\n expect(received).toBe(expected) // Object.is equality\r\n\r\n Expected: "https://telkku.com/api/channel-groups/default_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails"\r\n Received: "https://telkku.com/api/channel-groups/default_builtin_channelgroupdefault_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails"\r\n\r\n 15 |\r\n 16 | it(\'can generate valid url\', () => {\r\n > 17 | expect(url({ channel, date })).toBe(\r\n | ^\r\n 18 | \'https://telkku.com/api/channel-groups/default_builtin_channelgroup1/offering?startTime=00%3A00%3A00.000&duration=PT24H&inclusionPolicy=IncludeOngoingAlso&limit=1000&tvDate=2022-10-29&view=PublicationDetails\'\r\n 19 | )\r\n 20 | })\r\n\r\n at Object. (sites/iltalehti.fi/iltalehti.fi.test.js:17:34)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 2 passed, 3 total\r\nSnapshots: 0 total\r\nTime: 3.193 s\r\nRan all test suites matching /iltalehti.fi/i.\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2396/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2395',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2395',
+ id: 2370186157,
+ node_id: 'I_kwDOFLVvtM6NRiut',
+ number: 2395,
+ title: 'chaines-tv.orange.fr',
+ user: {
+ login: 'freearhey',
+ id: 7253922,
+ node_id: 'MDQ6VXNlcjcyNTM5MjI=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/freearhey',
+ html_url: 'https://github.com/freearhey',
+ followers_url: 'https://api.github.com/users/freearhey/followers',
+ following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
+ gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
+ organizations_url: 'https://api.github.com/users/freearhey/orgs',
+ repos_url: 'https://api.github.com/users/freearhey/repos',
+ events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/freearhey/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 2,
+ created_at: '2024-06-24T12:55:21Z',
+ updated_at: '2024-12-27T05:17:25Z',
+ closed_at: null,
+ author_association: 'COLLABORATOR',
+ active_lock_reason: null,
+ body: '### Site\r\n\r\nchaines-tv.orange.fr\r\n\r\n### Description\r\n\r\nTest failed:\r\n\r\n```sh\r\nnpm test -- chaines-tv.orange.fr\r\n\r\n> test\r\n> run-script-os chaines-tv.orange.fr\r\n\r\n\r\n> test:default\r\n> TZ=Pacific/Nauru npx jest --runInBand chaines-tv.orange.fr\r\n\r\n FAIL sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js\r\n ✓ can generate valid url (5 ms)\r\n ✕ can parse response (12 ms)\r\n ✓ can handle empty guide (1 ms)\r\n\r\n ● can parse response\r\n\r\n expect(received).toMatchObject(expected)\r\n\r\n - Expected - 1\r\n + Received + 1\r\n\r\n @@ -3,8 +3,8 @@\r\n "category": "Série Suspense",\r\n "description": "Un tueur en série prend un plaisir pervers à prévenir les autorités de Tallahassee avant chaque nouveau meurtre. Rossi apprend le décès d\'un de ses vieux amis.",\r\n "icon": "https://proxymedia.woopic.com/340/p/169_EMI_9697669.jpg",\r\n "start": "2021-11-07T23:35:00.000Z",\r\n "stop": "2021-11-08T00:20:00.000Z",\r\n - "title": "Tête de liste",\r\n + "title": "Esprits criminels",\r\n },\r\n ]\r\n\r\n 23 | it(\'can parse response\', () => {\r\n 24 | const result = parser({ date, channel, content })\r\n > 25 | expect(result).toMatchObject([\r\n | ^\r\n 26 | {\r\n 27 | start: \'2021-11-07T23:35:00.000Z\',\r\n 28 | stop: \'2021-11-08T00:20:00.000Z\',\r\n\r\n at Object. (sites/chaines-tv.orange.fr/chaines-tv.orange.fr.test.js:25:18)\r\n\r\nTest Suites: 1 failed, 1 total\r\nTests: 1 failed, 2 passed, 3 total\r\nSnapshots: 0 total\r\nTime: 4.003 s\r\nRan all test suites matching /chaines-tv.orange.fr/i.\r\n```',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2395/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2304',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2304',
+ id: 2064638324,
+ node_id: 'I_kwDOFLVvtM57D-F0',
+ number: 2304,
+ title: 'digiturk.com.tr Missing Channel Identifications',
+ user: {
+ login: 'UzunMuhalefet',
+ id: 80906858,
+ node_id: 'MDQ6VXNlcjgwOTA2ODU4',
+ avatar_url: 'https://avatars.githubusercontent.com/u/80906858?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/UzunMuhalefet',
+ html_url: 'https://github.com/UzunMuhalefet',
+ followers_url: 'https://api.github.com/users/UzunMuhalefet/followers',
+ following_url: 'https://api.github.com/users/UzunMuhalefet/following{/other_user}',
+ gists_url: 'https://api.github.com/users/UzunMuhalefet/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/UzunMuhalefet/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/UzunMuhalefet/subscriptions',
+ organizations_url: 'https://api.github.com/users/UzunMuhalefet/orgs',
+ repos_url: 'https://api.github.com/users/UzunMuhalefet/repos',
+ events_url: 'https://api.github.com/users/UzunMuhalefet/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/UzunMuhalefet/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 0,
+ created_at: '2024-01-03T20:57:58Z',
+ updated_at: '2024-12-27T05:32:37Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\r\n\r\ndigiturk.com.tr\r\n\r\n### Describe your issue\r\n\r\nThe following channels can be corrected as follows. (I added the TVG-IDs if they exist in https://iptv-org.github.io/)\r\n\r\n```\r\nKANAL 24 HD \r\nTARIH TV HD \r\nSÖZCÜ TV HD \r\n```\r\n\r\nLet me clarify the cases:\r\n- SZC changed its name to Sözcü TV\r\n- 24 TV often called as Kanal (Channel) 24\r\n- Tarih TV is straightforward.\r\n',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2304/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2303',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2303',
+ id: 2064633657,
+ node_id: 'I_kwDOFLVvtM57D885',
+ number: 2303,
+ title: 'dsmart.com.tr Channel Identifications',
+ user: {
+ login: 'UzunMuhalefet',
+ id: 80906858,
+ node_id: 'MDQ6VXNlcjgwOTA2ODU4',
+ avatar_url: 'https://avatars.githubusercontent.com/u/80906858?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/UzunMuhalefet',
+ html_url: 'https://github.com/UzunMuhalefet',
+ followers_url: 'https://api.github.com/users/UzunMuhalefet/followers',
+ following_url: 'https://api.github.com/users/UzunMuhalefet/following{/other_user}',
+ gists_url: 'https://api.github.com/users/UzunMuhalefet/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/UzunMuhalefet/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/UzunMuhalefet/subscriptions',
+ organizations_url: 'https://api.github.com/users/UzunMuhalefet/orgs',
+ repos_url: 'https://api.github.com/users/UzunMuhalefet/repos',
+ events_url: 'https://api.github.com/users/UzunMuhalefet/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/UzunMuhalefet/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 1,
+ created_at: '2024-01-03T20:53:34Z',
+ updated_at: '2024-12-27T05:44:16Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Describe your issue\r\n\r\nThe following channels can be corrected as follows. (I added the TVG-IDs if they exist in https://iptv-org.github.io/)\r\n\r\n```\r\nNR1 \r\nNR1 Türk \r\nTRT EBA TV İlkokul \r\nTRT EBA TV Ortaokul \r\nTRT EBA TV Lise \r\nÇifçi TV \r\nKanal 16 \r\nFlash Haber \r\nYeni Kocaeli TV \r\nATV Turkiye SD \r\nTRT EBA TV İlkokul SD \r\nTRT EBA TV Ortaokul SD \r\nTRT EBA TV Lise SD \r\nTarih Tv \r\nSZC \r\nTRT 3 Spor \r\n``` \r\n\r\nLet me clarify the cases: \r\n\r\n- NR1 stands for Number One\r\n- Cifci TV - Çiftçi TV - misspelling\r\n- The number 16 is spelled as onaltı (on -> 10, altı->6, on6 -> 16) in Turkish so on6 - Kanal 16\r\n- Flash TV changed its name to Flash Haber TV\r\n- SZC changed its name to Sözcü TV\r\n- TRT 3 is a strange channel that usually streams the same content as TRT Spor but when there is a Turkish parliament event it switches to that event. So, the channel is both called TRT 3 and TRT 3 Spor.\r\n',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2303/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2272',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2272',
+ id: 2022135766,
+ node_id: 'I_kwDOFLVvtM54h1fW',
+ number: 2272,
+ title: 'Film titles with numbers only in the title (as in "1900" or "1917") don\'t show up',
+ user: {
+ login: 'GlamoramaAttack',
+ id: 116585465,
+ node_id: 'U_kgDOBvLz-Q',
+ avatar_url: 'https://avatars.githubusercontent.com/u/116585465?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/GlamoramaAttack',
+ html_url: 'https://github.com/GlamoramaAttack',
+ followers_url: 'https://api.github.com/users/GlamoramaAttack/followers',
+ following_url: 'https://api.github.com/users/GlamoramaAttack/following{/other_user}',
+ gists_url: 'https://api.github.com/users/GlamoramaAttack/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/GlamoramaAttack/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/GlamoramaAttack/subscriptions',
+ organizations_url: 'https://api.github.com/users/GlamoramaAttack/orgs',
+ repos_url: 'https://api.github.com/users/GlamoramaAttack/repos',
+ events_url: 'https://api.github.com/users/GlamoramaAttack/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/GlamoramaAttack/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 2,
+ created_at: '2023-12-02T17:29:50Z',
+ updated_at: '2024-12-27T05:02:05Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\r\n\r\ntvpassport.com\r\n\r\n### Describe your issue\r\n\r\nFilm titles with numbers only in the title -as in "1900" or "1917"- don\'t show up at all.\r\n\r\nSorry, I don\'t understand anything about how to write a script or fix it but I see there is notable difference in the **guide.xml** file - the examples are excerpts from tvpassport.com. This isn\'t a new bug I think, it\'s just that I thought for a long time it\'s a Kodi problem before looking into the guide.xml file...\r\n\r\n```\r\nchannel="Showtime2East.us">The Caine Mutiny Court-Martial A \r\nchannel="Showtime2East.us">Two British soldiers receive seemingly impossible orders \r\nchannel="Showtime2East.us">There Will Be Blood Daniel \r\n```\r\nor:\r\n\r\n```\r\nchannel="MGMPlusEast.us">A Fistful of Dynamite A thief \r\nchannel="MGMPlusEast.us">The son (Robert De Niro) of a landowner and the son \r\nchannel="MGMPlusEast.us">Indecent Proposal A Las Vegas \r\n```\r\n\r\nFor some reason "title lang" gets replaced by "desc lang" and the film title is nowhere displayed.\r\n\r\nOn Kodi it looks like this for the films and you can also see it\'s not a problem if the film title includes more than numbers (see "88 Minutes" or "Resistance: 1942"). But titles as "1900", "1917" or "1408" (Horror with John Cusack) appear blank.\r\n\r\n\r\n\r\nI\'m not sure whether the problem also exists with other sources than tvpassport.com because I use only two other (German language) EPG sources that have currently no film titles with numbers only. But I assume it\'s a bug if it\'s not reduced to tvpassport.',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2272/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2176',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/2176',
+ id: 1915947653,
+ node_id: 'I_kwDOFLVvtM5yMwqF',
+ number: 2176,
+ title: 'tvtv',
+ user: {
+ login: 'jvdillon',
+ id: 1137078,
+ node_id: 'MDQ6VXNlcjExMzcwNzg=',
+ avatar_url: 'https://avatars.githubusercontent.com/u/1137078?v=4',
+ gravatar_id: '',
+ url: 'https://api.github.com/users/jvdillon',
+ html_url: 'https://github.com/jvdillon',
+ followers_url: 'https://api.github.com/users/jvdillon/followers',
+ following_url: 'https://api.github.com/users/jvdillon/following{/other_user}',
+ gists_url: 'https://api.github.com/users/jvdillon/gists{/gist_id}',
+ starred_url: 'https://api.github.com/users/jvdillon/starred{/owner}{/repo}',
+ subscriptions_url: 'https://api.github.com/users/jvdillon/subscriptions',
+ organizations_url: 'https://api.github.com/users/jvdillon/orgs',
+ repos_url: 'https://api.github.com/users/jvdillon/repos',
+ events_url: 'https://api.github.com/users/jvdillon/events{/privacy}',
+ received_events_url: 'https://api.github.com/users/jvdillon/received_events',
+ type: 'User',
+ user_view_type: 'public',
+ site_admin: false
+ },
+ labels: [
+ {
+ id: 4542348869,
+ node_id: 'LA_kwDOFLVvtM8AAAABDr6-RQ',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/broken%20guide',
+ name: 'broken guide',
+ color: 'eaeaea',
+ default: false,
+ description: "There's a problem with the guide"
+ },
+ {
+ id: 7932710318,
+ node_id: 'LA_kwDOFLVvtM8AAAAB2NONrg',
+ url: 'https://api.github.com/repos/iptv-org/epg/labels/status:warning',
+ name: 'status:warning',
+ color: 'fbca06',
+ default: false,
+ description: 'The guide downloads, but contains errors'
+ }
+ ],
+ state: 'open',
+ locked: false,
+ assignee: null,
+ assignees: [],
+ milestone: null,
+ comments: 6,
+ created_at: '2023-09-27T16:34:00Z',
+ updated_at: '2024-12-27T04:55:00Z',
+ closed_at: null,
+ author_association: 'NONE',
+ active_lock_reason: null,
+ body: '### Site\r\n\r\ntvtv.us\r\n\r\n### Description\r\n\r\nStarts getting error 429 after several 100 scrapes. I tried setting the delay to 1000ms, 1500ms, and 2000ms but keep seeing the issue.\r\n\r\nIt almost appears to happen after a sequence of 0 program scrapes. I wonder if the delay is not happening when nothing is downloaded which causes tvtv.us to throttle which triggers 0 programs downloaded. (Ie a feedback loop)',
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/reactions',
+ total_count: 0,
+ '+1': 0,
+ '-1': 0,
+ laugh: 0,
+ hooray: 0,
+ confused: 0,
+ heart: 0,
+ rocket: 0,
+ eyes: 0
+ },
+ timeline_url: 'https://api.github.com/repos/iptv-org/epg/issues/2176/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ }
+]
diff --git a/tests/__data__/input/sites-update/sites/iltalehti.fi/readme.md b/tests/__data__/input/sites-update/sites/iltalehti.fi/readme.md
new file mode 100644
index 00000000..144ed147
--- /dev/null
+++ b/tests/__data__/input/sites-update/sites/iltalehti.fi/readme.md
@@ -0,0 +1 @@
+# litalehti.fi
diff --git a/tests/__data__/input/sites-update/sites/indihometv.com/readme.md b/tests/__data__/input/sites-update/sites/indihometv.com/readme.md
new file mode 100644
index 00000000..83b8c5c1
--- /dev/null
+++ b/tests/__data__/input/sites-update/sites/indihometv.com/readme.md
@@ -0,0 +1 @@
+# indihometv.com
diff --git a/tests/__data__/input/sites-update/sites/kan.org.il/readme.md b/tests/__data__/input/sites-update/sites/kan.org.il/readme.md
new file mode 100644
index 00000000..8c5b49ea
--- /dev/null
+++ b/tests/__data__/input/sites-update/sites/kan.org.il/readme.md
@@ -0,0 +1 @@
+# kan.org.il
diff --git a/tests/commands/api/generate.test.ts b/tests/commands/api/generate.test.ts
index ab6a3ee7..1480ac59 100644
--- a/tests/commands/api/generate.test.ts
+++ b/tests/commands/api/generate.test.ts
@@ -1,6 +1,6 @@
import { execSync } from 'child_process'
import fs from 'fs-extra'
-import path from 'path'
+import { pathToFileURL } from 'node:url'
import os from 'os'
let ENV_VAR = 'SITES_DIR=tests/__data__/input/epg-grab/sites API_DIR=tests/__data__/output'
@@ -16,7 +16,8 @@ beforeEach(() => {
describe('api:generate', () => {
it('can generate guides.json', () => {
const cmd = `${ENV_VAR} npm run api:generate`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guides.json')).toEqual(
content('tests/__data__/expected/guides.json')
@@ -25,7 +26,7 @@ describe('api:generate', () => {
})
function content(filepath: string) {
- return fs.readFileSync(path.resolve(filepath), {
+ return fs.readFileSync(pathToFileURL(filepath), {
encoding: 'utf8'
})
}
diff --git a/tests/commands/channels/editor.test.ts b/tests/commands/channels/editor.test.ts
index 271014f0..0c001df5 100644
--- a/tests/commands/channels/editor.test.ts
+++ b/tests/commands/channels/editor.test.ts
@@ -1,13 +1,18 @@
import fs from 'fs-extra'
import { execSync } from 'child_process'
import os from 'os'
-import path from 'path'
+import { pathToFileURL } from 'node:url'
type ExecError = {
status: number
stdout: string
}
+let ENV_VAR = 'DATA_DIR=tests/__data__/input/temp/data'
+if (os.platform() === 'win32') {
+ ENV_VAR = 'SET "DATA_DIR=tests/__data__/input/temp/data" &&'
+}
+
beforeEach(() => {
fs.emptyDirSync('tests/__data__/output')
fs.copySync(
@@ -18,19 +23,16 @@ beforeEach(() => {
describe('channels:editor', () => {
it('shows list of options for a channel', () => {
- let ENV_VAR = 'DATA_DIR=tests/__data__/input/temp/data'
- if (os.platform() === 'win32') {
- ENV_VAR = 'SET "DATA_DIR=tests/__data__/input/temp/data" &&'
- }
-
try {
const cmd = `${ENV_VAR} npm run channels:editor --- tests/__data__/output/channels.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
} catch (error) {
+ if (process.env.DEBUG === 'true') console.log(cmd, error)
expect((error as ExecError).status).toBe(1)
expect((error as ExecError).stdout).toContain('CNN International | CNNInternational.us [new]')
expect((error as ExecError).stdout).toContain(
- 'CNN International Europe | CNNInternationalEurope.us [api]'
+ 'CNN International Europe | CNNInternationalEurope.us'
)
expect((error as ExecError).stdout).toContain('Overwrite')
expect((error as ExecError).stdout).toContain('Skip')
@@ -45,7 +47,7 @@ describe('channels:editor', () => {
})
function content(filepath: string) {
- return fs.readFileSync(path.resolve(filepath), {
+ return fs.readFileSync(pathToFileURL(filepath), {
encoding: 'utf8'
})
}
diff --git a/tests/commands/channels/lint.test.ts b/tests/commands/channels/lint.test.ts
index 4e37d7a9..2ba65d80 100644
--- a/tests/commands/channels/lint.test.ts
+++ b/tests/commands/channels/lint.test.ts
@@ -8,15 +8,49 @@ type ExecError = {
describe('channels:lint', () => {
it('will show a message if the file contains a syntax error', () => {
try {
- const cmd =
- 'npm run channels:lint --- --channels=tests/__data__/input/channels-lint/channels-lint.channels.xml'
- execSync(cmd, { encoding: 'utf8' })
+ const cmd = 'npm run channels:lint --- tests/__data__/input/channels-lint/error.channels.xml'
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
process.exit(1)
} catch (error) {
expect((error as ExecError).status).toBe(1)
expect((error as ExecError).stdout).toContain(
- "channels-lint.channels.xml\n 3:0 Element 'channel': The attribute 'lang' is required but missing.\n\n1 error(s)\n"
+ "error.channels.xml\n 3:0 Element 'channel': The attribute 'lang' is required but missing.\n\n1 error(s)\n"
)
}
})
+
+ it('will show a message if an error occurred while parsing an xml file', () => {
+ try {
+ const cmd =
+ 'npm run channels:lint --- tests/__data__/input/channels-lint/invalid.channels.xml'
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+ process.exit(1)
+ } catch (error) {
+ expect((error as ExecError).status).toBe(1)
+ expect((error as ExecError).stdout).toContain(
+ 'invalid.channels.xml\n 2:6 XML declaration allowed only at the start of the document\n'
+ )
+ }
+ })
+
+ it('can test multiple files at ones', () => {
+ try {
+ const cmd =
+ 'npm run channels:lint --- tests/__data__/input/channels-lint/error.channels.xml tests/__data__/input/channels-lint/invalid.channels.xml'
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+ process.exit(1)
+ } catch (error) {
+ expect((error as ExecError).status).toBe(1)
+ expect((error as ExecError).stdout).toContain(
+ "error.channels.xml\n 3:0 Element 'channel': The attribute 'lang' is required but missing.\n"
+ )
+ expect((error as ExecError).stdout).toContain(
+ 'invalid.channels.xml\n 2:6 XML declaration allowed only at the start of the document\n'
+ )
+ expect((error as ExecError).stdout).toContain('2 error(s)')
+ }
+ })
})
diff --git a/tests/commands/channels/parse.test.ts b/tests/commands/channels/parse.test.ts
index 5ca5ad87..6c9fa113 100644
--- a/tests/commands/channels/parse.test.ts
+++ b/tests/commands/channels/parse.test.ts
@@ -1,6 +1,6 @@
import { execSync } from 'child_process'
import fs from 'fs-extra'
-import path from 'path'
+import { pathToFileURL } from 'node:url'
beforeEach(() => {
fs.emptyDirSync('tests/__data__/output')
@@ -14,7 +14,8 @@ describe('channels:parse', () => {
it('can parse channels', () => {
const cmd =
'npm run channels:parse --- --config=tests/__data__/input/channels-parse/channels-parse.config.js --output=tests/__data__/output/channels.xml'
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/channels.xml')).toEqual(
content('tests/__data__/expected/sites/channels-parse/channels-parse.channels.xml')
@@ -23,7 +24,7 @@ describe('channels:parse', () => {
})
function content(filepath: string) {
- return fs.readFileSync(path.resolve(filepath), {
+ return fs.readFileSync(pathToFileURL(filepath), {
encoding: 'utf8'
})
}
diff --git a/tests/commands/channels/validate.test.ts b/tests/commands/channels/validate.test.ts
index dfb1e907..d4d3b039 100644
--- a/tests/commands/channels/validate.test.ts
+++ b/tests/commands/channels/validate.test.ts
@@ -15,17 +15,12 @@ describe('channels:validate', () => {
it('will show a message if the file contains a duplicate', () => {
try {
const cmd = `${ENV_VAR} npm run channels:validate --- --channels=tests/__data__/input/channels-validate/duplicate.channels.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
process.exit(1)
} catch (error) {
expect((error as ExecError).status).toBe(1)
expect((error as ExecError).stdout).toContain(`
-> channels:validate
-> npx tsx scripts/commands/channels/validate.ts --channels=tests/__data__/input/channels-validate/duplicate.channels.xml
-
-options:
- channels: tests/__data__/input/channels-validate/duplicate.channels.xml
-tests/__data__/input/channels-validate/duplicate.channels.xml
┌─────────┬─────────────┬──────┬────────────────┬─────────┬─────────┐
│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
├─────────┼─────────────┼──────┼────────────────┼─────────┼─────────┤
@@ -40,17 +35,12 @@ tests/__data__/input/channels-validate/duplicate.channels.xml
it('will show a message if the file contains a channel with wrong xmltv_id', () => {
try {
const cmd = `${ENV_VAR} npm run channels:validate --- --channels=tests/__data__/input/channels-validate/wrong_xmltv_id.channels.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
process.exit(1)
} catch (error) {
expect((error as ExecError).status).toBe(1)
expect((error as ExecError).stdout).toContain(`
-> channels:validate
-> npx tsx scripts/commands/channels/validate.ts --channels=tests/__data__/input/channels-validate/wrong_xmltv_id.channels.xml
-
-options:
- channels: tests/__data__/input/channels-validate/wrong_xmltv_id.channels.xml
-tests/__data__/input/channels-validate/wrong_xmltv_id.channels.xml
┌─────────┬──────────────────┬──────┬────────────────────┬─────────┬─────────────────────┐
│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
├─────────┼──────────────────┼──────┼────────────────────┼─────────┼─────────────────────┤
diff --git a/tests/commands/epg/grab.test.ts b/tests/commands/epg/grab.test.ts
index 1c5be77e..d580f265 100644
--- a/tests/commands/epg/grab.test.ts
+++ b/tests/commands/epg/grab.test.ts
@@ -1,5 +1,6 @@
import { execSync } from 'child_process'
import fs from 'fs-extra'
+import { pathToFileURL } from 'node:url'
import path from 'path'
import os from 'os'
import { Zip } from '@freearhey/core'
@@ -17,10 +18,11 @@ beforeEach(() => {
describe('epg:grab', () => {
it('can grab epg by site name', () => {
- const cmd = `${ENV_VAR} npm run grab --- --site=example.com --output=${path.resolve(
+ const cmd = `${ENV_VAR} npm run grab --- --site=example.com --output="${path.resolve(
'tests/__data__/output/guide.xml'
- )}`
- execSync(cmd, { encoding: 'utf8' })
+ )}"`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guide.xml')).toEqual(
content('tests/__data__/expected/guide2.xml')
@@ -29,7 +31,8 @@ describe('epg:grab', () => {
it('can grab epg with multiple channels.xml files', () => {
const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/sites/**/*.channels.xml --output=tests/__data__/output/guide.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guide.xml')).toEqual(
content('tests/__data__/expected/guide.xml')
@@ -37,10 +40,11 @@ describe('epg:grab', () => {
})
it('can grab epg with gzip option enabled', async () => {
- const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/sites/**/*.channels.xml --output=${path.resolve(
+ const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/sites/**/*.channels.xml --output="${path.resolve(
'tests/__data__/output/guide.xml'
- )} --gzip`
- execSync(cmd, { encoding: 'utf8' })
+ )}" --gzip`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guide.xml')).toEqual(
content('tests/__data__/expected/guide.xml')
@@ -50,11 +54,12 @@ describe('epg:grab', () => {
const expected = await zip.decompress(fs.readFileSync('tests/__data__/output/guide.xml.gz'))
const result = await zip.decompress(fs.readFileSync('tests/__data__/expected/guide.xml.gz'))
expect(expected).toEqual(result)
- })
+ }, 30000)
it('can grab epg with wildcard as output', () => {
const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/sites/example.com/example.com.channels.xml --output=tests/__data__/output/guides/{lang}/{site}.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guides/en/example.com.xml')).toEqual(
content('tests/__data__/expected/guides/en/example.com.xml')
@@ -67,7 +72,8 @@ describe('epg:grab', () => {
it('can grab epg then language filter enabled', () => {
const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/sites/example.com/example.com.channels.xml --output=tests/__data__/output/guides/{lang}/{site}.xml --lang=fr`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guides/fr/example.com.xml')).toEqual(
content('tests/__data__/expected/guides/fr/example.com.xml')
@@ -76,7 +82,8 @@ describe('epg:grab', () => {
it('can grab epg using custom channels list', () => {
const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/custom.channels.xml --output=tests/__data__/output/guide.xml`
- execSync(cmd, { encoding: 'utf8' })
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(content('tests/__data__/output/guide.xml')).toEqual(
content('tests/__data__/expected/guide.xml')
@@ -86,13 +93,14 @@ describe('epg:grab', () => {
it('it will raise an error if the timeout is exceeded', () => {
const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg-grab/custom.channels.xml --output=tests/__data__/output/guide.xml --timeout=0`
const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
expect(stdout).toContain('ERR: Connection timeout')
})
})
function content(filepath: string) {
- return fs.readFileSync(path.resolve(filepath), {
+ return fs.readFileSync(pathToFileURL(filepath), {
encoding: 'utf8'
})
}
diff --git a/tests/commands/sites/update.test.ts b/tests/commands/sites/update.test.ts
index e38414d3..0af18d4c 100644
--- a/tests/commands/sites/update.test.ts
+++ b/tests/commands/sites/update.test.ts
@@ -1,36 +1,45 @@
-import { execSync } from 'child_process'
-import fs from 'fs-extra'
-import path from 'path'
-
-beforeEach(() => {
- fs.emptyDirSync('tests/__data__/output')
- fs.mkdirSync('tests/__data__/output/.sites')
- fs.copyFileSync(
- 'tests/__data__/input/.sites/config.json',
- 'tests/__data__/output/.sites/config.json'
- )
- fs.copyFileSync(
- 'tests/__data__/input/.sites/template.md',
- 'tests/__data__/output/.sites/template.md'
- )
-})
-
-it('can update SITES.md', () => {
- const stdout = execSync('DOT_SITES_DIR=tests/__data__/output/.sites npm run sites:update', {
- encoding: 'utf8'
- })
-
- expect(content('tests/__data__/output/sites.md')).toEqual(
- content('tests/__data__/expected/_sites.md')
- )
-
- expect(true).toBe(true)
-})
-
-function content(filepath: string) {
- const data = fs.readFileSync(path.resolve(filepath), {
- encoding: 'utf8'
- })
-
- return JSON.stringify(data)
-}
+import { execSync } from 'child_process'
+import fs from 'fs-extra'
+import { pathToFileURL } from 'node:url'
+import os from 'os'
+
+let ENV_VAR =
+ 'DOT_SITES_DIR=tests/__data__/output/.sites SITES_DIR=tests/__data__/input/sites-update/sites'
+if (os.platform() === 'win32') {
+ ENV_VAR =
+ 'SET "DOT_SITES_DIR=tests/__data__/output/.sites" && SET "SITES_DIR=tests/__data__/input/sites-update/sites" &&'
+}
+
+beforeEach(() => {
+ fs.emptyDirSync('tests/__data__/output')
+ fs.mkdirSync('tests/__data__/output/.sites')
+ fs.copyFileSync(
+ 'tests/__data__/input/.sites/config.json',
+ 'tests/__data__/output/.sites/config.json'
+ )
+ fs.copyFileSync(
+ 'tests/__data__/input/.sites/template.md',
+ 'tests/__data__/output/.sites/template.md'
+ )
+})
+
+it('can update SITES.md', () => {
+ const cmd = `${ENV_VAR} npm run sites:update`
+
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/sites.md')).toEqual(
+ content('tests/__data__/expected/_sites.md')
+ )
+
+ expect(true).toBe(true)
+})
+
+function content(filepath: string) {
+ const data = fs.readFileSync(pathToFileURL(filepath), {
+ encoding: 'utf8'
+ })
+
+ return JSON.stringify(data)
+}
diff --git a/yarn.lock b/yarn.lock
index b4605e59..81ca202d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -33,7 +33,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz"
integrity sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==
-"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8":
+"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0":
version "7.22.8"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz"
integrity sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==
@@ -379,7 +379,7 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@9.17.0":
+"@eslint/js@^9.17.0", "@eslint/js@9.17.0":
version "9.17.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz"
integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==
@@ -523,6 +523,13 @@
slash "^3.0.0"
strip-ansi "^6.0.0"
+"@jest/create-cache-key-function@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz"
+ integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==
+ dependencies:
+ "@jest/types" "^29.6.3"
+
"@jest/environment@^29.7.0":
version "29.7.0"
resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz"
@@ -657,7 +664,7 @@
slash "^3.0.0"
write-file-atomic "^4.0.2"
-"@jest/types@^29.0.0", "@jest/types@^29.6.3":
+"@jest/types@^29.6.3":
version "29.6.3"
resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz"
integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==
@@ -849,57 +856,6 @@
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
-"@pm2/agent@~2.0.0":
- version "2.0.4"
- resolved "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.4.tgz"
- integrity sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==
- dependencies:
- async "~3.2.0"
- chalk "~3.0.0"
- dayjs "~1.8.24"
- debug "~4.3.1"
- eventemitter2 "~5.0.1"
- fast-json-patch "^3.0.0-1"
- fclone "~1.0.11"
- nssocket "0.6.0"
- pm2-axon "~4.0.1"
- pm2-axon-rpc "~0.7.0"
- proxy-agent "~6.3.0"
- semver "~7.5.0"
- ws "~7.5.10"
-
-"@pm2/io@~6.0.1":
- version "6.0.1"
- resolved "https://registry.npmjs.org/@pm2/io/-/io-6.0.1.tgz"
- integrity sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==
- dependencies:
- async "~2.6.1"
- debug "~4.3.1"
- eventemitter2 "^6.3.1"
- require-in-the-middle "^5.0.0"
- semver "~7.5.4"
- shimmer "^1.2.0"
- signal-exit "^3.0.3"
- tslib "1.9.3"
-
-"@pm2/js-api@~0.8.0":
- version "0.8.0"
- resolved "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz"
- integrity sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==
- dependencies:
- async "^2.6.3"
- debug "~4.3.1"
- eventemitter2 "^6.3.1"
- extrareqp2 "^1.0.0"
- ws "^7.0.0"
-
-"@pm2/pm2-version-check@latest":
- version "1.0.4"
- resolved "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz"
- integrity sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==
- dependencies:
- debug "^4.3.1"
-
"@seald-io/binary-search-tree@^1.0.2":
version "1.0.2"
resolved "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.2.tgz"
@@ -938,6 +894,51 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
+"@swc/core-darwin-x64@1.10.4":
+ version "1.10.4"
+ resolved "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.4.tgz"
+ integrity sha512-gjYNU6vrAUO4+FuovEo9ofnVosTFXkF0VDuo1MKPItz6e2pxc2ale4FGzLw0Nf7JB1sX4a8h06CN16/pLJ8Q2w==
+
+"@swc/core@*", "@swc/core@^1.10.4", "@swc/core@>=1.2.50":
+ version "1.10.4"
+ resolved "https://registry.npmjs.org/@swc/core/-/core-1.10.4.tgz"
+ integrity sha512-ut3zfiTLORMxhr6y/GBxkHmzcGuVpwJYX4qyXWuBKkpw/0g0S5iO1/wW7RnLnZbAi8wS/n0atRZoaZlXWBkeJg==
+ dependencies:
+ "@swc/counter" "^0.1.3"
+ "@swc/types" "^0.1.17"
+ optionalDependencies:
+ "@swc/core-darwin-arm64" "1.10.4"
+ "@swc/core-darwin-x64" "1.10.4"
+ "@swc/core-linux-arm-gnueabihf" "1.10.4"
+ "@swc/core-linux-arm64-gnu" "1.10.4"
+ "@swc/core-linux-arm64-musl" "1.10.4"
+ "@swc/core-linux-x64-gnu" "1.10.4"
+ "@swc/core-linux-x64-musl" "1.10.4"
+ "@swc/core-win32-arm64-msvc" "1.10.4"
+ "@swc/core-win32-ia32-msvc" "1.10.4"
+ "@swc/core-win32-x64-msvc" "1.10.4"
+
+"@swc/counter@^0.1.3":
+ version "0.1.3"
+ resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz"
+ integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
+
+"@swc/jest@^0.2.37":
+ version "0.2.37"
+ resolved "https://registry.npmjs.org/@swc/jest/-/jest-0.2.37.tgz"
+ integrity sha512-CR2BHhmXKGxTiFr21DYPRHQunLkX3mNIFGFkxBGji6r9uyIR5zftTOVYj1e0sFNMV2H7mf/+vpaglqaryBtqfQ==
+ dependencies:
+ "@jest/create-cache-key-function" "^29.7.0"
+ "@swc/counter" "^0.1.3"
+ jsonc-parser "^3.2.0"
+
+"@swc/types@^0.1.17":
+ version "0.1.17"
+ resolved "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz"
+ integrity sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==
+ dependencies:
+ "@swc/counter" "^0.1.3"
+
"@szmarczak/http-timer@^4.0.5":
version "4.0.6"
resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz"
@@ -945,11 +946,6 @@
dependencies:
defer-to-connect "^2.0.0"
-"@tootallnate/quickjs-emscripten@^0.23.0":
- version "0.23.0"
- resolved "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz"
- integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==
-
"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz"
@@ -1104,7 +1100,7 @@
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz"
integrity sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==
-"@types/luxon@^3.3.2":
+"@types/luxon@^3.3.2", "@types/luxon@~3.3.0":
version "3.3.2"
resolved "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.2.tgz"
integrity sha512-l5cpE57br4BIjK+9BSkFBOsWtwv6J9bJpC7gdXIzZyI0vuKvNTk0wZZrkQxMGsUAuGW9+WMNWF2IJMD7br2yeQ==
@@ -1269,7 +1265,7 @@ acorn-walk@^8.1.1:
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz"
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
-agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.2, agent-base@^7.1.3:
+agent-base@^7.1.0, agent-base@^7.1.2, agent-base@^7.1.3:
version "7.1.3"
resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
@@ -1302,18 +1298,6 @@ ajv@8.12.0:
require-from-string "^2.0.2"
uri-js "^4.2.2"
-amp-message@~0.1.1:
- version "0.1.2"
- resolved "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz"
- integrity sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==
- dependencies:
- amp "0.3.1"
-
-amp@~0.3.1, amp@0.3.1:
- version "0.3.1"
- resolved "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz"
- integrity sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==
-
ansi-align@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz"
@@ -1321,11 +1305,6 @@ ansi-align@^3.0.1:
dependencies:
string-width "^4.1.0"
-ansi-colors@^4.1.1:
- version "4.1.3"
- resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz"
- integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
-
ansi-escapes@^4.2.1:
version "4.3.2"
resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz"
@@ -1367,7 +1346,7 @@ ansi-styles@^6.1.0:
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
-anymatch@^3.0.3, anymatch@~3.1.2:
+anymatch@^3.0.3:
version "3.1.3"
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
@@ -1402,42 +1381,11 @@ argparse@^2.0.1:
resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
-ast-types@^0.13.4:
- version "0.13.4"
- resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz"
- integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==
- dependencies:
- tslib "^2.0.1"
-
-async@^2.6.3:
- version "2.6.4"
- resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz"
- integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
- dependencies:
- lodash "^4.17.14"
-
-async@^3.2.0:
- version "3.2.6"
- resolved "https://registry.npmjs.org/async/-/async-3.2.6.tgz"
- integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
-
async@^3.2.3:
version "3.2.3"
resolved "https://registry.npmjs.org/async/-/async-3.2.3.tgz"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
-async@~2.6.1:
- version "2.6.4"
- resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz"
- integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
- dependencies:
- lodash "^4.17.14"
-
-async@~3.2.0:
- version "3.2.6"
- resolved "https://registry.npmjs.org/async/-/async-3.2.6.tgz"
- integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
-
async@0.2.10:
version "0.2.10"
resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
@@ -1482,7 +1430,7 @@ axios@^1.5.1, axios@^1.6.1, axios@^1.7.9, "axios@>= 0.9.0", axios@>=0.20.0:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
-babel-jest@^29.0.0, babel-jest@^29.7.0:
+babel-jest@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz"
integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==
@@ -1552,21 +1500,11 @@ base64-js@^1.3.1:
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-basic-ftp@^5.0.2:
- version "5.0.5"
- resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz"
- integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==
-
before-after-hook@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz"
integrity sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==
-binary-extensions@^2.0.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"
- integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
-
bindings@~1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz"
@@ -1583,16 +1521,6 @@ bl@^4.0.3, bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
-blessed@0.1.81:
- version "0.1.81"
- resolved "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz"
- integrity sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==
-
-bodec@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz"
- integrity sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==
-
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
@@ -1627,7 +1555,7 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
-braces@^3.0.3, braces@~3.0.2:
+braces@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
@@ -1644,13 +1572,6 @@ browserslist@^4.21.9, "browserslist@>= 4.21.0":
node-releases "^2.0.12"
update-browserslist-db "^1.0.11"
-bs-logger@0.x:
- version "0.2.6"
- resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz"
- integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
- dependencies:
- fast-json-stable-stringify "2.x"
-
bser@2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz"
@@ -1785,22 +1706,6 @@ chalk@^5.0.1:
resolved "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz"
integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==
-chalk@~3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz"
- integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
- dependencies:
- ansi-styles "^4.1.0"
- supports-color "^7.1.0"
-
-chalk@3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz"
- integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
- dependencies:
- ansi-styles "^4.1.0"
- supports-color "^7.1.0"
-
chalk@5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz"
@@ -1816,11 +1721,6 @@ chardet@^0.7.0:
resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
-charm@~0.1.1:
- version "0.1.2"
- resolved "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz"
- integrity sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==
-
cheerio-select@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz"
@@ -1846,21 +1746,6 @@ cheerio@^1.0.0-rc.10, cheerio@^1.0.0-rc.12:
parse5 "^7.0.0"
parse5-htmlparser2-tree-adapter "^7.0.0"
-chokidar@^3.5.3:
- version "3.6.0"
- resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"
- integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
- dependencies:
- anymatch "~3.1.2"
- braces "~3.0.2"
- glob-parent "~5.1.2"
- is-binary-path "~2.1.0"
- is-glob "~4.0.1"
- normalize-path "~3.0.0"
- readdirp "~3.6.0"
- optionalDependencies:
- fsevents "~2.3.2"
-
chownr@^1.1.1:
version "1.1.4"
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
@@ -1910,13 +1795,6 @@ cli-spinners@^2.5.0:
resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz"
integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==
-cli-tableau@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz"
- integrity sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==
- dependencies:
- chalk "3.0.0"
-
cli-width@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz"
@@ -2043,11 +1921,6 @@ commander@^8.2.0:
resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz"
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
-commander@2.15.1:
- version "2.15.1"
- resolved "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz"
- integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
-
compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz"
@@ -2116,10 +1989,13 @@ create-require@^1.1.0:
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
-croner@~4.1.92:
- version "4.1.97"
- resolved "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz"
- integrity sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==
+cron@^2.4.3:
+ version "2.4.3"
+ resolved "https://registry.npmjs.org/cron/-/cron-2.4.3.tgz"
+ integrity sha512-YBvExkQYF7w0PxyeFLRyr817YVDhGxaCi5/uRRMqa4aWD3IFKRd+uNbpW1VWMdqQy8PZ7CElc+accXJcauPKzQ==
+ dependencies:
+ "@types/luxon" "~3.3.0"
+ luxon "~3.3.0"
cross-spawn@^7.0.0, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
version "7.0.6"
@@ -2153,11 +2029,6 @@ csv-parser@^3.0.0:
dependencies:
minimist "^1.2.0"
-culvert@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz"
- integrity sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==
-
curl-generator@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/curl-generator/-/curl-generator-0.2.0.tgz"
@@ -2172,21 +2043,11 @@ cwait@^1.1.2:
dependencies:
cdata "^0.1.1"
-data-uri-to-buffer@^6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz"
- integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==
-
-dayjs@^1.10.4, dayjs@^1.11.10, dayjs@^1.11.6, dayjs@~1.11.5:
+dayjs@^1.10.4, dayjs@^1.11.10, dayjs@^1.11.6:
version "1.11.10"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
-dayjs@~1.8.24:
- version "1.8.36"
- resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz"
- integrity sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==
-
debug@^3.1.0:
version "3.2.7"
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
@@ -2194,14 +2055,7 @@ debug@^3.1.0:
dependencies:
ms "^2.1.1"
-debug@^3.2.6:
- version "3.2.7"
- resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
- integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
- dependencies:
- ms "^2.1.1"
-
-debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@4:
+debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2254,15 +2108,6 @@ defer-to-connect@^2.0.0:
resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz"
integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
-degenerator@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz"
- integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==
- dependencies:
- ast-types "^0.13.4"
- escodegen "^2.1.0"
- esprima "^4.0.1"
-
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
@@ -2362,13 +2207,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
dependencies:
once "^1.4.0"
-enquirer@2.3.6:
- version "2.3.6"
- resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
- integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
- dependencies:
- ansi-colors "^4.1.1"
-
entities@^4.2.0, entities@^4.3.0, entities@^4.4.0:
version "4.4.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz"
@@ -2479,17 +2317,6 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-escodegen@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz"
- integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==
- dependencies:
- esprima "^4.0.1"
- estraverse "^5.2.0"
- esutils "^2.0.2"
- optionalDependencies:
- source-map "~0.6.1"
-
eslint-config-prettier@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz"
@@ -2562,7 +2389,7 @@ espree@^10.0.1, espree@^10.3.0:
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.2.0"
-esprima@^4.0.0, esprima@^4.0.1:
+esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -2591,21 +2418,6 @@ esutils@^2.0.2:
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-eventemitter2@^6.3.1:
- version "6.4.9"
- resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz"
- integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==
-
-eventemitter2@~0.4.14:
- version "0.4.14"
- resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz"
- integrity sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==
-
-eventemitter2@~5.0.1, eventemitter2@5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz"
- integrity sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==
-
execa@^5.0.0, execa@^5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
@@ -2656,13 +2468,6 @@ external-editor@^3.0.3:
iconv-lite "^0.4.24"
tmp "^0.0.33"
-extrareqp2@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz"
- integrity sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==
- dependencies:
- follow-redirects "^1.14.0"
-
fast-content-type-parse@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.0.tgz"
@@ -2689,12 +2494,7 @@ fast-glob@^3.3.2:
merge2 "^1.3.0"
micromatch "^4.0.4"
-fast-json-patch@^3.0.0-1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz"
- integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==
-
-fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x:
+fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -2718,11 +2518,6 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
-fclone@~1.0.11, fclone@1.0.11:
- version "1.0.11"
- resolved "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz"
- integrity sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==
-
fecha@^4.2.0:
version "4.2.3"
resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz"
@@ -2802,7 +2597,7 @@ fn.name@1.x.x:
resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz"
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
-follow-redirects@^1.14.0, follow-redirects@^1.15.6:
+follow-redirects@^1.15.6:
version "1.15.6"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
@@ -2866,7 +2661,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3:
+fsevents@^2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
@@ -2910,25 +2705,6 @@ get-tsconfig@^4.7.5:
dependencies:
resolve-pkg-maps "^1.0.0"
-get-uri@^6.0.1:
- version "6.0.4"
- resolved "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz"
- integrity sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==
- dependencies:
- basic-ftp "^5.0.2"
- data-uri-to-buffer "^6.0.2"
- debug "^4.3.4"
-
-git-node-fs@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz"
- integrity sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==
-
-git-sha1@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz"
- integrity sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==
-
github-from-package@0.0.0:
version "0.0.0"
resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz"
@@ -2948,13 +2724,6 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
-glob-parent@~5.1.2:
- version "5.1.2"
- resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
- integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
- dependencies:
- is-glob "^4.0.1"
-
glob@^10.2.2:
version "10.4.5"
resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz"
@@ -3012,6 +2781,11 @@ globals@^14.0.0:
resolved "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
+globals@^15.14.0:
+ version "15.14.0"
+ resolved "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz"
+ integrity sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==
+
got@^11.8.2:
version "11.8.5"
resolved "https://registry.npmjs.org/got/-/got-11.8.5.tgz"
@@ -3099,7 +2873,7 @@ http2-wrapper@^1.0.0-beta.5.2:
quick-lru "^5.1.1"
resolve-alpn "^1.0.0"
-https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2, https-proxy-agent@^7.0.6:
+https-proxy-agent@^7.0.1:
version "7.0.6"
resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
@@ -3112,7 +2886,12 @@ human-signals@^2.1.0:
resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
-iconv-lite@^0.4.24, iconv-lite@^0.4.4:
+husky@^9.1.7:
+ version "9.1.7"
+ resolved "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz"
+ integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==
+
+iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -3180,7 +2959,7 @@ inherits@^2.0.3, inherits@^2.0.4, inherits@2:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-ini@^1.3.5, ini@~1.3.0:
+ini@~1.3.0:
version "1.3.8"
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@@ -3224,13 +3003,6 @@ is-arrayish@^0.3.1:
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
-is-binary-path@~2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
- integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
- dependencies:
- binary-extensions "^2.0.0"
-
is-blob@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/is-blob/-/is-blob-2.1.0.tgz"
@@ -3268,7 +3040,7 @@ is-generator-fn@^2.0.0:
resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz"
integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
-is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
@@ -3579,6 +3351,13 @@ jest-mock@^29.7.0:
"@types/node" "*"
jest-util "^29.7.0"
+jest-offline@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/jest-offline/-/jest-offline-1.0.1.tgz"
+ integrity sha512-pcYJ8rVxWP3SS9de15iSQY87ErLGGgMC4qtVcRLb/qemrefI1IgnAzOusp0eemGu7JoAGlb4oBGnZorehu95KA==
+ dependencies:
+ mitm "^1.3.2"
+
jest-pnp-resolver@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz"
@@ -3693,7 +3472,7 @@ jest-snapshot@^29.7.0:
pretty-format "^29.7.0"
semver "^7.5.3"
-jest-util@^29.0.0, jest-util@^29.7.0:
+jest-util@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz"
integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==
@@ -3741,7 +3520,7 @@ jest-worker@^29.7.0:
merge-stream "^2.0.0"
supports-color "^8.0.0"
-jest@^29.0.0, jest@^29.7.0:
+jest@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz"
integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==
@@ -3751,16 +3530,6 @@ jest@^29.0.0, jest@^29.7.0:
import-local "^3.0.2"
jest-cli "^29.7.0"
-js-git@^0.7.8:
- version "0.7.8"
- resolved "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz"
- integrity sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==
- dependencies:
- bodec "^0.1.0"
- culvert "^0.1.2"
- git-sha1 "^0.1.2"
- pako "^0.2.5"
-
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
@@ -3781,13 +3550,6 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
-js-yaml@~4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
- integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
- dependencies:
- argparse "^2.0.1"
-
jsbn@1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz"
@@ -3828,16 +3590,16 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
-json-stringify-safe@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
- integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
-
-json5@^2.2.2, json5@^2.2.3:
+json5@^2.2.2:
version "2.2.3"
resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+jsonc-parser@^3.2.0:
+ version "3.3.1"
+ resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz"
+ integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==
+
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz"
@@ -3869,11 +3631,6 @@ langs@^2.0.0:
resolved "https://registry.npmjs.org/langs/-/langs-2.0.0.tgz"
integrity sha512-v4pxOBEQVN1WBTfB1crhTtxzNLZU9HPWgadlwzWKISJtt6Ku/CnpBrwVy+jFv8StjxsPfwPFzO0CMwdZLJ0/BA==
-lazy@~1.0.11:
- version "1.0.11"
- resolved "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz"
- integrity sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==
-
leven@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz"
@@ -3948,17 +3705,12 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
-lodash.memoize@4.x:
- version "4.1.2"
- resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
- integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
-
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-lodash@^4.17.14, lodash@^4.17.21:
+lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -4011,12 +3763,7 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
-lru-cache@^7.14.1:
- version "7.18.3"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz"
- integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
-
-luxon@^3.3.0:
+luxon@^3.3.0, luxon@~3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz"
integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==
@@ -4033,7 +3780,7 @@ make-dir@^4.0.0:
dependencies:
semver "^7.5.3"
-make-error@^1.1.1, make-error@1.x:
+make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
@@ -4222,12 +3969,19 @@ minizlib@^2.1.1, minizlib@^2.1.2:
minipass "^3.0.0"
yallist "^4.0.0"
+mitm@^1.3.2:
+ version "1.7.3"
+ resolved "https://registry.npmjs.org/mitm/-/mitm-1.7.3.tgz"
+ integrity sha512-linie/mGisDH73C7aiW6JmstA5XskXd15JBJAEeNQBdH3/L0dJdE/yZ+rw/y2zT7Fcib5KAnL5OvxYOOFQbsgw==
+ dependencies:
+ semver ">= 5 < 6"
+
mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
version "0.5.3"
resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
-mkdirp@^1.0.3, mkdirp@1.0.4:
+mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -4237,11 +3991,6 @@ mockdate@^3.0.5:
resolved "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz"
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==
-module-details-from-path@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz"
- integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
-
ms@^2.0.0, ms@^2.1.1:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
@@ -4257,7 +4006,7 @@ ms@2.1.2:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-mute-stream@~0.0.4, mute-stream@0.0.8:
+mute-stream@0.0.8:
version "0.0.8"
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
@@ -4289,25 +4038,11 @@ nedb-promises@^6.0.3:
dependencies:
"@seald-io/nedb" "^2.2.0"
-needle@2.4.0:
- version "2.4.0"
- resolved "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz"
- integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==
- dependencies:
- debug "^3.2.6"
- iconv-lite "^0.4.4"
- sax "^1.2.4"
-
negotiator@^0.6.3, negotiator@0.6.3:
version "0.6.3"
resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-netmask@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz"
- integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
-
node-abi@^3.3.0:
version "3.71.0"
resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz"
@@ -4363,7 +4098,7 @@ nopt@^7.0.0:
dependencies:
abbrev "^2.0.0"
-normalize-path@^3.0.0, normalize-path@~3.0.0:
+normalize-path@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
@@ -4380,14 +4115,6 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
-nssocket@0.6.0:
- version "0.6.0"
- resolved "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz"
- integrity sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==
- dependencies:
- eventemitter2 "~0.4.14"
- lazy "~1.0.11"
-
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz"
@@ -4532,38 +4259,11 @@ p-try@^2.0.0:
resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-pac-proxy-agent@^7.0.1:
- version "7.1.0"
- resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz"
- integrity sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==
- dependencies:
- "@tootallnate/quickjs-emscripten" "^0.23.0"
- agent-base "^7.1.2"
- debug "^4.3.4"
- get-uri "^6.0.1"
- http-proxy-agent "^7.0.0"
- https-proxy-agent "^7.0.6"
- pac-resolver "^7.0.1"
- socks-proxy-agent "^8.0.5"
-
-pac-resolver@^7.0.1:
- version "7.0.1"
- resolved "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz"
- integrity sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==
- dependencies:
- degenerator "^5.0.0"
- netmask "^2.0.2"
-
package-json-from-dist@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz"
integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
-pako@^0.2.5:
- version "0.2.9"
- resolved "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz"
- integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==
-
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
@@ -4665,25 +4365,11 @@ picocolors@^1.0.0:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
+picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pidusage@^2.0.21:
- version "2.0.21"
- resolved "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz"
- integrity sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==
- dependencies:
- safe-buffer "^5.2.1"
-
-pidusage@~3.0:
- version "3.0.2"
- resolved "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz"
- integrity sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==
- dependencies:
- safe-buffer "^5.2.1"
-
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz"
@@ -4709,86 +4395,6 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
-pm2-axon-rpc@~0.7.0, pm2-axon-rpc@~0.7.1:
- version "0.7.1"
- resolved "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz"
- integrity sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==
- dependencies:
- debug "^4.3.1"
-
-pm2-axon@~4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz"
- integrity sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==
- dependencies:
- amp "~0.3.1"
- amp-message "~0.1.1"
- debug "^4.3.1"
- escape-string-regexp "^4.0.0"
-
-pm2-deploy@~1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz"
- integrity sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==
- dependencies:
- run-series "^1.1.8"
- tv4 "^1.3.0"
-
-pm2-multimeter@^0.1.2:
- version "0.1.2"
- resolved "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz"
- integrity sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==
- dependencies:
- charm "~0.1.1"
-
-pm2-sysmonit@^1.2.8:
- version "1.2.8"
- resolved "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz"
- integrity sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==
- dependencies:
- async "^3.2.0"
- debug "^4.3.1"
- pidusage "^2.0.21"
- systeminformation "^5.7"
- tx2 "~1.0.4"
-
-pm2@^5.4.3:
- version "5.4.3"
- resolved "https://registry.npmjs.org/pm2/-/pm2-5.4.3.tgz"
- integrity sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==
- dependencies:
- "@pm2/agent" "~2.0.0"
- "@pm2/io" "~6.0.1"
- "@pm2/js-api" "~0.8.0"
- "@pm2/pm2-version-check" latest
- async "~3.2.0"
- blessed "0.1.81"
- chalk "3.0.0"
- chokidar "^3.5.3"
- cli-tableau "^2.0.0"
- commander "2.15.1"
- croner "~4.1.92"
- dayjs "~1.11.5"
- debug "^4.3.1"
- enquirer "2.3.6"
- eventemitter2 "5.0.1"
- fclone "1.0.11"
- js-yaml "~4.1.0"
- mkdirp "1.0.4"
- needle "2.4.0"
- pidusage "~3.0"
- pm2-axon "~4.0.1"
- pm2-axon-rpc "~0.7.1"
- pm2-deploy "~1.0.2"
- pm2-multimeter "^0.1.2"
- promptly "^2"
- semver "^7.2"
- source-map-support "0.5.21"
- sprintf-js "1.1.2"
- vizion "~2.2.1"
- optionalDependencies:
- pm2-sysmonit "^1.2.8"
-
prebuild-install@^7.1.2:
version "7.1.2"
resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz"
@@ -4834,13 +4440,6 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
-promptly@^2:
- version "2.2.0"
- resolved "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz"
- integrity sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==
- dependencies:
- read "^1.0.4"
-
prompts@^2.0.1:
version "2.4.2"
resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz"
@@ -4849,20 +4448,6 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
-proxy-agent@~6.3.0:
- version "6.3.1"
- resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz"
- integrity sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==
- dependencies:
- agent-base "^7.0.2"
- debug "^4.3.4"
- http-proxy-agent "^7.0.0"
- https-proxy-agent "^7.0.2"
- lru-cache "^7.14.1"
- pac-proxy-agent "^7.0.1"
- proxy-from-env "^1.1.0"
- socks-proxy-agent "^8.0.2"
-
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
@@ -4921,13 +4506,6 @@ react-is@^18.0.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
-read@^1.0.4:
- version "1.0.7"
- resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz"
- integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==
- dependencies:
- mute-stream "~0.0.4"
-
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
@@ -4937,13 +4515,6 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
-readdirp@~3.6.0:
- version "3.6.0"
- resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
- integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
- dependencies:
- picomatch "^2.2.1"
-
registry-auth-token@3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz"
@@ -4969,15 +4540,6 @@ require-from-string@^2.0.2:
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
-require-in-the-middle@^5.0.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz"
- integrity sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==
- dependencies:
- debug "^4.1.1"
- module-details-from-path "^1.0.3"
- resolve "^1.22.1"
-
resolve-alpn@^1.0.0:
version "1.2.1"
resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz"
@@ -5010,7 +4572,7 @@ resolve.exports@^2.0.0:
resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.20.0, resolve@^1.22.1:
+resolve@^1.20.0:
version "1.22.6"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz"
integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==
@@ -5061,11 +4623,6 @@ run-script-os@^1.1.6:
resolved "https://registry.npmjs.org/run-script-os/-/run-script-os-1.1.6.tgz"
integrity sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==
-run-series@^1.1.8:
- version "1.1.9"
- resolved "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz"
- integrity sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==
-
rxjs@^7.2.0, rxjs@^7.5.5:
version "7.8.1"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz"
@@ -5078,11 +4635,6 @@ safe-buffer@^5.0.1, safe-buffer@5.1.2:
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-safe-buffer@^5.2.1:
- version "5.2.1"
- resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
- integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
@@ -5108,11 +4660,6 @@ semver@^6.3.0:
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-semver@^7.2:
- version "7.6.3"
- resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz"
- integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
-
semver@^7.3.5:
version "7.6.3"
resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz"
@@ -5137,19 +4684,10 @@ semver@^7.6.0:
resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
-semver@~7.5.0:
- version "7.5.4"
- resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz"
- integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
- dependencies:
- lru-cache "^6.0.0"
-
-semver@~7.5.4:
- version "7.5.4"
- resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz"
- integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
- dependencies:
- lru-cache "^6.0.0"
+"semver@>= 5 < 6":
+ version "5.7.2"
+ resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
serve-handler@6.1.6:
version "6.1.6"
@@ -5193,11 +4731,6 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shimmer@^1.2.0:
- version "1.2.1"
- resolved "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz"
- integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
-
signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
@@ -5243,6 +4776,11 @@ sisteransi@^1.0.5:
resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz"
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
+skip-postinstall@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/skip-postinstall/-/skip-postinstall-1.0.0.tgz"
+ integrity sha512-IUVEmm4v7Ubzrp9JDG15oTzMB+abJdHcduXMRzBlHnHRrmpQ/QoPtYCRaorP+abAULTGEh87gPPyyMK5H1X1Dg==
+
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
@@ -5253,7 +4791,7 @@ smart-buffer@^4.2.0:
resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
-socks-proxy-agent@^8.0.2, socks-proxy-agent@^8.0.3, socks-proxy-agent@^8.0.5:
+socks-proxy-agent@^8.0.3:
version "8.0.5"
resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz"
integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==
@@ -5278,15 +4816,7 @@ source-map-support@0.5.13:
buffer-from "^1.0.0"
source-map "^0.6.0"
-source-map-support@0.5.21:
- version "0.5.21"
- resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz"
- integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -5301,11 +4831,6 @@ sprintf-js@~1.0.2:
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
-sprintf-js@1.1.2:
- version "1.1.2"
- resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
- integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
srcset@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz"
@@ -5444,11 +4969,6 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
-systeminformation@^5.7:
- version "5.24.6"
- resolved "https://registry.npmjs.org/systeminformation/-/systeminformation-5.24.6.tgz"
- integrity sha512-zxmlzFvPVxlUWmDZX1PK8iUf31/BzrDiAqiTcUwhSGw74D8VWm+ikgBTa38eb5We6o5bZHA4RsTPfYzmDbGvWQ==
-
table2array@^0.0.2:
version "0.0.2"
resolved "https://registry.npmjs.org/table2array/-/table2array-0.0.2.tgz"
@@ -5576,20 +5096,6 @@ ts-api-utils@^1.3.0:
resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz"
integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==
-ts-jest@^29.1.1:
- version "29.1.1"
- resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz"
- integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==
- dependencies:
- bs-logger "0.x"
- fast-json-stable-stringify "2.x"
- jest-util "^29.0.0"
- json5 "^2.2.3"
- lodash.memoize "4.x"
- make-error "1.x"
- semver "^7.5.3"
- yargs-parser "^21.0.1"
-
ts-node@>=9.0.0:
version "10.9.1"
resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz"
@@ -5609,16 +5115,11 @@ ts-node@>=9.0.0:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
-tslib@^2.0.1, tslib@^2.1.0:
+tslib@^2.1.0:
version "2.6.2"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
-tslib@1.9.3:
- version "1.9.3"
- resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz"
- integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
-
tsx@^4.19.2:
version "4.19.2"
resolved "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz"
@@ -5636,18 +5137,6 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
-tv4@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz"
- integrity sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==
-
-tx2@~1.0.4:
- version "1.0.5"
- resolved "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz"
- integrity sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==
- dependencies:
- json-stringify-safe "^5.0.1"
-
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
@@ -5670,7 +5159,7 @@ type-fest@^2.13.0:
resolved "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz"
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
-typescript@>=2.7, typescript@>=4.2.0, "typescript@>=4.3 <6", "typescript@>=4.8.4 <5.8.0":
+typescript@>=2.7, typescript@>=4.2.0, "typescript@>=4.8.4 <5.8.0":
version "5.2.2"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz"
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
@@ -5758,16 +5247,6 @@ vary@~1.1.2:
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
-vizion@~2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz"
- integrity sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==
- dependencies:
- async "^2.6.3"
- git-node-fs "^1.0.0"
- ini "^1.3.5"
- js-git "^0.7.8"
-
walker@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz"
@@ -5891,11 +5370,6 @@ write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
-ws@^7.0.0, ws@~7.5.10:
- version "7.5.10"
- resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz"
- integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==
-
xml-js@^1.6.11:
version "1.6.11"
resolved "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz"
@@ -5923,11 +5397,6 @@ yargs-parser@^20.2.2:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-yargs-parser@^21.0.1:
- version "21.1.1"
- resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
- integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"