` 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.
+- `channels:lint`: сhecks the channel lists for syntax errors.
+- `channels:parse`: generates a list of channels based on the site configuration.
+- `channels:parse`: formats `*.channels.xml` files. The process involves removing invalid `xmltv_id`, adding missing Feed ID, and sorting the list.
+- `channels:edit`: utility for quick channels mapping.
+- `channels:validate`: checks the description of channels for errors.
+- `sites:init`: creates a new site config from the template.
+- `sites:update`: updates the list of sites and their status in [SITES.md](SITES.md).
+- `grab`: downloads a program from a specified source.
+- `serve`: starts the [web server](https://github.com/vercel/serve).
+- `lint`: сhecks the scripts for syntax errors.
+- `test`: runs a test of all the scripts described above.
diff --git a/README.md b/README.md
index 626c1cba..e1d4fe47 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ After that open the [Console](https://en.wikipedia.org/wiki/Windows_Console) (or
git clone --depth 1 -b master https://github.com/iptv-org/epg.git
```
-Then navigate to the downloaded `epg` folder:
+This will copy all the code from the repository to your computer into the `epg` folder. After that, we just need to go to the folder we created:
```sh
cd epg
@@ -76,7 +76,7 @@ By default, the guide for each channel is downloaded one by one, but you can cha
npm run grab --- --site=example.com --maxConnections=10
```
-But be aware that under heavy load, some sites may start return an error or completely block your access.
+But be aware that under heavy load some sites may start return an error or completely block your access.
### Use custom channel list
@@ -98,7 +98,7 @@ npm run grab --- --channels=path/to/custom.channels.xml
### Run on schedule
-If you want to download guides on a schedule, you can use [cron](https://en.wikipedia.org/wiki/Cron) or any other task scheduler. Currently, we use a tool called `chronos` for this purpose.
+If you want to download guides on a schedule, you can use [cron](https://en.wikipedia.org/wiki/Cron) or any other task scheduler. Currently, we use a tool called [chronos](https://github.com/freearhey/chronos) for this purpose.
To start it, you only need to specify the necessary `grab` command and [cron expression](https://crontab.guru/):
@@ -188,7 +188,7 @@ docker run \
-e DAYS=14 \
-e TIMEOUT=5 \
-e DELAY=2 \
-iptv-org/epg
+ghcr.io/iptv-org/epg:master
```
| Variable | Description |
diff --git a/SITES.md b/SITES.md
index 1d86bef2..a9da004c 100644
--- a/SITES.md
+++ b/SITES.md
@@ -65,7 +65,7 @@
| gigatv.3bbtv.co.th | 79 | 38 | 🟢 | |
| guiadetv.com | 124 | 0 | 🟢 | |
| guida.tv | 88 | 88 | 🟢 | |
- | guidatv.sky.it | 154 | 154 | 🟢 | https://github.com/iptv-org/epg/issues/2849 |
+ | guidatv.sky.it | 154 | 154 | 🟢 | |
| guidetnt.com | 69 | 69 | 🟢 | |
| horizon.tv | 184 | 172 | 🟢 | |
| hoy.tv | 3 | 1 | 🟢 | |
@@ -93,7 +93,7 @@
| meuguia.tv | 102 | 97 | 🟢 | |
| mewatch.sg | 25 | 24 | 🟢 | |
| mi.tv | 2084 | 620 | 🟢 | |
- | mncvision.id | 276 | 223 | 🟢 | https://github.com/iptv-org/epg/issues/2848 |
+ | mncvision.id | 276 | 223 | 🟢 | |
| moji.id | 1 | 1 | 🟢 | |
| mojmaxtv.hrvatskitelekom.hr | 243 | 0 | 🟢 | |
| mon-programme-tv.be | 111 | 95 | 🟢 | |
@@ -101,7 +101,7 @@
| mtel.ba | 501 | 0 | 🟢 | |
| mts.rs | 457 | 0 | 🟢 | |
| mujtvprogram.cz | 216 | 202 | 🟢 | |
- | musor.tv | 181 | 145 | 🟢 | |
+ | musor.tv | 181 | 143 | 🟢 | |
| mysky.com.ph | 115 | 43 | 🟢 | |
| mytelly.co.uk | 488 | 401 | 🟢 | |
| mytvsuper.com | 108 | 99 | 🟢 | |
@@ -143,12 +143,12 @@
| ruv.is | 2 | 2 | 🟢 | |
| s.mxtv.jp | 2 | 2 | 🟢 | |
| sat.tv | 30308 | 249 | 🟢 | |
- | shahid.mbc.net | 225 | 183 | 🟢 | |
+ | shahid.mbc.net | 228 | 186 | 🟢 | |
| siba.com.co | 98 | 96 | 🟢 | |
| singtel.com | 155 | 113 | 🟢 | |
| sjonvarp.is | 13 | 13 | 🟢 | |
| sky.co.nz | 111 | 93 | 🟢 | |
- | sky.com | 559 | 458 | 🟡 | https://github.com/iptv-org/epg/issues/2763 |
+ | sky.com | 542 | 489 | 🟡 | https://github.com/iptv-org/epg/issues/2763 |
| sky.de | 75 | 75 | 🟢 | |
| skylife.co.kr | 251 | 0 | 🔴 | https://github.com/iptv-org/epg/issues/2845 |
| skyperfectv.co.jp | 137 | 130 | 🟢 | |
diff --git a/package-lock.json b/package-lock.json
index f99859f6..505bc805 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,35 +10,34 @@
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "^9.38.0",
+ "@eslint/js": "^9.33.0",
"@freearhey/chronos": "^0.0.1",
- "@freearhey/core": "^0.14.3",
- "@freearhey/search-js": "^0.2.0",
- "@freearhey/storage-js": "^0.2.0",
+ "@freearhey/core": "^0.10.3",
+ "@freearhey/search-js": "^0.1.2",
"@ntlab/sfetch": "^1.2.0",
- "@octokit/core": "^7.0.5",
- "@octokit/plugin-paginate-rest": "^13.2.1",
- "@octokit/plugin-rest-endpoint-methods": "^16.1.1",
- "@stylistic/eslint-plugin": "^5.5.0",
- "@swc/core": "^1.13.5",
+ "@octokit/core": "^7.0.3",
+ "@octokit/plugin-paginate-rest": "^13.1.1",
+ "@octokit/plugin-rest-endpoint-methods": "^16.0.0",
+ "@stylistic/eslint-plugin": "^5.2.3",
+ "@swc/core": "^1.13.3",
"@swc/jest": "^0.2.39",
"@types/cli-progress": "^3.11.6",
"@types/fs-extra": "^11.0.4",
- "@types/inquirer": "^9.0.9",
+ "@types/inquirer": "^9.0.8",
"@types/jest": "^30.0.0",
"@types/langs": "^2.0.5",
"@types/lodash.orderby": "^4.6.9",
"@types/lodash.sortby": "^4.7.9",
"@types/lodash.startcase": "^4.4.9",
"@types/lodash.uniqby": "^4.7.9",
- "@types/node": "^24.9.1",
+ "@types/node": "^24.3.0",
"@types/node-cleanup": "^2.1.5",
"@types/numeral": "^2.0.5",
- "@typescript-eslint/eslint-plugin": "^8.46.2",
- "@typescript-eslint/parser": "^8.46.2",
- "axios": "^1.12.2",
+ "@typescript-eslint/eslint-plugin": "^8.40.0",
+ "@typescript-eslint/parser": "^8.40.0",
+ "axios": "^1.11.0",
"axios-cookiejar-support": "^6.0.4",
- "chalk": "^5.6.2",
+ "chalk": "^5.6.0",
"cheerio": "^1.1.2",
"cli-progress": "^3.12.0",
"commander": "^14.0.1",
@@ -46,22 +45,22 @@
"cross-env": "^10.1.0",
"csv-parser": "^3.2.0",
"cwait": "^1.1.2",
- "dayjs": "^1.11.18",
- "epg-grabber": "^0.44.0",
+ "dayjs": "^1.11.13",
+ "epg-grabber": "^0.41.0",
"epg-parser": "^0.4.0",
- "eslint": "^9.38.0",
+ "eslint": "^9.33.0",
"eslint-config-prettier": "^10.1.8",
"form-data": "^4.0.4",
- "fs-extra": "^11.3.2",
+ "fs-extra": "^11.3.1",
"glob": "^11.0.3",
"globals": "^16.4.0",
"husky": "^9.1.7",
"iconv-lite": "^0.7.0",
- "inquirer": "^12.10.0",
- "jest": "^30.2.0",
+ "inquirer": "^12.9.3",
+ "jest": "^30.0.5",
"jest-offline": "^1.0.1",
"langs": "^2.0.0",
- "libxml2-wasm": "^0.6.0",
+ "libxml2-wasm": "^0.5.0",
"lodash.orderby": "^4.6.0",
"lodash.sortby": "^4.7.0",
"lodash.startcase": "^4.4.0",
@@ -84,10 +83,10 @@
"srcset": "^5.0.2",
"table2array": "^0.0.2",
"tabletojson": "^4.1.6",
- "tough-cookie": "^6.0.0",
+ "tough-cookie": "^5.1.2",
"transliteration": "^2.3.5",
- "tsx": "^4.20.6",
- "typescript": "^5.9.3",
+ "tsx": "^4.20.4",
+ "typescript": "^5.9.2",
"unzipit": "^1.4.3",
"uuid": "^13.0.0",
"wildcard-match": "^5.1.4"
@@ -594,11 +593,11 @@
}
},
"node_modules/@dabh/diagnostics": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
- "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
+ "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
"dependencies": {
- "colorspace": "1.1.x",
+ "@so-ric/colorspace": "^1.1.6",
"enabled": "2.0.x",
"kuler": "^2.0.0"
}
@@ -1055,21 +1054,18 @@
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz",
- "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==",
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
"license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.16.0"
- },
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
- "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
@@ -1129,9 +1125,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.38.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz",
- "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==",
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz",
+ "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1150,12 +1146,12 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz",
- "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^0.16.0",
+ "@eslint/core": "^0.15.2",
"levn": "^0.4.1"
},
"engines": {
@@ -1176,10 +1172,9 @@
}
},
"node_modules/@freearhey/core": {
- "version": "0.14.3",
- "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.14.3.tgz",
- "integrity": "sha512-w/kaoUdZlbqvOSOmid0nrBI9iGZkUZ+KLZUfkWpfZRPXOEu/FxlEP5gPANGgovwijrgogAbVf/qnf9VV+429ag==",
- "license": "MIT",
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.10.3.tgz",
+ "integrity": "sha512-in5wgFHo+PJF585TXpaPLInlsgXuDLbUpXfcWrctd17mJpNNr5Mt5DetpzBqSqLERgh2jxxGRHyPGhm3Yl02hQ==",
"dependencies": {
"@types/lodash": "^4.14.198",
"@types/pako": "^2.0.3",
@@ -1206,17 +1201,6 @@
"node": ">=16.0.0"
}
},
- "node_modules/@freearhey/storage-js": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@freearhey/storage-js/-/storage-js-0.2.0.tgz",
- "integrity": "sha512-IPFeOqE6/N8CdCxld5q4/eYR71eysn3FOizRmN3PGLUcnR3QiMjoYC/CwKFJYGuYs1CTK8pGTvik4d/WqIiDqg==",
- "license": "MIT",
- "dependencies": {
- "@types/fs-extra": "^11.0.4",
- "fs-extra": "^11.3.1",
- "glob": "^11.0.3"
- }
- },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -1284,9 +1268,9 @@
}
},
"node_modules/@inquirer/checkbox": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz",
- "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.1.tgz",
+ "integrity": "sha512-bevKGO6kX1eM/N+pdh9leS5L7TBF4ICrzi9a+cbWkrxeAeIcwlo/7OfWGCDERdRCI2/Q6tjltX4bt07ALHDwFw==",
"license": "MIT",
"dependencies": {
"@inquirer/ansi": "^1.0.1",
@@ -1308,9 +1292,9 @@
}
},
"node_modules/@inquirer/confirm": {
- "version": "5.1.19",
- "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz",
- "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==",
+ "version": "5.1.15",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.15.tgz",
+ "integrity": "sha512-SwHMGa8Z47LawQN0rog0sT+6JpiL0B7eW9p1Bb7iCeKDGTI5Ez25TSc2l8kw52VV7hA4sX/C78CGkMrKXfuspA==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1329,9 +1313,9 @@
}
},
"node_modules/@inquirer/core": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz",
- "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==",
+ "version": "10.1.15",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.15.tgz",
+ "integrity": "sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==",
"license": "MIT",
"dependencies": {
"@inquirer/ansi": "^1.0.1",
@@ -1359,7 +1343,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
"integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
- "license": "ISC",
"engines": {
"node": "^18.17.0 || >=20.5.0"
}
@@ -1368,7 +1351,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "license": "ISC",
"engines": {
"node": ">=14"
},
@@ -1377,9 +1359,9 @@
}
},
"node_modules/@inquirer/editor": {
- "version": "4.2.21",
- "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz",
- "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==",
+ "version": "4.2.17",
+ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.17.tgz",
+ "integrity": "sha512-r6bQLsyPSzbWrZZ9ufoWL+CztkSatnJ6uSxqd6N+o41EZC51sQeWOzI6s5jLb+xxTWxl7PlUppqm8/sow241gg==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1399,9 +1381,9 @@
}
},
"node_modules/@inquirer/expand": {
- "version": "4.0.21",
- "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz",
- "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==",
+ "version": "4.0.17",
+ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.17.tgz",
+ "integrity": "sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1421,9 +1403,9 @@
}
},
"node_modules/@inquirer/external-editor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz",
- "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz",
+ "integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==",
"license": "MIT",
"dependencies": {
"chardet": "^2.1.0",
@@ -1442,18 +1424,18 @@
}
},
"node_modules/@inquirer/figures": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz",
- "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==",
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz",
+ "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/input": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz",
- "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.1.tgz",
+ "integrity": "sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1472,9 +1454,9 @@
}
},
"node_modules/@inquirer/number": {
- "version": "3.0.21",
- "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz",
- "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==",
+ "version": "3.0.17",
+ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.17.tgz",
+ "integrity": "sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1493,9 +1475,9 @@
}
},
"node_modules/@inquirer/password": {
- "version": "4.0.21",
- "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz",
- "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==",
+ "version": "4.0.17",
+ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.17.tgz",
+ "integrity": "sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==",
"license": "MIT",
"dependencies": {
"@inquirer/ansi": "^1.0.1",
@@ -1515,21 +1497,21 @@
}
},
"node_modules/@inquirer/prompts": {
- "version": "7.9.0",
- "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz",
- "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==",
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.3.tgz",
+ "integrity": "sha512-iHYp+JCaCRktM/ESZdpHI51yqsDgXu+dMs4semzETftOaF8u5hwlqnbIsuIR/LrWZl8Pm1/gzteK9I7MAq5HTA==",
"license": "MIT",
"dependencies": {
- "@inquirer/checkbox": "^4.3.0",
- "@inquirer/confirm": "^5.1.19",
- "@inquirer/editor": "^4.2.21",
- "@inquirer/expand": "^4.0.21",
- "@inquirer/input": "^4.2.5",
- "@inquirer/number": "^3.0.21",
- "@inquirer/password": "^4.0.21",
- "@inquirer/rawlist": "^4.1.9",
- "@inquirer/search": "^3.2.0",
- "@inquirer/select": "^4.4.0"
+ "@inquirer/checkbox": "^4.2.1",
+ "@inquirer/confirm": "^5.1.15",
+ "@inquirer/editor": "^4.2.17",
+ "@inquirer/expand": "^4.0.17",
+ "@inquirer/input": "^4.2.1",
+ "@inquirer/number": "^3.0.17",
+ "@inquirer/password": "^4.0.17",
+ "@inquirer/rawlist": "^4.1.5",
+ "@inquirer/search": "^3.1.0",
+ "@inquirer/select": "^4.3.1"
},
"engines": {
"node": ">=18"
@@ -1544,9 +1526,9 @@
}
},
"node_modules/@inquirer/rawlist": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz",
- "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.5.tgz",
+ "integrity": "sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1566,9 +1548,9 @@
}
},
"node_modules/@inquirer/search": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz",
- "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.1.0.tgz",
+ "integrity": "sha512-PMk1+O/WBcYJDq2H7foV0aAZSmDdkzZB9Mw2v/DmONRJopwA/128cS9M/TXWLKKdEQKZnKwBzqu2G4x/2Nqx8Q==",
"license": "MIT",
"dependencies": {
"@inquirer/core": "^10.3.0",
@@ -1589,9 +1571,9 @@
}
},
"node_modules/@inquirer/select": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz",
- "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.3.1.tgz",
+ "integrity": "sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==",
"license": "MIT",
"dependencies": {
"@inquirer/ansi": "^1.0.1",
@@ -1613,9 +1595,9 @@
}
},
"node_modules/@inquirer/type": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz",
- "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz",
+ "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -1629,6 +1611,47 @@
}
}
},
+ "node_modules/@iptv-org/sdk": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@iptv-org/sdk/-/sdk-1.1.0.tgz",
+ "integrity": "sha512-/lEIcWGmbBSWWgS8uOKEFdfGBYPlEOcDrETHqU4k3VxsnggL46mvIsA8+ZvCV5Fa3sADD2ded5FfjDmYhoX2DA==",
+ "dependencies": {
+ "@freearhey/core": "^0.14.3",
+ "@freearhey/search-js": "^0.2.0",
+ "@ntlab/sfetch": "^1.2.0",
+ "axios": "^1.11.0",
+ "dayjs": "^1.11.18"
+ }
+ },
+ "node_modules/@iptv-org/sdk/node_modules/@freearhey/core": {
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.14.3.tgz",
+ "integrity": "sha512-w/kaoUdZlbqvOSOmid0nrBI9iGZkUZ+KLZUfkWpfZRPXOEu/FxlEP5gPANGgovwijrgogAbVf/qnf9VV+429ag==",
+ "dependencies": {
+ "@types/lodash": "^4.14.198",
+ "@types/pako": "^2.0.3",
+ "consola": "^3.4.2",
+ "dayjs": "^1.11.13",
+ "glob": "^11.0.1",
+ "lodash": "^4.17.21",
+ "natural-orderby": "^5.0.0",
+ "normalize-url": "^8.1.0",
+ "object-treeify": "^2.1.1",
+ "pako": "^2.1.0",
+ "timer-node": "^5.0.9"
+ }
+ },
+ "node_modules/@iptv-org/sdk/node_modules/@freearhey/search-js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@freearhey/search-js/-/search-js-0.2.0.tgz",
+ "integrity": "sha512-1sxfCRbxM12Js3nM/S51cVKLYEjoksERidz539bleMAXes44eTC2m0TEQTJzJyE7l1pw2qUwsIhjd2l2l88fSw==",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
@@ -2859,7 +2882,6 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -2872,7 +2894,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "license": "MIT",
"engines": {
"node": ">= 8"
}
@@ -2881,7 +2902,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
@@ -3119,17 +3139,6 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC"
},
- "node_modules/@pm2/blessed": {
- "version": "0.1.81",
- "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz",
- "integrity": "sha512-ZcNHqQjMuNRcQ7Z1zJbFIQZO/BDKV3KbiTckWdfbUaYhj7uNmUwb+FbdDWSCkvxNr9dBJQwvV17o6QBkAvgO0g==",
- "bin": {
- "blessed": "bin/tput.js"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
"node_modules/@pm2/io": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz",
@@ -3278,14 +3287,23 @@
"@sinonjs/commons": "^3.0.1"
}
},
+ "node_modules/@so-ric/colorspace": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
+ "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==",
+ "dependencies": {
+ "color": "^5.0.2",
+ "text-hex": "1.0.x"
+ }
+ },
"node_modules/@stylistic/eslint-plugin": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
- "integrity": "sha512-IeZF+8H0ns6prg4VrkhgL+yrvDXWDH2cKchrbh80ejG9dQgZWp10epHMbgRuQvgchLII/lfh6Xn3lu6+6L86Hw==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.2.3.tgz",
+ "integrity": "sha512-oY7GVkJGVMI5benlBDCaRrSC1qPasafyv5dOBLLv5MTilMGnErKhO6ziEfodDDIZbo5QxPUNW360VudJOFODMw==",
"license": "MIT",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.9.0",
- "@typescript-eslint/types": "^8.46.1",
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/types": "^8.38.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"estraverse": "^5.3.0",
@@ -3321,11 +3339,10 @@
}
},
"node_modules/@swc/core": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz",
- "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.3.tgz",
+ "integrity": "sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==",
"hasInstallScript": true,
- "license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.24"
@@ -3338,16 +3355,16 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
- "@swc/core-darwin-arm64": "1.13.5",
- "@swc/core-darwin-x64": "1.13.5",
- "@swc/core-linux-arm-gnueabihf": "1.13.5",
- "@swc/core-linux-arm64-gnu": "1.13.5",
- "@swc/core-linux-arm64-musl": "1.13.5",
- "@swc/core-linux-x64-gnu": "1.13.5",
- "@swc/core-linux-x64-musl": "1.13.5",
- "@swc/core-win32-arm64-msvc": "1.13.5",
- "@swc/core-win32-ia32-msvc": "1.13.5",
- "@swc/core-win32-x64-msvc": "1.13.5"
+ "@swc/core-darwin-arm64": "1.13.3",
+ "@swc/core-darwin-x64": "1.13.3",
+ "@swc/core-linux-arm-gnueabihf": "1.13.3",
+ "@swc/core-linux-arm64-gnu": "1.13.3",
+ "@swc/core-linux-arm64-musl": "1.13.3",
+ "@swc/core-linux-x64-gnu": "1.13.3",
+ "@swc/core-linux-x64-musl": "1.13.3",
+ "@swc/core-win32-arm64-msvc": "1.13.3",
+ "@swc/core-win32-ia32-msvc": "1.13.3",
+ "@swc/core-win32-x64-msvc": "1.13.3"
},
"peerDependencies": {
"@swc/helpers": ">=0.5.17"
@@ -3359,13 +3376,12 @@
}
},
"node_modules/@swc/core-darwin-arm64": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz",
- "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.3.tgz",
+ "integrity": "sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==",
"cpu": [
"arm64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
@@ -3375,13 +3391,12 @@
}
},
"node_modules/@swc/core-darwin-x64": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz",
- "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.3.tgz",
+ "integrity": "sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==",
"cpu": [
"x64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
@@ -3391,13 +3406,12 @@
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz",
- "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.3.tgz",
+ "integrity": "sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==",
"cpu": [
"arm"
],
- "license": "Apache-2.0",
"optional": true,
"os": [
"linux"
@@ -3407,13 +3421,12 @@
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz",
- "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.3.tgz",
+ "integrity": "sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==",
"cpu": [
"arm64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@@ -3423,13 +3436,12 @@
}
},
"node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz",
- "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.3.tgz",
+ "integrity": "sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==",
"cpu": [
"arm64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@@ -3439,13 +3451,12 @@
}
},
"node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz",
- "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.3.tgz",
+ "integrity": "sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==",
"cpu": [
"x64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@@ -3455,13 +3466,12 @@
}
},
"node_modules/@swc/core-linux-x64-musl": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz",
- "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.3.tgz",
+ "integrity": "sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==",
"cpu": [
"x64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@@ -3471,13 +3481,12 @@
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz",
- "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.3.tgz",
+ "integrity": "sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==",
"cpu": [
"arm64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@@ -3487,13 +3496,12 @@
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz",
- "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.3.tgz",
+ "integrity": "sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==",
"cpu": [
"ia32"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@@ -3503,13 +3511,12 @@
}
},
"node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz",
- "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.3.tgz",
+ "integrity": "sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==",
"cpu": [
"x64"
],
- "license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@@ -3611,6 +3618,11 @@
"integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==",
"license": "MIT"
},
+ "node_modules/@types/bluebird": {
+ "version": "3.5.42",
+ "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz",
+ "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A=="
+ },
"node_modules/@types/cli-progress": {
"version": "3.11.6",
"resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.6.tgz",
@@ -3636,9 +3648,9 @@
}
},
"node_modules/@types/inquirer": {
- "version": "9.0.9",
- "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.9.tgz",
- "integrity": "sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==",
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.8.tgz",
+ "integrity": "sha512-CgPD5kFGWsb8HJ5K7rfWlifao87m4ph8uioU7OTncJevmE/VLIqAAjfQtko578JZg7/f69K4FgqYym3gNr7DeA==",
"license": "MIT",
"dependencies": {
"@types/through": "*",
@@ -3742,12 +3754,12 @@
}
},
"node_modules/@types/node": {
- "version": "24.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
- "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
+ "version": "24.3.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
+ "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
"license": "MIT",
"dependencies": {
- "undici-types": "~7.16.0"
+ "undici-types": "~7.10.0"
}
},
"node_modules/@types/node-cleanup": {
@@ -3762,12 +3774,6 @@
"integrity": "sha512-kH8I7OSSwQu9DS9JYdFWbuvhVzvFRoCPCkGxNwoGgaPeDfEPJlcxNvEOypZhQ3XXHsGbfIuYcxcJxKUfJHnRfw==",
"license": "MIT"
},
- "node_modules/@types/pako": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.4.tgz",
- "integrity": "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==",
- "license": "MIT"
- },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -3802,16 +3808,16 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz",
- "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.40.0.tgz",
+ "integrity": "sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==",
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/type-utils": "8.46.2",
- "@typescript-eslint/utils": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/type-utils": "8.40.0",
+ "@typescript-eslint/utils": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -3825,9 +3831,9 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.46.2",
+ "@typescript-eslint/parser": "^8.40.0",
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
@@ -3840,15 +3846,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz",
- "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.40.0.tgz",
+ "integrity": "sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"debug": "^4.3.4"
},
"engines": {
@@ -3860,17 +3866,17 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/project-service": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz",
- "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.40.0.tgz",
+ "integrity": "sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.46.2",
- "@typescript-eslint/types": "^8.46.2",
+ "@typescript-eslint/tsconfig-utils": "^8.40.0",
+ "@typescript-eslint/types": "^8.40.0",
"debug": "^4.3.4"
},
"engines": {
@@ -3881,17 +3887,17 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz",
- "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.40.0.tgz",
+ "integrity": "sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2"
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3902,9 +3908,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz",
- "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.40.0.tgz",
+ "integrity": "sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3914,18 +3920,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz",
- "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.40.0.tgz",
+ "integrity": "sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2",
- "@typescript-eslint/utils": "8.46.2",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0",
+ "@typescript-eslint/utils": "8.40.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -3938,13 +3944,13 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz",
- "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.40.0.tgz",
+ "integrity": "sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3955,15 +3961,15 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz",
- "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.40.0.tgz",
+ "integrity": "sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.46.2",
- "@typescript-eslint/tsconfig-utils": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/project-service": "8.40.0",
+ "@typescript-eslint/tsconfig-utils": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -3979,14 +3985,13 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -3995,7 +4000,6 @@
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -4007,15 +4011,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz",
- "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.40.0.tgz",
+ "integrity": "sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==",
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2"
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4026,16 +4030,16 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz",
- "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.40.0.tgz",
+ "integrity": "sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.46.2",
+ "@typescript-eslint/types": "8.40.0",
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
@@ -4050,7 +4054,6 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -4317,8 +4320,7 @@
"node_modules/@zeit/schemas": {
"version": "2.36.0",
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz",
- "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==",
- "license": "MIT"
+ "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg=="
},
"node_modules/acorn": {
"version": "8.15.0",
@@ -4382,7 +4384,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
"integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
- "license": "ISC",
"dependencies": {
"string-width": "^4.1.0"
}
@@ -4470,14 +4471,12 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "license": "MIT"
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
},
"node_modules/argparse": {
"version": "1.0.10",
@@ -4537,10 +4536,9 @@
}
},
"node_modules/axios-cache-interceptor": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.3.tgz",
- "integrity": "sha512-ifuSBoCEkVaiugg1UTjVuTdK+SjSOJ35pdv2OrzhRT3wDMr52QiayQxUqs7jd7GDsfPOjMcw3T3ek0TysbyZZw==",
- "license": "MIT",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.0.tgz",
+ "integrity": "sha512-cTNnPGJyQkxnWp0EWvE3NRvgURU5cWw/Qx3dIhXyHSM4Ip0c7EEe0I3an0Jwa549m1CAOg57ibj27YRNLmQCcg==",
"dependencies": {
"cache-parser": "1.2.5",
"fast-defer": "1.1.8",
@@ -4574,30 +4572,6 @@
"tough-cookie": ">=4.0.0"
}
},
- "node_modules/axios-cookiejar-support/node_modules/http-cookie-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.2.tgz",
- "integrity": "sha512-aHaES6SOFtnSlmWu0yEaaQvu+QexUG2gscSAvMhJ7auzW8r/jYOgGrzuAm9G9nHbksuhz7Lw4zOwDHmfQaxZvw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.4"
- },
- "engines": {
- "node": ">=20.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/3846masa"
- },
- "peerDependencies": {
- "tough-cookie": "^4.0.0 || ^5.0.0",
- "undici": "^7.0.0"
- },
- "peerDependenciesMeta": {
- "undici": {
- "optional": true
- }
- }
- },
"node_modules/babel-jest": {
"version": "30.2.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
@@ -4748,12 +4722,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/bluebird": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
- "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
- "license": "MIT"
- },
"node_modules/bodec": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz",
@@ -4768,7 +4736,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz",
"integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==",
- "license": "MIT",
"dependencies": {
"ansi-align": "^3.0.1",
"camelcase": "^7.0.0",
@@ -4787,10 +4754,9 @@
}
},
"node_modules/boxen/node_modules/ansi-regex": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz",
- "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==",
- "license": "MIT",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"engines": {
"node": ">=12"
},
@@ -4802,7 +4768,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "license": "MIT",
"engines": {
"node": ">=12"
},
@@ -4814,7 +4779,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
"integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
- "license": "MIT",
"engines": {
"node": ">=14.16"
},
@@ -4825,14 +4789,12 @@
"node_modules/boxen/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "license": "MIT"
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"node_modules/boxen/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
@@ -4846,10 +4808,9 @@
}
},
"node_modules/boxen/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "license": "MIT",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
+ "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
@@ -4864,7 +4825,6 @@
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
- "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=12.20"
},
@@ -4876,7 +4836,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
@@ -4961,7 +4920,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
- "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -5062,9 +5020,9 @@
"integrity": "sha512-z0R4cT5357OEAVkP1CEFTHz1egpu2gYiWm2WJOY/sQDhojEXUYL4m3v2kYi5wER3PkMRL+GgfDhed2kGzrHSZA=="
},
"node_modules/chalk": {
- "version": "5.6.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
- "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
+ "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -5077,7 +5035,6 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
"integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
- "license": "MIT",
"dependencies": {
"chalk": "^4.1.2"
},
@@ -5116,8 +5073,7 @@
"node_modules/chardet": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz",
- "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==",
- "license": "MIT"
+ "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA=="
},
"node_modules/charm": {
"version": "0.1.2",
@@ -5223,7 +5179,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
"integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
- "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -5269,7 +5224,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
- "license": "ISC",
"engines": {
"node": ">= 12"
}
@@ -5278,7 +5232,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz",
"integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==",
- "license": "MIT",
"dependencies": {
"arch": "^2.2.0",
"execa": "^5.1.1",
@@ -5339,12 +5292,15 @@
"license": "MIT"
},
"node_modules/color": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
- "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/color/-/color-5.0.2.tgz",
+ "integrity": "sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA==",
"dependencies": {
- "color-convert": "^1.9.3",
- "color-string": "^1.6.0"
+ "color-convert": "^3.0.1",
+ "color-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/color-convert": {
@@ -5364,34 +5320,41 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.2.tgz",
+ "integrity": "sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA==",
"dependencies": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
+ "color-name": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/color-string/node_modules/color-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
+ "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "engines": {
+ "node": ">=12.20"
}
},
"node_modules/color/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.2.tgz",
+ "integrity": "sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg==",
"dependencies": {
- "color-name": "1.1.3"
+ "color-name": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.6"
}
},
"node_modules/color/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
- "node_modules/colorspace": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
- "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
- "dependencies": {
- "color": "^3.1.3",
- "text-hex": "1.0.x"
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
+ "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==",
+ "engines": {
+ "node": ">=12.20"
}
},
"node_modules/combined-stream": {
@@ -5481,7 +5444,6 @@
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==",
- "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -5596,10 +5558,9 @@
}
},
"node_modules/dayjs": {
- "version": "1.11.18",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz",
- "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
- "license": "MIT"
+ "version": "1.11.15",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.15.tgz",
+ "integrity": "sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ=="
},
"node_modules/debug": {
"version": "4.3.4",
@@ -5640,7 +5601,6 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -5819,18 +5779,6 @@
"url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
}
},
- "node_modules/encoding-sniffer/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -5854,10 +5802,9 @@
}
},
"node_modules/epg-grabber": {
- "version": "0.44.0",
- "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.44.0.tgz",
- "integrity": "sha512-M4k/PG1/OIbHV7p8rM23yDWig6WwtpB/LafRzealc8A50HDOGskmkvuhzxf1S34Oe8xL3aU529oW2vocrpijuA==",
- "license": "MIT",
+ "version": "0.41.0",
+ "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.41.0.tgz",
+ "integrity": "sha512-975WApyNb/ICZWYHxE2i/MDSDQOWZN0F+VARWZR1eFJovAs2CffQXJnG2Qx28RG312M3I+B+GkyPv2GxKxhQCA==",
"dependencies": {
"@freearhey/core": "^0.14.0",
"@types/bluebird": "^3.5.42",
@@ -5883,17 +5830,27 @@
"epg-grabber": "dist/cli.js"
},
"engines": {
- "node": ">=22.12.0"
+ "node": ">=10.0.0"
}
},
- "node_modules/epg-parser": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.4.0.tgz",
- "integrity": "sha512-SynflAhgfrgFjFnMVggIjzgLpg7EANYymy4Q1OBiaMcEYSaIjp8iw36djam8/4B7htaNPa5ckIQ+4TUwEc0pdA==",
+ "node_modules/epg-grabber/node_modules/epg-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz",
+ "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==",
"license": "MIT",
"dependencies": {
"dayjs": "^1.11.6",
- "lodash.groupby": "^4.6.0",
+ "lodash": "^4.17.21",
+ "xml-js": "^1.6.11"
+ }
+ },
+ "node_modules/epg-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz",
+ "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==",
+ "dependencies": {
+ "dayjs": "^1.11.6",
+ "lodash": "^4.17.21",
"xml-js": "^1.6.11"
}
},
@@ -6028,19 +5985,19 @@
}
},
"node_modules/eslint": {
- "version": "9.38.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz",
- "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz",
+ "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==",
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.1",
- "@eslint/config-helpers": "^0.4.1",
- "@eslint/core": "^0.16.0",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.38.0",
- "@eslint/plugin-kit": "^0.4.0",
+ "@eslint/js": "9.33.0",
+ "@eslint/plugin-kit": "^0.3.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -6384,7 +6341,6 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -6400,7 +6356,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -6428,7 +6383,6 @@
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
- "license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
}
@@ -6588,9 +6542,9 @@
}
},
"node_modules/fs-extra": {
- "version": "11.3.2",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
- "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz",
+ "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
@@ -6919,6 +6873,29 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/http-cookie-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.2.tgz",
+ "integrity": "sha512-aHaES6SOFtnSlmWu0yEaaQvu+QexUG2gscSAvMhJ7auzW8r/jYOgGrzuAm9G9nHbksuhz7Lw4zOwDHmfQaxZvw==",
+ "dependencies": {
+ "agent-base": "^7.1.4"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/3846masa"
+ },
+ "peerDependencies": {
+ "tough-cookie": "^4.0.0 || ^5.0.0",
+ "undici": "^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "undici": {
+ "optional": true
+ }
+ }
+ },
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -6968,19 +6945,15 @@
}
},
"node_modules/iconv-lite": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
- "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
}
},
"node_modules/ignore": {
@@ -7069,15 +7042,15 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"node_modules/inquirer": {
- "version": "12.10.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.10.0.tgz",
- "integrity": "sha512-K/epfEnDBZj2Q3NMDcgXWZye3nhSPeoJnOh8lcKWrldw54UEZfS4EmAMsAsmVbl7qKi+vjAsy39Sz4fbgRMewg==",
+ "version": "12.9.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.3.tgz",
+ "integrity": "sha512-Hpw2JWdrYY8xJSmhU05Idd5FPshQ1CZErH00WO+FK6fKxkBeqj+E+yFXSlERZLKtzWeQYFCMfl8U2TK9SvVbtQ==",
"license": "MIT",
"dependencies": {
- "@inquirer/ansi": "^1.0.1",
- "@inquirer/core": "^10.3.0",
- "@inquirer/prompts": "^7.9.0",
- "@inquirer/type": "^3.0.9",
+ "@inquirer/core": "^10.1.15",
+ "@inquirer/prompts": "^7.8.3",
+ "@inquirer/type": "^3.0.8",
+ "ansi-escapes": "^4.3.2",
"mute-stream": "^2.0.0",
"run-async": "^4.0.5",
"rxjs": "^7.8.2"
@@ -7182,7 +7155,6 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "license": "MIT",
"bin": {
"is-docker": "cli.js"
},
@@ -7259,7 +7231,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz",
"integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==",
- "license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
@@ -7315,7 +7286,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "license": "MIT",
"dependencies": {
"is-docker": "^2.0.0"
},
@@ -9034,12 +9004,11 @@
}
},
"node_modules/libxml2-wasm": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/libxml2-wasm/-/libxml2-wasm-0.6.0.tgz",
- "integrity": "sha512-CQ6bJT10o49FkL6O/zLYNf4DAm2eE6LH+ELMLf1z9842CXjgWejfOc5Fu/Yn/d6EnqTPrJbuB4i3D0MaYJ92Og==",
- "license": "MIT",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/libxml2-wasm/-/libxml2-wasm-0.5.0.tgz",
+ "integrity": "sha512-ANq8aMCg/+pYJv3QqgrvYzJldvm2P2V2T08303AVyzjdeCuOAOjxPUSazQj/NA2+rOcS9BMx/HTTtq1I2g8foQ==",
"engines": {
- "node": ">=18"
+ "node": ">=16"
}
},
"node_modules/lie": {
@@ -9125,12 +9094,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "node_modules/lodash.groupby": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
- "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==",
- "license": "MIT"
- },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -9236,7 +9199,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "license": "MIT",
"engines": {
"node": ">= 8"
}
@@ -9293,13 +9255,9 @@
}
},
"node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/minipass": {
"version": "7.1.2",
@@ -9465,6 +9423,16 @@
"node": ">=6.0.0"
}
},
+ "node_modules/node-ensure": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
+ "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc="
+ },
+ "node_modules/node-gzip": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/node-gzip/-/node-gzip-1.1.2.tgz",
+ "integrity": "sha512-ZB6zWpfZHGtxZnPMrJSKHVPrRjURoUzaDbLFj3VO70mpLTW5np96vXyHwft4Id0o+PYIzgDkBUjIzaNHhQ8srw=="
+ },
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -9486,10 +9454,9 @@
}
},
"node_modules/normalize-url": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz",
- "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==",
- "license": "MIT",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"engines": {
"node": ">=14.16"
},
@@ -9793,8 +9760,7 @@
"node_modules/path-is-inside": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
- "license": "(WTFPL OR MIT)"
+ "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w=="
},
"node_modules/path-key": {
"version": "3.1.1",
@@ -9838,8 +9804,7 @@
"node_modules/path-to-regexp": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz",
- "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==",
- "license": "MIT"
+ "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw=="
},
"node_modules/pdf-parse": {
"version": "2.4.5",
@@ -9996,36 +9961,36 @@
}
},
"node_modules/pm2": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.13.tgz",
- "integrity": "sha512-1hS/adMgKoDpX4S1ichJW8SiGpex+oBSZK31dP1FSYOOGtaeuemXzhXPOCefmddgIY4K6v7uu+7xNPnmEnK3ag==",
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.10.tgz",
+ "integrity": "sha512-sbk4HsnhtJMx1wJlhFQhYfDRzHtVK+cvdrIezbjM9WjSyc7kLtQ4nZ5K7JLOdLe3AevytmRcTiOa3VvAQrve2A==",
"dependencies": {
"@pm2/agent": "~2.1.1",
- "@pm2/blessed": "0.1.81",
"@pm2/io": "~6.1.0",
"@pm2/js-api": "~0.8.0",
"@pm2/pm2-version-check": "latest",
"ansis": "4.0.0-node10",
- "async": "3.2.6",
- "chokidar": "3.6.0",
- "cli-tableau": "2.0.1",
+ "async": "~3.2.6",
+ "blessed": "0.1.81",
+ "chokidar": "^3.5.3",
+ "cli-tableau": "^2.0.0",
"commander": "2.15.1",
- "croner": "4.1.97",
- "dayjs": "1.11.15",
- "debug": "4.4.3",
+ "croner": "~4.1.92",
+ "dayjs": "~1.11.13",
+ "debug": "^4.3.7",
"enquirer": "2.3.6",
"eventemitter2": "5.0.1",
"fclone": "1.0.11",
- "js-yaml": "4.1.0",
+ "js-yaml": "~4.1.0",
"mkdirp": "1.0.4",
"needle": "2.4.0",
- "pidusage": "3.0.2",
+ "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.2.0",
- "semver": "7.7.2",
+ "promptly": "^2",
+ "semver": "^7.6.2",
"source-map-support": "0.5.21",
"sprintf-js": "1.1.2",
"vizion": "~2.2.1"
@@ -10144,9 +10109,10 @@
"license": "MIT"
},
"node_modules/pm2/node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
@@ -10320,14 +10286,12 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==",
- "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -10336,7 +10300,6 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@@ -10351,7 +10314,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -10406,7 +10368,6 @@
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
"integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
- "license": "MIT",
"dependencies": {
"rc": "^1.1.6",
"safe-buffer": "^5.0.1"
@@ -10416,7 +10377,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
"integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==",
- "license": "MIT",
"dependencies": {
"rc": "^1.0.1"
},
@@ -10437,7 +10397,6 @@
"version": "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==",
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -10509,7 +10468,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "license": "MIT",
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
@@ -10541,7 +10499,6 @@
"url": "https://feross.org/support"
}
],
- "license": "MIT",
"dependencies": {
"queue-microtask": "^1.2.2"
}
@@ -10599,8 +10556,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/safe-regex-test": {
"version": "1.1.0",
@@ -10677,7 +10633,6 @@
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz",
"integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==",
- "license": "MIT",
"dependencies": {
"bytes": "3.0.0",
"content-disposition": "0.5.2",
@@ -10692,7 +10647,6 @@
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
- "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -10701,7 +10655,6 @@
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
- "license": "MIT",
"dependencies": {
"mime-db": "~1.33.0"
},
@@ -10713,7 +10666,6 @@
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -10729,7 +10681,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
"integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
- "license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
@@ -10740,8 +10691,7 @@
"node_modules/serve/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "license": "MIT"
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/set-function-length": {
"version": "1.2.2",
@@ -10870,19 +10820,6 @@
"node": ">=4"
}
},
- "node_modules/simple-swizzle": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
- "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
- "dependencies": {
- "is-arrayish": "^0.3.1"
- }
- },
- "node_modules/simple-swizzle/node_modules/is-arrayish": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
- "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
- },
"node_modules/skip-postinstall": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/skip-postinstall/-/skip-postinstall-1.0.0.tgz",
@@ -11241,22 +11178,20 @@
"license": "MIT"
},
"node_modules/tldts": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.12.tgz",
- "integrity": "sha512-M9ZQBPp6FyqhMcl233vHYyYRkxXOA1SKGlnq13S0mJdUhRSwr2w6I8rlchPL73wBwRlyIZpFvpu2VcdSMWLYXw==",
- "license": "MIT",
+ "version": "6.1.68",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.68.tgz",
+ "integrity": "sha512-JKF17jROiYkjJPT73hUTEiTp2OBCf+kAlB+1novk8i6Q6dWjHsgEjw9VLiipV4KTJavazXhY1QUXyQFSem2T7w==",
"dependencies": {
- "tldts-core": "^7.0.12"
+ "tldts-core": "^6.1.68"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.12.tgz",
- "integrity": "sha512-3K76aXywJFduGRsOYoY5JzINLs/WMlOkeDwPL+8OCPq2Rh39gkSDtWAxdJQlWjpun/xF/LHf29yqCi6VC/rHDA==",
- "license": "MIT"
+ "version": "6.1.68",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.68.tgz",
+ "integrity": "sha512-85TdlS/DLW/gVdf2oyyzqp3ocS30WxjaL4la85EArl9cHUR/nizifKAJPziWewSZjDZS71U517/i6ciUeqtB5Q=="
},
"node_modules/tmpl": {
"version": "1.0.5",
@@ -11276,12 +11211,12 @@
}
},
"node_modules/tough-cookie": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
- "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
"license": "BSD-3-Clause",
"dependencies": {
- "tldts": "^7.0.5"
+ "tldts": "^6.1.32"
},
"engines": {
"node": ">=16"
@@ -11315,7 +11250,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
- "license": "MIT",
"engines": {
"node": ">=18.12"
},
@@ -11329,9 +11263,9 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/tsx": {
- "version": "4.20.6",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz",
- "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==",
+ "version": "4.20.4",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.4.tgz",
+ "integrity": "sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==",
"license": "MIT",
"dependencies": {
"esbuild": "~0.25.0",
@@ -11397,9 +11331,9 @@
}
},
"node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -11418,9 +11352,9 @@
}
},
"node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "version": "7.10.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
+ "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
"license": "MIT"
},
"node_modules/universal-user-agent": {
@@ -11517,7 +11451,6 @@
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
"integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==",
- "license": "MIT",
"dependencies": {
"registry-auth-token": "3.3.2",
"registry-url": "3.1.0"
@@ -11632,18 +11565,6 @@
"node": ">=18"
}
},
- "node_modules/whatwg-encoding/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
@@ -11692,7 +11613,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
"integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
- "license": "MIT",
"dependencies": {
"string-width": "^5.0.1"
},
@@ -11704,10 +11624,9 @@
}
},
"node_modules/widest-line/node_modules/ansi-regex": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz",
- "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==",
- "license": "MIT",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"engines": {
"node": ">=12"
},
@@ -11718,14 +11637,12 @@
"node_modules/widest-line/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "license": "MIT"
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"node_modules/widest-line/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
@@ -11739,10 +11656,9 @@
}
},
"node_modules/widest-line/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "license": "MIT",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
+ "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
@@ -11760,12 +11676,12 @@
"license": "ISC"
},
"node_modules/winston": {
- "version": "3.17.0",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
- "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
+ "version": "3.18.3",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz",
+ "integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==",
"dependencies": {
"@colors/colors": "^1.6.0",
- "@dabh/diagnostics": "^2.0.2",
+ "@dabh/diagnostics": "^2.0.8",
"async": "^3.2.3",
"is-stream": "^2.0.0",
"logform": "^2.7.0",
@@ -11797,7 +11713,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@@ -11941,9 +11856,9 @@
}
},
"node_modules/yoctocolors-cjs": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz",
- "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz",
+ "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -12280,11 +12195,11 @@
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="
},
"@dabh/diagnostics": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
- "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
+ "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
"requires": {
- "colorspace": "1.1.x",
+ "@so-ric/colorspace": "^1.1.6",
"enabled": "2.0.x",
"kuler": "^2.0.0"
}
@@ -12496,17 +12411,14 @@
}
},
"@eslint/config-helpers": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz",
- "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==",
- "requires": {
- "@eslint/core": "^0.16.0"
- }
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="
},
"@eslint/core": {
- "version": "0.16.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
- "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"requires": {
"@types/json-schema": "^7.0.15"
}
@@ -12548,9 +12460,9 @@
}
},
"@eslint/js": {
- "version": "9.38.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz",
- "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A=="
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz",
+ "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A=="
},
"@eslint/object-schema": {
"version": "2.1.7",
@@ -12558,11 +12470,11 @@
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="
},
"@eslint/plugin-kit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz",
- "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"requires": {
- "@eslint/core": "^0.16.0",
+ "@eslint/core": "^0.15.2",
"levn": "^0.4.1"
}
},
@@ -12577,9 +12489,9 @@
}
},
"@freearhey/core": {
- "version": "0.14.3",
- "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.14.3.tgz",
- "integrity": "sha512-w/kaoUdZlbqvOSOmid0nrBI9iGZkUZ+KLZUfkWpfZRPXOEu/FxlEP5gPANGgovwijrgogAbVf/qnf9VV+429ag==",
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.10.3.tgz",
+ "integrity": "sha512-in5wgFHo+PJF585TXpaPLInlsgXuDLbUpXfcWrctd17mJpNNr5Mt5DetpzBqSqLERgh2jxxGRHyPGhm3Yl02hQ==",
"requires": {
"@types/lodash": "^4.14.198",
"@types/pako": "^2.0.3",
@@ -12649,9 +12561,9 @@
"integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw=="
},
"@inquirer/checkbox": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz",
- "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.1.tgz",
+ "integrity": "sha512-bevKGO6kX1eM/N+pdh9leS5L7TBF4ICrzi9a+cbWkrxeAeIcwlo/7OfWGCDERdRCI2/Q6tjltX4bt07ALHDwFw==",
"requires": {
"@inquirer/ansi": "^1.0.1",
"@inquirer/core": "^10.3.0",
@@ -12661,9 +12573,9 @@
}
},
"@inquirer/confirm": {
- "version": "5.1.19",
- "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz",
- "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==",
+ "version": "5.1.15",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.15.tgz",
+ "integrity": "sha512-SwHMGa8Z47LawQN0rog0sT+6JpiL0B7eW9p1Bb7iCeKDGTI5Ez25TSc2l8kw52VV7hA4sX/C78CGkMrKXfuspA==",
"requires": {
"@inquirer/core": "^10.3.0",
"@inquirer/type": "^3.0.9"
@@ -12722,7 +12634,17 @@
"integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==",
"requires": {
"chardet": "^2.1.0",
- "iconv-lite": "^0.7.0"
+ "iconv-lite": "^0.6.3"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
}
},
"@inquirer/figures": {
@@ -12759,20 +12681,20 @@
}
},
"@inquirer/prompts": {
- "version": "7.9.0",
- "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz",
- "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==",
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.3.tgz",
+ "integrity": "sha512-iHYp+JCaCRktM/ESZdpHI51yqsDgXu+dMs4semzETftOaF8u5hwlqnbIsuIR/LrWZl8Pm1/gzteK9I7MAq5HTA==",
"requires": {
- "@inquirer/checkbox": "^4.3.0",
- "@inquirer/confirm": "^5.1.19",
- "@inquirer/editor": "^4.2.21",
- "@inquirer/expand": "^4.0.21",
- "@inquirer/input": "^4.2.5",
- "@inquirer/number": "^3.0.21",
- "@inquirer/password": "^4.0.21",
- "@inquirer/rawlist": "^4.1.9",
- "@inquirer/search": "^3.2.0",
- "@inquirer/select": "^4.4.0"
+ "@inquirer/checkbox": "^4.2.1",
+ "@inquirer/confirm": "^5.1.15",
+ "@inquirer/editor": "^4.2.17",
+ "@inquirer/expand": "^4.0.17",
+ "@inquirer/input": "^4.2.1",
+ "@inquirer/number": "^3.0.17",
+ "@inquirer/password": "^4.0.17",
+ "@inquirer/rawlist": "^4.1.5",
+ "@inquirer/search": "^3.1.0",
+ "@inquirer/select": "^4.3.1"
}
},
"@inquirer/rawlist": {
@@ -12814,6 +12736,46 @@
"integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==",
"requires": {}
},
+ "@iptv-org/sdk": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@iptv-org/sdk/-/sdk-1.1.0.tgz",
+ "integrity": "sha512-/lEIcWGmbBSWWgS8uOKEFdfGBYPlEOcDrETHqU4k3VxsnggL46mvIsA8+ZvCV5Fa3sADD2ded5FfjDmYhoX2DA==",
+ "requires": {
+ "@freearhey/core": "^0.14.3",
+ "@freearhey/search-js": "^0.2.0",
+ "@ntlab/sfetch": "^1.2.0",
+ "axios": "^1.11.0",
+ "dayjs": "^1.11.18"
+ },
+ "dependencies": {
+ "@freearhey/core": {
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/@freearhey/core/-/core-0.14.3.tgz",
+ "integrity": "sha512-w/kaoUdZlbqvOSOmid0nrBI9iGZkUZ+KLZUfkWpfZRPXOEu/FxlEP5gPANGgovwijrgogAbVf/qnf9VV+429ag==",
+ "requires": {
+ "@types/lodash": "^4.14.198",
+ "@types/pako": "^2.0.3",
+ "consola": "^3.4.2",
+ "dayjs": "^1.11.13",
+ "glob": "^11.0.1",
+ "lodash": "^4.17.21",
+ "natural-orderby": "^5.0.0",
+ "normalize-url": "^8.1.0",
+ "object-treeify": "^2.1.1",
+ "pako": "^2.1.0",
+ "timer-node": "^5.0.9"
+ }
+ },
+ "@freearhey/search-js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@freearhey/search-js/-/search-js-0.2.0.tgz",
+ "integrity": "sha512-1sxfCRbxM12Js3nM/S51cVKLYEjoksERidz539bleMAXes44eTC2m0TEQTJzJyE7l1pw2qUwsIhjd2l2l88fSw==",
+ "requires": {
+ "lodash": "^4.17.21"
+ }
+ }
+ }
+ },
"@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
@@ -13816,11 +13778,6 @@
}
}
},
- "@pm2/blessed": {
- "version": "0.1.81",
- "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz",
- "integrity": "sha512-ZcNHqQjMuNRcQ7Z1zJbFIQZO/BDKV3KbiTckWdfbUaYhj7uNmUwb+FbdDWSCkvxNr9dBJQwvV17o6QBkAvgO0g=="
- },
"@pm2/io": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz",
@@ -13948,13 +13905,22 @@
"@sinonjs/commons": "^3.0.1"
}
},
- "@stylistic/eslint-plugin": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
- "integrity": "sha512-IeZF+8H0ns6prg4VrkhgL+yrvDXWDH2cKchrbh80ejG9dQgZWp10epHMbgRuQvgchLII/lfh6Xn3lu6+6L86Hw==",
+ "@so-ric/colorspace": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
+ "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==",
"requires": {
- "@eslint-community/eslint-utils": "^4.9.0",
- "@typescript-eslint/types": "^8.46.1",
+ "color": "^5.0.2",
+ "text-hex": "1.0.x"
+ }
+ },
+ "@stylistic/eslint-plugin": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.2.3.tgz",
+ "integrity": "sha512-oY7GVkJGVMI5benlBDCaRrSC1qPasafyv5dOBLLv5MTilMGnErKhO6ziEfodDDIZbo5QxPUNW360VudJOFODMw==",
+ "requires": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/types": "^8.38.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"estraverse": "^5.3.0",
@@ -13974,82 +13940,82 @@
}
},
"@swc/core": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz",
- "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.3.tgz",
+ "integrity": "sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==",
"requires": {
- "@swc/core-darwin-arm64": "1.13.5",
- "@swc/core-darwin-x64": "1.13.5",
- "@swc/core-linux-arm-gnueabihf": "1.13.5",
- "@swc/core-linux-arm64-gnu": "1.13.5",
- "@swc/core-linux-arm64-musl": "1.13.5",
- "@swc/core-linux-x64-gnu": "1.13.5",
- "@swc/core-linux-x64-musl": "1.13.5",
- "@swc/core-win32-arm64-msvc": "1.13.5",
- "@swc/core-win32-ia32-msvc": "1.13.5",
- "@swc/core-win32-x64-msvc": "1.13.5",
+ "@swc/core-darwin-arm64": "1.13.3",
+ "@swc/core-darwin-x64": "1.13.3",
+ "@swc/core-linux-arm-gnueabihf": "1.13.3",
+ "@swc/core-linux-arm64-gnu": "1.13.3",
+ "@swc/core-linux-arm64-musl": "1.13.3",
+ "@swc/core-linux-x64-gnu": "1.13.3",
+ "@swc/core-linux-x64-musl": "1.13.3",
+ "@swc/core-win32-arm64-msvc": "1.13.3",
+ "@swc/core-win32-ia32-msvc": "1.13.3",
+ "@swc/core-win32-x64-msvc": "1.13.3",
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.24"
}
},
"@swc/core-darwin-arm64": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz",
- "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.3.tgz",
+ "integrity": "sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==",
"optional": true
},
"@swc/core-darwin-x64": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz",
- "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.3.tgz",
+ "integrity": "sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==",
"optional": true
},
"@swc/core-linux-arm-gnueabihf": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz",
- "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.3.tgz",
+ "integrity": "sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==",
"optional": true
},
"@swc/core-linux-arm64-gnu": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz",
- "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.3.tgz",
+ "integrity": "sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==",
"optional": true
},
"@swc/core-linux-arm64-musl": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz",
- "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.3.tgz",
+ "integrity": "sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==",
"optional": true
},
"@swc/core-linux-x64-gnu": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz",
- "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.3.tgz",
+ "integrity": "sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==",
"optional": true
},
"@swc/core-linux-x64-musl": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz",
- "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.3.tgz",
+ "integrity": "sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==",
"optional": true
},
"@swc/core-win32-arm64-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz",
- "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.3.tgz",
+ "integrity": "sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==",
"optional": true
},
"@swc/core-win32-ia32-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz",
- "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.3.tgz",
+ "integrity": "sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==",
"optional": true
},
"@swc/core-win32-x64-msvc": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz",
- "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.3.tgz",
+ "integrity": "sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==",
"optional": true
},
"@swc/counter": {
@@ -14154,9 +14120,9 @@
}
},
"@types/inquirer": {
- "version": "9.0.9",
- "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.9.tgz",
- "integrity": "sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==",
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.8.tgz",
+ "integrity": "sha512-CgPD5kFGWsb8HJ5K7rfWlifao87m4ph8uioU7OTncJevmE/VLIqAAjfQtko578JZg7/f69K4FgqYym3gNr7DeA==",
"requires": {
"@types/through": "*",
"rxjs": "^7.2.0"
@@ -14248,11 +14214,11 @@
}
},
"@types/node": {
- "version": "24.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
- "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
+ "version": "24.3.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
+ "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
"requires": {
- "undici-types": "~7.16.0"
+ "undici-types": "~7.10.0"
}
},
"@types/node-cleanup": {
@@ -14302,15 +14268,15 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA=="
},
"@typescript-eslint/eslint-plugin": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz",
- "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.40.0.tgz",
+ "integrity": "sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==",
"requires": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/type-utils": "8.46.2",
- "@typescript-eslint/utils": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/type-utils": "8.40.0",
+ "@typescript-eslint/utils": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -14325,68 +14291,68 @@
}
},
"@typescript-eslint/parser": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz",
- "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.40.0.tgz",
+ "integrity": "sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==",
"requires": {
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/project-service": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz",
- "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.40.0.tgz",
+ "integrity": "sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==",
"requires": {
- "@typescript-eslint/tsconfig-utils": "^8.46.2",
- "@typescript-eslint/types": "^8.46.2",
+ "@typescript-eslint/tsconfig-utils": "^8.40.0",
+ "@typescript-eslint/types": "^8.40.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz",
- "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.40.0.tgz",
+ "integrity": "sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==",
"requires": {
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2"
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0"
}
},
"@typescript-eslint/tsconfig-utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz",
- "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.40.0.tgz",
+ "integrity": "sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==",
"requires": {}
},
"@typescript-eslint/type-utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz",
- "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.40.0.tgz",
+ "integrity": "sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==",
"requires": {
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2",
- "@typescript-eslint/utils": "8.46.2",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0",
+ "@typescript-eslint/utils": "8.40.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
}
},
"@typescript-eslint/types": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz",
- "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ=="
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.40.0.tgz",
+ "integrity": "sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg=="
},
"@typescript-eslint/typescript-estree": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz",
- "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.40.0.tgz",
+ "integrity": "sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==",
"requires": {
- "@typescript-eslint/project-service": "8.46.2",
- "@typescript-eslint/tsconfig-utils": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/visitor-keys": "8.46.2",
+ "@typescript-eslint/project-service": "8.40.0",
+ "@typescript-eslint/tsconfig-utils": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/visitor-keys": "8.40.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -14414,22 +14380,22 @@
}
},
"@typescript-eslint/utils": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz",
- "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.40.0.tgz",
+ "integrity": "sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==",
"requires": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.46.2",
- "@typescript-eslint/types": "8.46.2",
- "@typescript-eslint/typescript-estree": "8.46.2"
+ "@typescript-eslint/scope-manager": "8.40.0",
+ "@typescript-eslint/types": "8.40.0",
+ "@typescript-eslint/typescript-estree": "8.40.0"
}
},
"@typescript-eslint/visitor-keys": {
- "version": "8.46.2",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz",
- "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.40.0.tgz",
+ "integrity": "sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==",
"requires": {
- "@typescript-eslint/types": "8.46.2",
+ "@typescript-eslint/types": "8.40.0",
"eslint-visitor-keys": "^4.2.1"
},
"dependencies": {
@@ -14725,16 +14691,6 @@
"integrity": "sha512-4Bzj+l63eGwnWDBFdJHeGS6Ij3ytpyqvo//ocsb5kCLN/rKthzk27Afh2iSkZtuudOBkHUWWIcyCb4GKhXqovQ==",
"requires": {
"http-cookie-agent": "^7.0.2"
- },
- "dependencies": {
- "http-cookie-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.2.tgz",
- "integrity": "sha512-aHaES6SOFtnSlmWu0yEaaQvu+QexUG2gscSAvMhJ7auzW8r/jYOgGrzuAm9G9nHbksuhz7Lw4zOwDHmfQaxZvw==",
- "requires": {
- "agent-base": "^7.1.4"
- }
- }
}
},
"babel-jest": {
@@ -14838,11 +14794,6 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
},
- "bluebird": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
- "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
- },
"bodec": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz",
@@ -14869,9 +14820,9 @@
},
"dependencies": {
"ansi-regex": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz",
- "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg=="
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="
},
"ansi-styles": {
"version": "6.2.1",
@@ -14899,9 +14850,9 @@
}
},
"strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
+ "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
"requires": {
"ansi-regex": "^6.0.1"
}
@@ -15025,9 +14976,9 @@
"integrity": "sha512-z0R4cT5357OEAVkP1CEFTHz1egpu2gYiWm2WJOY/sQDhojEXUYL4m3v2kYi5wER3PkMRL+GgfDhed2kGzrHSZA=="
},
"chalk": {
- "version": "5.6.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
- "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
+ "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="
},
"chalk-template": {
"version": "0.4.0",
@@ -15209,26 +15160,26 @@
"integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw=="
},
"color": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
- "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/color/-/color-5.0.2.tgz",
+ "integrity": "sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA==",
"requires": {
- "color-convert": "^1.9.3",
- "color-string": "^1.6.0"
+ "color-convert": "^3.0.1",
+ "color-string": "^2.0.0"
},
"dependencies": {
"color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.2.tgz",
+ "integrity": "sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg==",
"requires": {
- "color-name": "1.1.3"
+ "color-name": "^2.0.0"
}
},
"color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
+ "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A=="
}
}
},
@@ -15246,21 +15197,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.2.tgz",
+ "integrity": "sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA==",
"requires": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
- }
- },
- "colorspace": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
- "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
- "requires": {
- "color": "^3.1.3",
- "text-hex": "1.0.x"
+ "color-name": "^2.0.0"
+ },
+ "dependencies": {
+ "color-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz",
+ "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A=="
+ }
}
},
"combined-stream": {
@@ -15556,16 +15504,6 @@
"requires": {
"iconv-lite": "^0.6.3",
"whatwg-encoding": "^3.1.1"
- },
- "dependencies": {
- "iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- }
- }
}
},
"enquirer": {
@@ -15605,15 +15543,27 @@
"socks-proxy-agent": "^8.0.5",
"winston": "^3.17.0",
"xml-js": "^1.6.11"
+ },
+ "dependencies": {
+ "epg-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz",
+ "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==",
+ "requires": {
+ "dayjs": "^1.11.6",
+ "lodash": "^4.17.21",
+ "xml-js": "^1.6.11"
+ }
+ }
}
},
"epg-parser": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.4.0.tgz",
- "integrity": "sha512-SynflAhgfrgFjFnMVggIjzgLpg7EANYymy4Q1OBiaMcEYSaIjp8iw36djam8/4B7htaNPa5ckIQ+4TUwEc0pdA==",
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz",
+ "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==",
"requires": {
"dayjs": "^1.11.6",
- "lodash.groupby": "^4.6.0",
+ "lodash": "^4.17.21",
"xml-js": "^1.6.11"
}
},
@@ -15708,18 +15658,18 @@
}
},
"eslint": {
- "version": "9.38.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz",
- "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz",
+ "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==",
"requires": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.1",
- "@eslint/config-helpers": "^0.4.1",
- "@eslint/core": "^0.16.0",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.38.0",
- "@eslint/plugin-kit": "^0.4.0",
+ "@eslint/js": "9.33.0",
+ "@eslint/plugin-kit": "^0.3.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -16280,6 +16230,14 @@
}
}
},
+ "http-cookie-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.2.tgz",
+ "integrity": "sha512-aHaES6SOFtnSlmWu0yEaaQvu+QexUG2gscSAvMhJ7auzW8r/jYOgGrzuAm9G9nHbksuhz7Lw4zOwDHmfQaxZvw==",
+ "requires": {
+ "agent-base": "^7.1.4"
+ }
+ },
"http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -16309,9 +16267,9 @@
"integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="
},
"iconv-lite": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
- "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
@@ -16376,14 +16334,14 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"inquirer": {
- "version": "12.10.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.10.0.tgz",
- "integrity": "sha512-K/epfEnDBZj2Q3NMDcgXWZye3nhSPeoJnOh8lcKWrldw54UEZfS4EmAMsAsmVbl7qKi+vjAsy39Sz4fbgRMewg==",
+ "version": "12.9.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.3.tgz",
+ "integrity": "sha512-Hpw2JWdrYY8xJSmhU05Idd5FPshQ1CZErH00WO+FK6fKxkBeqj+E+yFXSlERZLKtzWeQYFCMfl8U2TK9SvVbtQ==",
"requires": {
- "@inquirer/ansi": "^1.0.1",
- "@inquirer/core": "^10.3.0",
- "@inquirer/prompts": "^7.9.0",
- "@inquirer/type": "^3.0.9",
+ "@inquirer/core": "^10.1.15",
+ "@inquirer/prompts": "^7.8.3",
+ "@inquirer/type": "^3.0.8",
+ "ansi-escapes": "^4.3.2",
"mute-stream": "^2.0.0",
"run-async": "^4.0.5",
"rxjs": "^7.8.2"
@@ -17751,9 +17709,9 @@
}
},
"libxml2-wasm": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/libxml2-wasm/-/libxml2-wasm-0.6.0.tgz",
- "integrity": "sha512-CQ6bJT10o49FkL6O/zLYNf4DAm2eE6LH+ELMLf1z9842CXjgWejfOc5Fu/Yn/d6EnqTPrJbuB4i3D0MaYJ92Og=="
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/libxml2-wasm/-/libxml2-wasm-0.5.0.tgz",
+ "integrity": "sha512-ANq8aMCg/+pYJv3QqgrvYzJldvm2P2V2T08303AVyzjdeCuOAOjxPUSazQj/NA2+rOcS9BMx/HTTtq1I2g8foQ=="
},
"lie": {
"version": "3.1.1",
@@ -17821,11 +17779,6 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "lodash.groupby": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
- "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="
- },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -17944,9 +17897,9 @@
}
},
"minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"minipass": {
"version": "7.1.2",
@@ -18064,6 +18017,16 @@
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz",
"integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg=="
},
+ "node-ensure": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
+ "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc="
+ },
+ "node-gzip": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/node-gzip/-/node-gzip-1.1.2.tgz",
+ "integrity": "sha512-ZB6zWpfZHGtxZnPMrJSKHVPrRjURoUzaDbLFj3VO70mpLTW5np96vXyHwft4Id0o+PYIzgDkBUjIzaNHhQ8srw=="
+ },
"node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -18427,37 +18390,37 @@
}
},
"pm2": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.13.tgz",
- "integrity": "sha512-1hS/adMgKoDpX4S1ichJW8SiGpex+oBSZK31dP1FSYOOGtaeuemXzhXPOCefmddgIY4K6v7uu+7xNPnmEnK3ag==",
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.10.tgz",
+ "integrity": "sha512-sbk4HsnhtJMx1wJlhFQhYfDRzHtVK+cvdrIezbjM9WjSyc7kLtQ4nZ5K7JLOdLe3AevytmRcTiOa3VvAQrve2A==",
"requires": {
"@pm2/agent": "~2.1.1",
- "@pm2/blessed": "0.1.81",
"@pm2/io": "~6.1.0",
"@pm2/js-api": "~0.8.0",
"@pm2/pm2-version-check": "latest",
"ansis": "4.0.0-node10",
- "async": "3.2.6",
- "chokidar": "3.6.0",
- "cli-tableau": "2.0.1",
+ "async": "~3.2.6",
+ "blessed": "0.1.81",
+ "chokidar": "^3.5.3",
+ "cli-tableau": "^2.0.0",
"commander": "2.15.1",
- "croner": "4.1.97",
- "dayjs": "1.11.15",
- "debug": "4.4.3",
+ "croner": "~4.1.92",
+ "dayjs": "~1.11.13",
+ "debug": "^4.3.7",
"enquirer": "2.3.6",
"eventemitter2": "5.0.1",
"fclone": "1.0.11",
- "js-yaml": "4.1.0",
+ "js-yaml": "~4.1.0",
"mkdirp": "1.0.4",
"needle": "2.4.0",
- "pidusage": "3.0.2",
+ "pidusage": "~3.0",
"pm2-axon": "~4.0.1",
"pm2-axon-rpc": "~0.7.1",
"pm2-deploy": "~1.0.2",
"pm2-multimeter": "^0.1.2",
"pm2-sysmonit": "^1.2.8",
- "promptly": "2.2.0",
- "semver": "7.7.2",
+ "promptly": "^2",
+ "semver": "^7.6.2",
"source-map-support": "0.5.21",
"sprintf-js": "1.1.2",
"vizion": "~2.2.1"
@@ -18479,9 +18442,9 @@
"integrity": "sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ=="
},
"debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"requires": {
"ms": "^2.1.3"
}
@@ -19027,21 +18990,6 @@
}
}
},
- "simple-swizzle": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
- "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
- "requires": {
- "is-arrayish": "^0.3.1"
- },
- "dependencies": {
- "is-arrayish": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
- "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
- }
- }
- },
"skip-postinstall": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/skip-postinstall/-/skip-postinstall-1.0.0.tgz",
@@ -19272,17 +19220,17 @@
"integrity": "sha512-zXxCE/5/YDi0hY9pygqgRqjRbrFRzigYxOudG0I3syaqAAmX9/w9sxex1bNFCN6c1S66RwPtEIJv65dN+1psew=="
},
"tldts": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.12.tgz",
- "integrity": "sha512-M9ZQBPp6FyqhMcl233vHYyYRkxXOA1SKGlnq13S0mJdUhRSwr2w6I8rlchPL73wBwRlyIZpFvpu2VcdSMWLYXw==",
+ "version": "6.1.68",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.68.tgz",
+ "integrity": "sha512-JKF17jROiYkjJPT73hUTEiTp2OBCf+kAlB+1novk8i6Q6dWjHsgEjw9VLiipV4KTJavazXhY1QUXyQFSem2T7w==",
"requires": {
- "tldts-core": "^7.0.12"
+ "tldts-core": "^6.1.68"
}
},
"tldts-core": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.12.tgz",
- "integrity": "sha512-3K76aXywJFduGRsOYoY5JzINLs/WMlOkeDwPL+8OCPq2Rh39gkSDtWAxdJQlWjpun/xF/LHf29yqCi6VC/rHDA=="
+ "version": "6.1.68",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.68.tgz",
+ "integrity": "sha512-85TdlS/DLW/gVdf2oyyzqp3ocS30WxjaL4la85EArl9cHUR/nizifKAJPziWewSZjDZS71U517/i6ciUeqtB5Q=="
},
"tmpl": {
"version": "1.0.5",
@@ -19298,11 +19246,11 @@
}
},
"tough-cookie": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
- "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
"requires": {
- "tldts": "^7.0.5"
+ "tldts": "^6.1.32"
}
},
"transliteration": {
@@ -19330,9 +19278,9 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"tsx": {
- "version": "4.20.6",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz",
- "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==",
+ "version": "4.20.4",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.4.tgz",
+ "integrity": "sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==",
"requires": {
"esbuild": "~0.25.0",
"fsevents": "~2.3.3",
@@ -19372,9 +19320,9 @@
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
},
"typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="
},
"undici": {
"version": "7.12.0",
@@ -19382,9 +19330,9 @@
"integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug=="
},
"undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="
+ "version": "7.10.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
+ "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="
},
"universal-user-agent": {
"version": "7.0.3",
@@ -19534,16 +19482,6 @@
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"requires": {
"iconv-lite": "0.6.3"
- },
- "dependencies": {
- "iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- }
- }
}
},
"whatwg-mimetype": {
@@ -19582,9 +19520,9 @@
},
"dependencies": {
"ansi-regex": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz",
- "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg=="
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="
},
"emoji-regex": {
"version": "9.2.2",
@@ -19602,9 +19540,9 @@
}
},
"strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
+ "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
"requires": {
"ansi-regex": "^6.0.1"
}
@@ -19617,12 +19555,12 @@
"integrity": "sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g=="
},
"winston": {
- "version": "3.17.0",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
- "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
+ "version": "3.18.3",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz",
+ "integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==",
"requires": {
"@colors/colors": "^1.6.0",
- "@dabh/diagnostics": "^2.0.2",
+ "@dabh/diagnostics": "^2.0.8",
"async": "^3.2.3",
"is-stream": "^2.0.0",
"logform": "^2.7.0",
diff --git a/package.json b/package.json
index 918da0b3..73682b17 100644
--- a/package.json
+++ b/package.json
@@ -2,11 +2,13 @@
"name": "epg",
"scripts": {
"act:check": "act pull_request -W .github/workflows/check.yml",
+ "act:format": "act workflow_dispatch -W .github/workflows/format.yml",
"act:update": "act workflow_dispatch -W .github/workflows/update.yml",
"api:load": "tsx scripts/commands/api/load.ts",
"api:generate": "tsx scripts/commands/api/generate.ts",
"channels:lint": "tsx scripts/commands/channels/lint.mts",
"channels:parse": "tsx scripts/commands/channels/parse.ts",
+ "channels:format": "tsx scripts/commands/channels/format.ts",
"channels:edit": "tsx scripts/commands/channels/edit.ts",
"channels:validate": "tsx scripts/commands/channels/validate.ts",
"sites:init": "tsx scripts/commands/sites/init.ts",
@@ -32,92 +34,94 @@
],
"testTimeout": 10000,
"transformIgnorePatterns": [
- "/node_modules/(?!parse-duration/.*|glob/.*|srcset/.*|balanced-match/.*|minimatch/.*)"
+ "/node_modules/(?!parse-duration/.*|@freearhey/core/.*|glob/.*|srcset/.*|balanced-match/.*|minimatch/.*)"
]
},
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "^9.38.0",
+ "@eslint/js": "^9.32.0",
"@freearhey/chronos": "^0.0.1",
- "@freearhey/core": "^0.14.3",
- "@freearhey/search-js": "^0.2.0",
+ "@freearhey/core": "^0.13.2",
+ "@freearhey/search-js": "^0.1.2",
"@freearhey/storage-js": "^0.2.0",
+ "@iptv-org/sdk": "^1.1.0",
"@ntlab/sfetch": "^1.2.0",
- "@octokit/core": "^7.0.5",
- "@octokit/plugin-paginate-rest": "^13.2.1",
- "@octokit/plugin-rest-endpoint-methods": "^16.1.1",
- "@stylistic/eslint-plugin": "^5.5.0",
- "@swc/core": "^1.13.5",
+ "@octokit/core": "^7.0.3",
+ "@octokit/plugin-paginate-rest": "^13.1.1",
+ "@octokit/plugin-rest-endpoint-methods": "^16.0.0",
+ "@stylistic/eslint-plugin": "^5.2.2",
+ "@swc/core": "^1.13.2",
"@swc/jest": "^0.2.39",
"@types/cli-progress": "^3.11.6",
"@types/fs-extra": "^11.0.4",
- "@types/inquirer": "^9.0.9",
+ "@types/inquirer": "^9.0.8",
"@types/jest": "^30.0.0",
"@types/langs": "^2.0.5",
"@types/lodash.orderby": "^4.6.9",
"@types/lodash.sortby": "^4.7.9",
"@types/lodash.startcase": "^4.4.9",
"@types/lodash.uniqby": "^4.7.9",
- "@types/node": "^24.9.1",
+ "@types/node": "^24.1.0",
"@types/node-cleanup": "^2.1.5",
"@types/numeral": "^2.0.5",
- "@typescript-eslint/eslint-plugin": "^8.46.2",
- "@typescript-eslint/parser": "^8.46.2",
- "axios": "^1.12.2",
+ "@types/pako": "^2.0.4",
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
+ "@typescript-eslint/parser": "^8.38.0",
+ "axios": "^1.11.0",
"axios-cookiejar-support": "^6.0.4",
- "chalk": "^5.6.2",
+ "chalk": "^5.4.1",
"cheerio": "^1.1.2",
"cli-progress": "^3.12.0",
- "commander": "^14.0.1",
+ "commander": "^14.0.0",
"consola": "^3.4.2",
- "cross-env": "^10.1.0",
+ "cross-env": "^10.0.0",
"csv-parser": "^3.2.0",
"cwait": "^1.1.2",
- "dayjs": "^1.11.18",
+ "dayjs": "^1.11.13",
"epg-grabber": "^0.44.0",
- "epg-parser": "^0.4.0",
- "eslint": "^9.38.0",
+ "epg-parser": "^0.3.1",
+ "eslint": "^9.32.0",
"eslint-config-prettier": "^10.1.8",
"form-data": "^4.0.4",
- "fs-extra": "^11.3.2",
+ "fs-extra": "^11.3.0",
"glob": "^11.0.3",
- "globals": "^16.4.0",
+ "globals": "^16.3.0",
"husky": "^9.1.7",
- "iconv-lite": "^0.7.0",
- "inquirer": "^12.10.0",
- "jest": "^30.2.0",
+ "iconv-lite": "^0.6.3",
+ "inquirer": "^12.8.2",
+ "jest": "^30.0.5",
"jest-offline": "^1.0.1",
"langs": "^2.0.0",
- "libxml2-wasm": "^0.6.0",
+ "libxml2-wasm": "^0.5.0",
"lodash.orderby": "^4.6.0",
"lodash.sortby": "^4.7.0",
"lodash.startcase": "^4.4.0",
"lodash.uniqby": "^4.7.0",
- "luxon": "^3.7.2",
+ "luxon": "^3.7.1",
"mockdate": "^3.0.5",
"nedb-promises": "^6.2.3",
"node-cleanup": "^2.1.2",
"numeral": "^2.0.6",
"pako": "^2.1.0",
"parse-duration": "^2.1.4",
- "pdf-parse": "^2.4.5",
- "pm2": "^6.0.13",
+ "pdf-parse": "^1.1.1",
+ "pm2": "^6.0.8",
"readline": "^1.3.0",
"run-script-os": "^1.1.6",
- "serve": "^14.2.5",
+ "serve": "^14.2.4",
"signale": "^1.4.0",
"skip-postinstall": "^1.0.0",
"socks-proxy-agent": "^8.0.5",
- "srcset": "^5.0.2",
+ "srcset": "^5.0.1",
"table2array": "^0.0.2",
"tabletojson": "^4.1.6",
- "tough-cookie": "^6.0.0",
+ "tough-cookie": "^5.1.2",
"transliteration": "^2.3.5",
- "tsx": "^4.20.6",
- "typescript": "^5.9.3",
+ "tsx": "^4.20.3",
+ "typescript": "^5.8.3",
"unzipit": "^1.4.3",
- "uuid": "^13.0.0",
+ "uuid": "^11.1.0",
"wildcard-match": "^5.1.4"
}
}
diff --git a/scripts/api.ts b/scripts/api.ts
new file mode 100644
index 00000000..4535b721
--- /dev/null
+++ b/scripts/api.ts
@@ -0,0 +1,117 @@
+import { Collection, Dictionary } from '@freearhey/core'
+import { DATA_DIR } from './constants'
+import cliProgress from 'cli-progress'
+import * as sdk from '@iptv-org/sdk'
+
+const data = {
+ channelsKeyById: new Dictionary(),
+ feedsKeyByStreamId: new Dictionary(),
+ feedsGroupedByChannelId: new Dictionary()
+}
+
+interface SearchIndex {
+ search: (query: string) => sdk.Types.ChannelSearchableData[]
+}
+
+let searchIndex: SearchIndex
+
+async function loadData() {
+ const dataManager = new sdk.DataManager({ dataDir: DATA_DIR })
+ await dataManager.loadFromDisk()
+ dataManager.processData()
+
+ const { channels, feeds } = dataManager.getProcessedData()
+
+ data.channelsKeyById = channels.keyBy((channel: sdk.Models.Channel) => channel.id)
+ data.feedsKeyByStreamId = feeds.keyBy((feed: sdk.Models.Feed) => feed.getStreamId())
+ data.feedsGroupedByChannelId = feeds.groupBy((feed: sdk.Models.Feed) => feed.channel)
+
+ searchIndex = sdk.SearchEngine.createIndex(channels)
+}
+
+async function downloadData() {
+ function formatBytes(bytes: number) {
+ if (bytes === 0) return '0 B'
+ const k = 1024
+ const sizes = ['B', 'KB', 'MB', 'GB']
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
+ }
+
+ const files = [
+ 'blocklist',
+ 'categories',
+ 'channels',
+ 'cities',
+ 'countries',
+ 'feeds',
+ 'guides',
+ 'languages',
+ 'logos',
+ 'regions',
+ 'streams',
+ 'subdivisions',
+ 'timezones'
+ ]
+
+ const multiBar = new cliProgress.MultiBar({
+ stopOnComplete: true,
+ hideCursor: true,
+ forceRedraw: true,
+ barsize: 36,
+ format(options, params, payload) {
+ const filename = payload.filename.padEnd(18, ' ')
+ const barsize = options.barsize || 40
+ const percent = (params.progress * 100).toFixed(2)
+ const speed = payload.speed ? formatBytes(payload.speed) + '/s' : 'N/A'
+ const total = formatBytes(params.total)
+ const completeSize = Math.round(params.progress * barsize)
+ const incompleteSize = barsize - completeSize
+ const bar =
+ options.barCompleteString && options.barIncompleteString
+ ? options.barCompleteString.substr(0, completeSize) +
+ options.barGlue +
+ options.barIncompleteString.substr(0, incompleteSize)
+ : '-'.repeat(barsize)
+
+ return `${filename} [${bar}] ${percent}% | ETA: ${params.eta}s | ${total} | ${speed}`
+ }
+ })
+
+ const dataManager = new sdk.DataManager({ dataDir: DATA_DIR })
+
+ const requests: Promise[] = []
+ for (const basename of files) {
+ const filename = `${basename}.json`
+ const progressBar = multiBar.create(0, 0, { filename })
+ const request = dataManager.downloadFileToDisk(basename, {
+ onDownloadProgress({ total, loaded, rate }) {
+ if (total) progressBar.setTotal(total)
+ progressBar.update(loaded, { speed: rate })
+ }
+ })
+
+ requests.push(request)
+ }
+
+ await Promise.allSettled(requests).catch(console.error)
+}
+
+function searchChannels(query: string): Collection {
+ if (!searchIndex) return new Collection()
+
+ const results = searchIndex.search(query)
+
+ const channels = new Collection()
+
+ new Collection(results).forEach(
+ (item: sdk.Types.ChannelSearchableData) => {
+ const channel = data.channelsKeyById.get(item.id)
+ if (channel) channels.add(channel)
+ }
+ )
+
+ return channels
+}
+
+export { data, loadData, downloadData, searchChannels }
diff --git a/scripts/commands/api/generate.ts b/scripts/commands/api/generate.ts
index 17b03aa3..0ca61940 100644
--- a/scripts/commands/api/generate.ts
+++ b/scripts/commands/api/generate.ts
@@ -1,9 +1,9 @@
-import { Logger, Collection } from '@freearhey/core'
-import { Storage } from '@freearhey/storage-js'
+import { ChannelGuideObject } from '../../types/channel'
import { SITES_DIR, API_DIR } from '../../constants'
-import { GuideChannel } from '../../models'
-import { ChannelsParser } from '../../core'
-import epgGrabber from 'epg-grabber'
+import { Logger, Collection } from '@freearhey/core'
+import epgGrabber, { EPGGrabber } from 'epg-grabber'
+import { Storage } from '@freearhey/storage-js'
+import { Channel } from '../../models'
import path from 'path'
async function main() {
@@ -13,24 +13,25 @@ async function main() {
logger.info('loading channels...')
const sitesStorage = new Storage(SITES_DIR)
- const parser = new ChannelsParser({
- storage: sitesStorage
- })
const files: string[] = await sitesStorage.list('**/*.channels.xml')
- const channels = new Collection()
+ const channels = new Collection()
for (const filepath of files) {
- const channelList = await parser.parse(filepath)
+ const xml = await sitesStorage.load(filepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ const channelsFromXML = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
- channelList.channels.forEach((data: epgGrabber.Channel) => {
- channels.add(new GuideChannel(data))
+ channelsFromXML.forEach((channel: Channel) => {
+ channels.add(channel)
})
}
logger.info(`found ${channels.count()} channel(s)`)
- const output = channels.map((channel: GuideChannel) => channel.toJSON())
+ const output = channels.map((channel: Channel) => channel.getGuideObject())
const apiStorage = new Storage(API_DIR)
const outputFilename = 'guides.json'
diff --git a/scripts/commands/api/load.ts b/scripts/commands/api/load.ts
index 8ce068e9..2ab0b182 100644
--- a/scripts/commands/api/load.ts
+++ b/scripts/commands/api/load.ts
@@ -1,25 +1,7 @@
-import { DATA_DIR } from '../../constants.js'
-import { DataLoader } from '../../core/dataLoader.js'
+import { downloadData } from '../../api'
async function main() {
- const { Storage } = await import('@freearhey/storage-js')
- const storage = new Storage(DATA_DIR)
- const loader = new DataLoader({ storage })
-
- await Promise.all([
- loader.download('blocklist.json'),
- loader.download('categories.json'),
- loader.download('channels.json'),
- loader.download('countries.json'),
- loader.download('languages.json'),
- loader.download('regions.json'),
- loader.download('subdivisions.json'),
- loader.download('feeds.json'),
- loader.download('timezones.json'),
- loader.download('guides.json'),
- loader.download('streams.json'),
- loader.download('logos.json')
- ])
+ await downloadData()
}
main()
diff --git a/scripts/commands/channels/edit.ts b/scripts/commands/channels/edit.ts
index 8298343a..650d8b07 100644
--- a/scripts/commands/channels/edit.ts
+++ b/scripts/commands/channels/edit.ts
@@ -1,21 +1,25 @@
-import { Collection, Logger, Dictionary } from '@freearhey/core'
-import { Storage } from '@freearhey/storage-js'
-import type { DataProcessorData } from '../../types/dataProcessor'
-import type { DataLoaderData } from '../../types/dataLoader'
-import { ChannelSearchableData } from '../../types/channel'
-import { Channel, ChannelList, Feed } from '../../models'
-import { DataProcessor, DataLoader } from '../../core'
+import { loadData, data, searchChannels } from '../../api'
+import epgGrabber, { EPGGrabber } from 'epg-grabber'
+import { Collection, Logger } from '@freearhey/core'
import { select, input } from '@inquirer/prompts'
-import { ChannelsParser } from '../../core'
-import { DATA_DIR } from '../../constants'
+import { generateChannelsXML } from '../../core'
+import { Storage } from '@freearhey/storage-js'
+import { Channel } from '../../models'
import nodeCleanup from 'node-cleanup'
-import sjs from '@freearhey/search-js'
-import epgGrabber from 'epg-grabber'
+import * as sdk from '@iptv-org/sdk'
import { Command } from 'commander'
import readline from 'readline'
-interface ChoiceValue { type: string; value?: Feed | Channel }
-interface Choice { name: string; short?: string; value: ChoiceValue; default?: boolean }
+interface ChoiceValue {
+ type: string
+ value?: sdk.Models.Feed | sdk.Models.Channel
+}
+interface Choice {
+ name: string
+ short?: string
+ value: ChoiceValue
+ default?: boolean
+}
if (process.platform === 'win32') {
readline
@@ -35,11 +39,11 @@ program.argument('', 'Path to *.channels.xml file to edit').parse(proc
const filepath = program.args[0]
const logger = new Logger()
const storage = new Storage()
-let channelList = new ChannelList({ channels: [] })
+let channelsFromXML = new Collection()
main(filepath)
nodeCleanup(() => {
- save(filepath, channelList)
+ save(filepath, channelsFromXML)
})
export default async function main(filepath: string) {
@@ -48,67 +52,46 @@ export default async function main(filepath: string) {
}
logger.info('loading data from api...')
- const processor = new DataProcessor()
- const dataStorage = new Storage(DATA_DIR)
- const loader = new DataLoader({ storage: dataStorage })
- const data: DataLoaderData = await loader.load()
- const { channels, channelsKeyById, feedsGroupedByChannelId }: DataProcessorData =
- processor.process(data)
+ await loadData()
logger.info('loading channels...')
- const parser = new ChannelsParser({ storage })
- channelList = await parser.parse(filepath)
- const parsedChannelsWithoutId = channelList.channels.filter(
- (channel: epgGrabber.Channel) => !channel.xmltv_id
+ const xml = await storage.load(filepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ channelsFromXML = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
)
+ const channelsFromXMLWithoutId = channelsFromXML.filter((channel: Channel) => !channel.xmltv_id)
logger.info(
- `found ${channelList.channels.count()} channels (including ${parsedChannelsWithoutId.count()} without ID)`
+ `found ${channelsFromXML.count()} channels (including ${channelsFromXMLWithoutId.count()} without ID)`
)
- logger.info('creating search index...')
- const items = channels.map((channel: Channel) => channel.getSearchable()).all()
- const searchIndex = sjs.createIndex(items, {
- searchable: ['name', 'altNames', 'guideNames', 'streamNames', 'feedFullNames']
- })
+ logger.info('starting...')
+ console.log()
- logger.info('starting...\n')
-
- for (const channel of parsedChannelsWithoutId.all()) {
+ for (const channel of channelsFromXMLWithoutId.all()) {
try {
- channel.xmltv_id = await selectChannel(
- channel,
- searchIndex,
- feedsGroupedByChannelId,
- channelsKeyById
- )
- } catch (err) {
- logger.info(err.message)
+ channel.xmltv_id = await selectChannel(channel)
+ } catch {
break
}
}
- parsedChannelsWithoutId.forEach((channel: epgGrabber.Channel) => {
+ channelsFromXMLWithoutId.forEach((channel: epgGrabber.Channel) => {
if (channel.xmltv_id === '-') {
channel.xmltv_id = ''
}
})
}
-async function selectChannel(
- channel: epgGrabber.Channel,
- searchIndex,
- feedsGroupedByChannelId: Dictionary,
- channelsKeyById: Dictionary
-): Promise {
+async function selectChannel(channel: epgGrabber.Channel): Promise {
const query = escapeRegex(channel.name)
- const similarChannels = searchIndex
- .search(query)
- .map((item: ChannelSearchableData) => channelsKeyById.get(item.id))
+ const similarChannels = searchChannels(query)
+ const choices = getChoicesForChannel(similarChannels).all()
const selected: ChoiceValue = await select({
message: `Select channel ID for "${channel.name}" (${channel.site_id}):`,
- choices: getChannelChoises(new Collection(similarChannels)),
+ choices,
pageSize: 10
})
@@ -118,14 +101,14 @@ async function selectChannel(
case 'type': {
const typedChannelId = await input({ message: ' Channel ID:' })
if (!typedChannelId) return ''
- const selectedFeedId = await selectFeed(typedChannelId, feedsGroupedByChannelId)
+ const selectedFeedId = await selectFeed(typedChannelId)
if (selectedFeedId === '-') return typedChannelId
return [typedChannelId, selectedFeedId].join('@')
}
case 'channel': {
const selectedChannel = selected.value
if (!selectedChannel) return ''
- const selectedFeedId = await selectFeed(selectedChannel.id || '', feedsGroupedByChannelId)
+ const selectedFeedId = await selectFeed(selectedChannel.id || '')
if (selectedFeedId === '-') return selectedChannel.id || ''
return [selectedChannel.id, selectedFeedId].join('@')
}
@@ -134,11 +117,9 @@ async function selectChannel(
return ''
}
-async function selectFeed(channelId: string, feedsGroupedByChannelId: Dictionary): Promise {
- const channelFeeds = feedsGroupedByChannelId.has(channelId)
- ? new Collection(feedsGroupedByChannelId.get(channelId))
- : new Collection()
- const choices = getFeedChoises(channelFeeds)
+async function selectFeed(channelId: string): Promise {
+ const channelFeeds = new Collection(data.feedsGroupedByChannelId.get(channelId))
+ const choices = getChoicesForFeed(channelFeeds).all()
const selected: ChoiceValue = await select({
message: `Select feed ID for "${channelId}":`,
@@ -160,13 +141,13 @@ async function selectFeed(channelId: string, feedsGroupedByChannelId: Dictionary
return ''
}
-function getChannelChoises(channels: Collection): Choice[] {
- const choises: Choice[] = []
+function getChoicesForChannel(channels: Collection): Collection {
+ const choices = new Collection()
- channels.forEach((channel: Channel) => {
- const names = new Collection([channel.name, ...channel.getAltNames().all()]).uniq().join(', ')
+ channels.forEach((channel: sdk.Models.Channel) => {
+ const names = new Collection([channel.name, ...channel.alt_names]).uniq().join(', ')
- choises.push({
+ choices.add({
value: {
type: 'channel',
value: channel
@@ -176,40 +157,42 @@ function getChannelChoises(channels: Collection): Choice[] {
})
})
- choises.push({ name: 'Type...', value: { type: 'type' } })
- choises.push({ name: 'Skip', value: { type: 'skip' } })
+ choices.add({ name: 'Type...', value: { type: 'type' } })
+ choices.add({ name: 'Skip', value: { type: 'skip' } })
- return choises
+ return choices
}
-function getFeedChoises(feeds: Collection): Choice[] {
- const choises: Choice[] = []
+function getChoicesForFeed(feeds: Collection): Collection {
+ const choices = new Collection()
- feeds.forEach((feed: Feed) => {
+ feeds.forEach((feed: sdk.Models.Feed) => {
let name = `${feed.id} (${feed.name})`
- if (feed.isMain) name += ' [main]'
+ if (feed.is_main) name += ' [main]'
- choises.push({
+ choices.add({
value: {
type: 'feed',
value: feed
},
- default: feed.isMain,
+ default: feed.is_main,
name,
short: feed.id
})
})
- choises.push({ name: 'Type...', value: { type: 'type' } })
- choises.push({ name: 'Skip', value: { type: 'skip' } })
+ choices.add({ name: 'Type...', value: { type: 'type' } })
+ choices.add({ name: 'Skip', value: { type: 'skip' } })
- return choises
+ return choices
}
-function save(filepath: string, channelList: ChannelList) {
+function save(filepath: string, channelsFromXML: Collection) {
if (!storage.existsSync(filepath)) return
- storage.saveSync(filepath, channelList.toString())
- logger.info(`\nFile '${filepath}' successfully saved`)
+ const xml = generateChannelsXML(channelsFromXML)
+ storage.saveSync(filepath, xml)
+ console.log()
+ logger.info(`File '${filepath}' successfully saved`)
}
function escapeRegex(string: string) {
diff --git a/scripts/commands/channels/format.ts b/scripts/commands/channels/format.ts
new file mode 100644
index 00000000..d830a484
--- /dev/null
+++ b/scripts/commands/channels/format.ts
@@ -0,0 +1,60 @@
+import { Collection, Logger } from '@freearhey/core'
+import epgGrabber, { EPGGrabber } from 'epg-grabber'
+import { generateChannelsXML } from '../../core'
+import { Storage } from '@freearhey/storage-js'
+import { SITES_DIR } from '../../constants'
+import { data, loadData } from '../../api'
+import { Channel } from '../../models'
+import { program } from 'commander'
+
+program.argument('[filepath...]', 'Path to file to format').parse(process.argv)
+
+async function main() {
+ const logger = new Logger()
+
+ logger.info('loading data from api...')
+ await loadData()
+
+ logger.info('loading *.channels.xml files...')
+ const storage = new Storage()
+ const files = program.args.length
+ ? program.args
+ : await storage.list(`${SITES_DIR}/**/*.channels.xml`)
+
+ logger.info(`found ${files.length} file(s)`)
+
+ logger.info('formating...')
+ for (const filepath of files) {
+ if (!storage.existsSync(filepath)) continue
+
+ const xml = await storage.load(filepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ const channelsFromXML = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
+
+ channelsFromXML.forEach((channel: Channel) => {
+ if (!channel.xmltv_id) return
+ if (data.feedsKeyByStreamId.get(channel.xmltv_id)) return
+
+ const channelData = data.channelsKeyById.get(channel.xmltv_id)
+ if (channelData) {
+ const mainFeed = channelData.getMainFeed()
+ if (mainFeed) {
+ channel.xmltv_id = mainFeed.getStreamId()
+ return
+ }
+ }
+
+ channel.xmltv_id = ''
+ })
+
+ channelsFromXML.sortBy((channel: Channel) => channel.site_id)
+
+ const output = generateChannelsXML(channelsFromXML)
+
+ await storage.save(filepath, output)
+ }
+}
+
+main()
diff --git a/scripts/commands/channels/lint.mts b/scripts/commands/channels/lint.mts
index 47f1182e..016fe834 100644
--- a/scripts/commands/channels/lint.mts
+++ b/scripts/commands/channels/lint.mts
@@ -1,7 +1,7 @@
-import chalk from 'chalk'
-import { program } from 'commander'
-import { Storage, File } from '@freearhey/storage-js'
import { XmlDocument, XsdValidator, XmlValidateError, ErrorDetail } from 'libxml2-wasm'
+import { Storage, File } from '@freearhey/storage-js'
+import { program } from 'commander'
+import chalk from 'chalk'
const xsd = `
diff --git a/scripts/commands/channels/parse.ts b/scripts/commands/channels/parse.ts
index fa0fa35d..56e1f13a 100644
--- a/scripts/commands/channels/parse.ts
+++ b/scripts/commands/channels/parse.ts
@@ -1,11 +1,21 @@
-import { Logger } from '@freearhey/core'
import { Storage, File } from '@freearhey/storage-js'
-import { ChannelsParser } from '../../core'
-import { ChannelList } from '../../models'
+import { Collection, Logger } from '@freearhey/core'
+import epgGrabber, { EPGGrabber } from 'epg-grabber'
+import { generateChannelsXML } from '../../core'
import { pathToFileURL } from 'node:url'
-import epgGrabber from 'epg-grabber'
+import { Channel } from '../../models'
import { Command } from 'commander'
+interface SiteConfigChannelData {
+ xmltv_id: string
+ name: string
+ site_id: string
+ lang?: string
+ logo?: string
+ url?: string
+ lcn?: string
+}
+
const program = new Command()
program
.requiredOption('-c, --config ', 'Config file')
@@ -33,17 +43,11 @@ async function main() {
const storage = new Storage()
const logger = new Logger()
- const parser = new ChannelsParser({ storage })
const file = new File(options.config)
const dir = file.dirname()
const config = (await import(pathToFileURL(options.config).toString())).default
const outputFilepath = options.output || `${dir}/${config.site}.channels.xml`
- let channelList = new ChannelList({ channels: [] })
- if (await storage.exists(outputFilepath)) {
- channelList = await parser.parse(outputFilepath)
- }
-
const args: Record = {}
if (Array.isArray(options.set)) {
@@ -53,29 +57,43 @@ async function main() {
})
}
- let parsedChannels: epgGrabber.Channel[] | Promise = []
-
- if (!config.channels || typeof config.channels !== 'function') {
- logger.error(`Config file '${options.config}' does not export a channels(...) function`)
- return
+ let channelsFromXML = new Collection()
+ if (await storage.exists(outputFilepath)) {
+ const xml = await storage.load(outputFilepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ channelsFromXML = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
}
- parsedChannels = config.channels(args)
-
- if (isPromise(parsedChannels)) {
- parsedChannels = await parsedChannels
+ let configChannels = config.channels(args)
+ if (isPromise(configChannels)) {
+ configChannels = await configChannels
}
- parsedChannels = (parsedChannels as epgGrabber.Channel[]).map((channel: epgGrabber.Channel) => {
- channel.site = config.site
- return channel
- })
+ const channelsFromConfig = new Collection(configChannels).map(
+ (data: SiteConfigChannelData) => {
+ return new Channel({
+ xmltv_id: data.xmltv_id,
+ name: data.name,
+ site_id: data.site_id,
+ lang: data.lang || null,
+ logo: data.logo || null,
+ url: data.url || null,
+ lcn: data.lcn || null,
+ site: config.site,
+ index: -1
+ })
+ }
+ )
- const newChannelList = new ChannelList({ channels: [] })
- parsedChannels.forEach((channel: epgGrabber.Channel) => {
+ const newChannelList = new Collection()
+ channelsFromConfig.forEach((channel: Channel) => {
if (!channel.site_id) return
- const found: epgGrabber.Channel | undefined = channelList.get(channel.site_id)
+ const found: Channel | undefined = channelsFromXML.find(
+ (_channel: Channel) => _channel.site_id == channel.site_id
+ )
if (found) {
channel.xmltv_id = found.xmltv_id
@@ -85,9 +103,15 @@ async function main() {
newChannelList.add(channel)
})
- newChannelList.sort()
+ newChannelList.sortBy([
+ (channel: Channel) => channel.lang || '_',
+ (channel: Channel) => (channel.xmltv_id ? channel.xmltv_id.toLowerCase() : '0'),
+ (channel: Channel) => channel.site_id
+ ])
- await storage.save(outputFilepath, newChannelList.toString())
+ const xml = generateChannelsXML(newChannelList)
+
+ await storage.save(outputFilepath, xml)
logger.info(`File '${outputFilepath}' successfully saved`)
}
diff --git a/scripts/commands/channels/validate.ts b/scripts/commands/channels/validate.ts
index 93e6945e..80ef732f 100644
--- a/scripts/commands/channels/validate.ts
+++ b/scripts/commands/channels/validate.ts
@@ -1,100 +1,96 @@
-import { ChannelsParser, DataLoader, DataProcessor } from '../../core'
-import { DataProcessorData } from '../../types/dataProcessor'
-import { Storage, Dictionary, File } from '@freearhey/core'
-import { DataLoaderData } from '../../types/dataLoader'
-import { ChannelList } from '../../models'
-import { DATA_DIR } from '../../constants'
-import epgGrabber from 'epg-grabber'
-import { program } from 'commander'
-import chalk from 'chalk'
-import langs from 'langs'
-
-program.argument('[filepath...]', 'Path to *.channels.xml files to validate').parse(process.argv)
-
-interface ValidationError {
- type: 'duplicate' | 'wrong_channel_id' | 'wrong_feed_id' | 'wrong_lang'
- name: string
- lang?: string
- xmltv_id?: string
- site_id?: string
- logo?: string
-}
-
-async function main() {
- const processor = new DataProcessor()
- const dataStorage = new Storage(DATA_DIR)
- const loader = new DataLoader({ storage: dataStorage })
- const data: DataLoaderData = await loader.load()
- const { channelsKeyById, feedsKeyByStreamId }: DataProcessorData = processor.process(data)
- const parser = new ChannelsParser({
- storage: new Storage()
- })
-
- let totalFiles = 0
- let totalErrors = 0
- let totalWarnings = 0
-
- const storage = new Storage()
- 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
-
- const channelList: ChannelList = await parser.parse(filepath)
-
- const bufferBySiteId = new Dictionary()
- const errors: ValidationError[] = []
- channelList.channels.forEach((channel: epgGrabber.Channel) => {
- const bufferId: string = channel.site_id
- if (bufferBySiteId.missing(bufferId)) {
- bufferBySiteId.set(bufferId, true)
- } else {
- errors.push({ type: 'duplicate', ...channel })
- totalErrors++
- }
-
- if (!langs.where('1', channel.lang ?? '')) {
- errors.push({ type: 'wrong_lang', ...channel })
- totalErrors++
- }
-
- if (!channel.xmltv_id) return
- const [channelId, feedId] = channel.xmltv_id.split('@')
-
- const foundChannel = channelsKeyById.get(channelId)
- if (!foundChannel) {
- errors.push({ type: 'wrong_channel_id', ...channel })
- totalWarnings++
- }
-
- if (feedId) {
- const foundFeed = feedsKeyByStreamId.get(channel.xmltv_id)
- if (!foundFeed) {
- errors.push({ type: 'wrong_feed_id', ...channel })
- totalWarnings++
- }
- }
- })
-
- if (errors.length) {
- console.log(chalk.underline(filepath))
- console.table(errors, ['type', 'lang', 'xmltv_id', 'site_id', 'name'])
- console.log()
- totalFiles++
- }
- }
-
- const totalProblems = totalWarnings + totalErrors
- if (totalProblems > 0) {
- console.log(
- chalk.red(
- `${totalProblems} problems (${totalErrors} errors, ${totalWarnings} warnings) in ${totalFiles} file(s)`
- )
- )
- if (totalErrors > 0) {
- process.exit(1)
- }
- }
-}
-
-main()
+import { Collection, Dictionary } from '@freearhey/core'
+import { Storage, File } from '@freearhey/storage-js'
+import epgGrabber, { EPGGrabber } from 'epg-grabber'
+import { loadData, data } from '../../api'
+import { Channel } from '../../models'
+import { program } from 'commander'
+import chalk from 'chalk'
+import langs from 'langs'
+
+program.argument('[filepath...]', 'Path to *.channels.xml files to validate').parse(process.argv)
+
+interface ValidationError {
+ type: 'duplicate' | 'wrong_channel_id' | 'wrong_feed_id' | 'wrong_lang'
+ name: string
+ lang: string | null
+ xmltv_id: string | null
+ site_id: string | null
+ logo: string | null
+}
+
+async function main() {
+ await loadData()
+ const { channelsKeyById, feedsKeyByStreamId } = data
+
+ let totalFiles = 0
+ let totalErrors = 0
+ let totalWarnings = 0
+
+ const storage = new Storage()
+ 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
+
+ const xml = await storage.load(filepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ const channelList = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
+
+ const bufferBySiteId = new Dictionary()
+ const errors: ValidationError[] = []
+ channelList.forEach((channel: Channel) => {
+ const bufferId: string = channel.site_id
+ if (bufferBySiteId.missing(bufferId)) {
+ bufferBySiteId.set(bufferId, true)
+ } else {
+ errors.push({ type: 'duplicate', ...channel.toObject() })
+ totalErrors++
+ }
+
+ if (!langs.where('1', channel.lang ?? '')) {
+ errors.push({ type: 'wrong_lang', ...channel.toObject() })
+ totalErrors++
+ }
+
+ if (!channel.xmltv_id) return
+ const [channelId, feedId] = channel.xmltv_id.split('@')
+
+ const foundChannel = channelsKeyById.get(channelId)
+ if (!foundChannel) {
+ errors.push({ type: 'wrong_channel_id', ...channel.toObject() })
+ totalWarnings++
+ }
+
+ if (feedId) {
+ const foundFeed = feedsKeyByStreamId.get(channel.xmltv_id)
+ if (!foundFeed) {
+ errors.push({ type: 'wrong_feed_id', ...channel.toObject() })
+ totalWarnings++
+ }
+ }
+ })
+
+ if (errors.length) {
+ console.log(chalk.underline(filepath))
+ console.table(errors, ['type', 'lang', 'xmltv_id', 'site_id', 'name'])
+ console.log()
+ totalFiles++
+ }
+ }
+
+ const totalProblems = totalWarnings + totalErrors
+ if (totalProblems > 0) {
+ console.log(
+ chalk.red(
+ `${totalProblems} problems (${totalErrors} errors, ${totalWarnings} warnings) in ${totalFiles} file(s)`
+ )
+ )
+ if (totalErrors > 0) {
+ process.exit(1)
+ }
+ }
+}
+
+main()
diff --git a/scripts/commands/epg/grab.ts b/scripts/commands/epg/grab.ts
index 6c8cc8f2..e7a55af4 100644
--- a/scripts/commands/epg/grab.ts
+++ b/scripts/commands/epg/grab.ts
@@ -1,11 +1,16 @@
-import { Logger, Timer, Collection } from '@freearhey/core'
+import { Logger, Timer, Collection, Template } from '@freearhey/core'
+import epgGrabber, { EPGGrabber, EPGGrabberMock } from 'epg-grabber'
+import { loadJs, parseProxy, SiteConfig, Queue } from '../../core'
+import { Channel, Guide, Program } from '../../models'
+import { SocksProxyAgent } from 'socks-proxy-agent'
+import { PromisyClass, TaskQueue } from 'cwait'
import { Storage } from '@freearhey/storage-js'
-import { QueueCreator, Job, ChannelsParser } from '../../core'
+import { QueueItem } from '../../types/queue'
import { Option, program } from 'commander'
import { SITES_DIR } from '../../constants'
-import { Channel } from 'epg-grabber'
+import { data, loadData } from '../../api'
+import dayjs, { Dayjs } from 'dayjs'
import path from 'path'
-import { ChannelList } from '../../models'
program
.addOption(new Option('-s, --site ', 'Name of the site to parse'))
@@ -18,14 +23,14 @@ program
.addOption(new Option('-o, --output ', 'Path to output file').default('guide.xml'))
.addOption(new Option('-l, --lang ', 'Filter channels by languages (ISO 639-1 codes)'))
.addOption(
- new Option('-t, --timeout ', 'Override the default timeout for each request').env(
- 'TIMEOUT'
- )
+ new Option('-t, --timeout ', 'Override the default timeout for each request')
+ .env('TIMEOUT')
+ .argParser(parseInt)
)
.addOption(
- new Option('-d, --delay ', 'Override the default delay between request').env(
- 'DELAY'
- )
+ new Option('-d, --delay ', 'Override the default delay between request')
+ .env('DELAY')
+ .argParser(parseInt)
)
.addOption(new Option('-x, --proxy ', 'Use the specified proxy').env('PROXY'))
.addOption(
@@ -33,12 +38,13 @@ program
'--days ',
'Override the number of days for which the program will be loaded (defaults to the value from the site config)'
)
- .argParser(value => parseInt(value))
+ .argParser(parseInt)
.env('DAYS')
)
.addOption(
new Option('--maxConnections ', 'Limit on the number of concurrent requests')
.default(1)
+ .argParser(parseInt)
.env('MAX_CONNECTIONS')
)
.addOption(
@@ -49,15 +55,15 @@ program
.addOption(new Option('--curl', 'Display each request as CURL').default(false).env('CURL'))
.parse()
-export interface GrabOptions {
+interface GrabOptions {
site?: string
channels?: string
output: string
gzip: boolean
curl: boolean
maxConnections: number
- timeout?: string
- delay?: string
+ timeout?: number
+ delay?: number
lang?: string
days?: number
proxy?: string
@@ -71,14 +77,13 @@ async function main() {
const logger = new Logger()
- logger.start('starting...')
+ logger.info('starting...')
logger.info('config:')
logger.tree(options)
logger.info('loading channels...')
const storage = new Storage()
- const parser = new ChannelsParser({ storage })
let files: string[] = []
if (options.site) {
@@ -89,46 +94,196 @@ async function main() {
files = await storage.list(options.channels)
}
- let channels = new Collection()
+ let channelsFromXML = new Collection()
for (const filepath of files) {
- const channelList: ChannelList = await parser.parse(filepath)
+ const xml = await storage.load(filepath)
+ const parsedChannels = EPGGrabber.parseChannelsXML(xml)
+ const _channelsFromXML = new Collection(parsedChannels).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
- channels = channels.concat(channelList.channels)
+ channelsFromXML.concat(_channelsFromXML)
}
if (options.lang) {
- channels = channels.filter((channel: Channel) => {
- if (!options.lang || !channel.lang) return true
+ channelsFromXML = channelsFromXML.filter((channel: Channel) => {
+ if (!options.lang) return true
return options.lang.includes(channel.lang)
})
}
- logger.info(` found ${channels.count()} channel(s)`)
+ logger.info(`found ${channelsFromXML.count()} channel(s)`)
+
+ logger.info('loading api data...')
+ await loadData()
+
+ logger.info('creating queue...')
+
+ let index = 0
+ const queue = new Queue()
+
+ for (const channel of channelsFromXML.all()) {
+ channel.index = index++
+ if (!channel.site || !channel.site_id || !channel.name) continue
+
+ const configObject = await loadJs(channel.getConfigPath())
+
+ const siteConfig = new SiteConfig(configObject)
+
+ siteConfig.filepath = channel.getConfigPath()
+
+ if (options.timeout !== undefined) {
+ siteConfig.request = { ...siteConfig.request, ...{ timeout: options.timeout } }
+ }
+ if (options.delay !== undefined) siteConfig.delay = options.delay
+ if (options.curl !== undefined) siteConfig.curl = options.curl
+ if (options.proxy !== undefined) {
+ const proxy = parseProxy(options.proxy)
+
+ if (
+ proxy.protocol &&
+ ['socks', 'socks5', 'socks5h', 'socks4', 'socks4a'].includes(String(proxy.protocol))
+ ) {
+ const socksProxyAgent = new SocksProxyAgent(options.proxy)
+
+ siteConfig.request = {
+ ...siteConfig.request,
+ ...{ httpAgent: socksProxyAgent, httpsAgent: socksProxyAgent }
+ }
+ } else {
+ siteConfig.request = { ...siteConfig.request, ...{ proxy } }
+ }
+ }
+
+ if (!channel.xmltv_id) channel.xmltv_id = channel.site_id
+
+ const days = options.days || siteConfig.days || 1
+ const currDate = dayjs.utc(process.env.CURR_DATE || new Date().toISOString())
+ const dates = Array.from({ length: days }, (_, day) => currDate.add(day, 'd'))
+
+ dates.forEach((date: Dayjs) => {
+ const key = `${channel.site}:${channel.lang}:${channel.xmltv_id}:${date.toJSON()}`
+ if (queue.has(key)) return
+ queue.add(key, {
+ channel,
+ date,
+ siteConfig,
+ error: null
+ })
+ })
+ }
+
+ const grabber = process.env.NODE_ENV === 'test' ? new EPGGrabberMock() : new EPGGrabber()
+
+ const taskQueue = new TaskQueue(Promise as PromisyClass, options.maxConnections)
+
+ const queueItems = queue.getItems()
+
+ const channels = new Collection()
+ const programs = new Collection()
+
+ let i = 1
+ const total = queueItems.count()
+
+ const requests = queueItems.map(
+ taskQueue.wrap(async (queueItem: QueueItem) => {
+ const { channel, siteConfig, date } = queueItem
+
+ if (!channel.logo) {
+ if (siteConfig.logo) {
+ channel.logo = await grabber.loadLogo(channel, date)
+ } else {
+ channel.logo = getLogoForChannel(channel)
+ }
+ }
+
+ channels.add(channel)
+
+ const channelPrograms = await grabber.grab(
+ channel,
+ date,
+ siteConfig,
+ (context: epgGrabber.Types.GrabCallbackContext, error: Error | null) => {
+ logger.info(
+ ` [${i}/${total}] ${context.channel.site} (${context.channel.lang}) - ${
+ context.channel.xmltv_id
+ } - ${context.date.format('MMM D, YYYY')} (${context.programs.length} programs)`
+ )
+ if (i < total) i++
+
+ if (error) {
+ logger.info(` ERR: ${error.message}`)
+ }
+ }
+ )
+
+ const _programs = new Collection(channelPrograms).map(
+ program => new Program(program.toObject())
+ )
+
+ programs.concat(_programs)
+ })
+ )
logger.info('run:')
- runJob({ logger, channels })
+
+ const timer = new Timer()
+ timer.start()
+
+ await Promise.all(requests.all())
+
+ const pathTemplate = new Template(options.output)
+
+ const channelsGroupedByKey = channels
+ .sortBy([(channel: Channel) => channel.index, (channel: Channel) => channel.xmltv_id])
+ .uniqBy((channel: Channel) => `${channel.xmltv_id}:${channel.site}:${channel.lang}`)
+ .groupBy((channel: Channel) => {
+ return pathTemplate.format({ lang: channel.lang || 'en', site: channel.site || '' })
+ })
+
+ const programsGroupedByKey = programs
+ .sortBy([(program: Program) => program.channel, (program: Program) => program.start])
+ .groupBy((program: Program) => {
+ const lang =
+ program.titles && program.titles.length && program.titles[0].lang
+ ? program.titles[0].lang
+ : 'en'
+
+ return pathTemplate.format({ lang, site: program.site || '' })
+ })
+
+ for (const groupKey of channelsGroupedByKey.keys()) {
+ const groupChannels = new Collection(channelsGroupedByKey.get(groupKey))
+ const groupPrograms = new Collection(programsGroupedByKey.get(groupKey))
+ const guide = new Guide({
+ filepath: groupKey,
+ gzip: options.gzip,
+ channels: groupChannels,
+ programs: groupPrograms
+ })
+
+ await guide.save({ logger })
+ }
+
+ logger.success(` done in ${timer.format('HH[h] mm[m] ss[s]')}`)
}
main()
-async function runJob({ logger, channels }: { logger: Logger; channels: Collection }) {
- const timer = new Timer()
- timer.start()
+function getLogoForChannel(channel: Channel): string | null {
+ const feedData = data.feedsKeyByStreamId.get(channel.xmltv_id)
+ if (feedData) {
+ const firstLogo = feedData.getLogos().first()
+ if (firstLogo) return firstLogo.url
+ }
- const queueCreator = new QueueCreator({
- channels,
- logger,
- options
- })
- const queue = await queueCreator.create()
- const job = new Job({
- queue,
- logger,
- options
- })
+ const [channelId] = channel.xmltv_id.split('@')
+ const channelData = data.channelsKeyById.get(channelId)
+ if (channelData) {
+ const firstLogo = channelData.getLogos().first()
+ if (firstLogo) return firstLogo.url
+ }
- await job.run()
-
- logger.success(` done in ${timer.format('HH[h] mm[m] ss[s]')}`)
+ return null
}
diff --git a/scripts/commands/sites/init.ts b/scripts/commands/sites/init.ts
index 44afd09b..03575a53 100644
--- a/scripts/commands/sites/init.ts
+++ b/scripts/commands/sites/init.ts
@@ -1,6 +1,6 @@
-import { Logger } from '@freearhey/core'
+import { SITES_DIR, EOL } from '../../constants'
import { Storage } from '@freearhey/storage-js'
-import { SITES_DIR } from '../../constants'
+import { Logger } from '@freearhey/core'
import { pathToFileURL } from 'node:url'
import { program } from 'commander'
import fs from 'fs-extra'
@@ -13,7 +13,7 @@ async function main() {
const storage = new Storage(SITES_DIR)
const logger = new Logger()
- logger.info(`Initializing "${domain}"...\r\n`)
+ logger.info(`Initializing "${domain}"...${EOL}`)
const dir = domain
if (await storage.exists(dir)) {
@@ -40,7 +40,7 @@ async function main() {
})
await storage.save(`${dir}/readme.md`, readmeTemplate.replace(//g, domain))
- logger.info('\r\nDone')
+ logger.info(`${EOL}Done`)
}
main()
diff --git a/scripts/commands/sites/update.ts b/scripts/commands/sites/update.ts
index 889f12fe..7f2939a7 100644
--- a/scripts/commands/sites/update.ts
+++ b/scripts/commands/sites/update.ts
@@ -1,26 +1,22 @@
-import { IssueLoader, HTMLTable, ChannelsParser } from '../../core'
-import { Logger, Collection } from '@freearhey/core'
-import { Storage } from '@freearhey/storage-js'
-import { ChannelList, Issue, Site } from '../../models'
+import { HTMLTableDataItem, HTMLTableRow, HTMLTableColumn } from '../../types/htmlTable'
import { SITES_DIR, ROOT_DIR } from '../../constants'
-import { Channel } from 'epg-grabber'
+import { Logger, Collection } from '@freearhey/core'
+import { Issue, Site, Channel } from '../../models'
+import { HTMLTable, loadIssues } from '../../core'
+import { Storage } from '@freearhey/storage-js'
+import * as epgGrabber from 'epg-grabber'
+import { EPGGrabber } from 'epg-grabber'
async function main() {
const logger = new Logger({ level: -999 })
- const issueLoader = new IssueLoader()
const sitesStorage = new Storage(SITES_DIR)
- const sites = new Collection()
-
- logger.info('loading channels...')
- const channelsParser = new ChannelsParser({
- storage: sitesStorage
- })
+ const sites = new Collection()
logger.info('loading list of sites')
const folders = await sitesStorage.list('*/')
logger.info('loading issues...')
- const issues = await issueLoader.load()
+ const issues = await loadIssues()
logger.info('putting the data together...')
const brokenGuideReports = issues.filter(issue =>
@@ -38,36 +34,43 @@ async function main() {
const files = await sitesStorage.list(`${domain}/*.channels.xml`)
for (const filepath of files) {
- const channelList: ChannelList = await channelsParser.parse(filepath)
+ const xml = await sitesStorage.load(filepath)
+ const channelsFromXML = EPGGrabber.parseChannelsXML(xml)
+ const channels = new Collection(channelsFromXML).map(
+ (channel: epgGrabber.Channel) => new Channel(channel.toObject())
+ )
- site.totalChannels += channelList.channels.count()
- site.markedChannels += channelList.channels
- .filter((channel: Channel) => channel.xmltv_id)
- .count()
+ site.totalChannels += channels.count()
+ site.markedChannels += channels.filter((channel: Channel) => channel.xmltv_id).count()
}
sites.add(site)
}
logger.info('creating sites table...')
- const tableData = new Collection()
+ const rows = new Collection()
sites.forEach((site: Site) => {
- tableData.add([
- { value: `${site.domain}` },
- { value: site.totalChannels, align: 'right' },
- { value: site.markedChannels, align: 'right' },
- { value: site.getStatus().emoji, align: 'center' },
- { value: site.getIssues().all().join(', ') }
- ])
+ rows.add(
+ new Collection([
+ { value: `${site.domain}` },
+ { value: site.totalChannels.toString(), align: 'right' },
+ { value: site.markedChannels.toString(), align: 'right' },
+ { value: site.getStatus().emoji, align: 'center' },
+ { value: site.getIssueUrls().all().join(', ') }
+ ])
+ )
})
logger.info('updating sites.md...')
- const table = new HTMLTable(tableData.all(), [
- { name: 'Site', align: 'left' },
- { name: 'Channels
(total / with xmltv-id)', colspan: 2, align: 'left' },
- { name: 'Status', align: 'left' },
- { name: 'Notes', align: 'left' }
- ])
+ const table = new HTMLTable(
+ rows,
+ new Collection([
+ { name: 'Site', align: 'left' },
+ { name: 'Channels
(total / with xmltv-id)', colspan: 2, align: 'left' },
+ { name: 'Status', align: 'left' },
+ { name: 'Notes', align: 'left' }
+ ])
+ )
const rootStorage = new Storage(ROOT_DIR)
const sitesTemplate = await new Storage().load('scripts/templates/_sites.md')
const sitesContent = sitesTemplate.replace('_TABLE_', table.toString())
diff --git a/scripts/constants.ts b/scripts/constants.ts
index 52c5d798..bdb32548 100644
--- a/scripts/constants.ts
+++ b/scripts/constants.ts
@@ -1,9 +1,10 @@
-export const ROOT_DIR = process.env.ROOT_DIR || '.'
-export const SITES_DIR = process.env.SITES_DIR || './sites'
-export const GUIDES_DIR = process.env.GUIDES_DIR || './guides'
-export const DATA_DIR = process.env.DATA_DIR || './temp/data'
-export const API_DIR = process.env.API_DIR || '.api'
-export const DOT_SITES_DIR = process.env.DOT_SITES_DIR || './.sites'
-export const TESTING = process.env.NODE_ENV === 'test' ? true : false
-export const OWNER = 'iptv-org'
-export const REPO = 'epg'
+export const ROOT_DIR = process.env.ROOT_DIR || '.'
+export const SITES_DIR = process.env.SITES_DIR || './sites'
+export const GUIDES_DIR = process.env.GUIDES_DIR || './guides'
+export const DATA_DIR = process.env.DATA_DIR || './temp/data'
+export const API_DIR = process.env.API_DIR || '.api'
+export const DOT_SITES_DIR = process.env.DOT_SITES_DIR || './.sites'
+export const TESTING = process.env.NODE_ENV === 'test' ? true : false
+export const OWNER = 'iptv-org'
+export const REPO = 'epg'
+export const EOL = '\r\n'
diff --git a/scripts/core/apiClient.ts b/scripts/core/apiClient.ts
deleted file mode 100644
index e4815a81..00000000
--- a/scripts/core/apiClient.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios'
-
-export class ApiClient {
- instance: AxiosInstance
-
- constructor() {
- this.instance = axios.create({
- baseURL: 'https://iptv-org.github.io/api',
- responseType: 'stream'
- })
- }
-
- get(url: string, options: AxiosRequestConfig): Promise {
- return this.instance.get(url, options)
- }
-}
diff --git a/scripts/core/channelsParser.ts b/scripts/core/channelsParser.ts
deleted file mode 100644
index 1ddcdfd2..00000000
--- a/scripts/core/channelsParser.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { EPGGrabber } from 'epg-grabber'
-import { Storage } from '@freearhey/storage-js'
-import { ChannelList } from '../models'
-
-interface ChannelsParserProps {
- storage: Storage
-}
-
-export class ChannelsParser {
- storage: Storage
-
- constructor({ storage }: ChannelsParserProps) {
- this.storage = storage
- }
-
- async parse(filepath: string): Promise {
- const content = await this.storage.load(filepath)
- const parsed = EPGGrabber.parseChannelsXML(content)
-
- return new ChannelList({ channels: parsed })
- }
-}
diff --git a/scripts/core/configLoader.ts b/scripts/core/configLoader.ts
deleted file mode 100644
index a49aee5a..00000000
--- a/scripts/core/configLoader.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { SiteConfig } from 'epg-grabber'
-import { pathToFileURL } from 'url'
-
-export class ConfigLoader {
- async load(filepath: string): Promise {
- const fileUrl = pathToFileURL(filepath).toString()
- const config = (await import(fileUrl)).default
- const defaultConfig = {
- days: 1,
- delay: 0,
- output: 'guide.xml',
- request: {
- method: 'GET',
- maxContentLength: 5242880,
- timeout: 30000,
- withCredentials: true,
- jar: null,
- responseType: 'arraybuffer',
- cache: false,
- headers: null,
- data: null
- },
- maxConnections: 1,
- site: undefined,
- url: undefined,
- parser: undefined,
- channels: undefined
- }
-
- return { ...defaultConfig, ...config } as SiteConfig
- }
-}
diff --git a/scripts/core/dataLoader.ts b/scripts/core/dataLoader.ts
deleted file mode 100644
index d46478df..00000000
--- a/scripts/core/dataLoader.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import type { DataLoaderProps, DataLoaderData } from '../types/dataLoader'
-import cliProgress, { MultiBar } from 'cli-progress'
-import { Storage } from '@freearhey/storage-js'
-import { ApiClient } from './apiClient'
-import numeral from 'numeral'
-
-export class DataLoader {
- client: ApiClient
- storage: Storage
- progressBar: MultiBar
-
- constructor(props: DataLoaderProps) {
- this.client = new ApiClient()
- this.storage = props.storage
- this.progressBar = new cliProgress.MultiBar({
- stopOnComplete: true,
- hideCursor: true,
- forceRedraw: true,
- barsize: 36,
- format(options, params, payload) {
- const filename = payload.filename.padEnd(18, ' ')
- const barsize = options.barsize || 40
- const percent = (params.progress * 100).toFixed(2)
- const speed = payload.speed ? numeral(payload.speed).format('0.0 b') + '/s' : 'N/A'
- const total = numeral(params.total).format('0.0 b')
- const completeSize = Math.round(params.progress * barsize)
- const incompleteSize = barsize - completeSize
- const bar =
- options.barCompleteString && options.barIncompleteString
- ? options.barCompleteString.substr(0, completeSize) +
- options.barGlue +
- options.barIncompleteString.substr(0, incompleteSize)
- : '-'.repeat(barsize)
-
- return `${filename} [${bar}] ${percent}% | ETA: ${params.eta}s | ${total} | ${speed}`
- }
- })
- }
-
- async load(): Promise {
- const [
- countries,
- regions,
- subdivisions,
- languages,
- categories,
- blocklist,
- channels,
- feeds,
- timezones,
- guides,
- streams,
- logos
- ] = await Promise.all([
- this.storage.json('countries.json'),
- this.storage.json('regions.json'),
- this.storage.json('subdivisions.json'),
- this.storage.json('languages.json'),
- this.storage.json('categories.json'),
- this.storage.json('blocklist.json'),
- this.storage.json('channels.json'),
- this.storage.json('feeds.json'),
- this.storage.json('timezones.json'),
- this.storage.json('guides.json'),
- this.storage.json('streams.json'),
- this.storage.json('logos.json')
- ])
-
- return {
- countries,
- regions,
- subdivisions,
- languages,
- categories,
- blocklist,
- channels,
- feeds,
- timezones,
- guides,
- streams,
- logos
- }
- }
-
- async download(filename: string) {
- if (!this.storage || !this.progressBar) return
-
- const stream = await this.storage.createStream(filename)
- const progressBar = this.progressBar.create(0, 0, { filename })
-
- this.client
- .get(filename, {
- responseType: 'stream',
- onDownloadProgress({ total, loaded, rate }) {
- if (total) progressBar.setTotal(total)
- progressBar.update(loaded, { speed: rate })
- }
- })
- .then(response => {
- response.data.pipe(stream)
- })
- }
-}
diff --git a/scripts/core/dataProcessor.ts b/scripts/core/dataProcessor.ts
deleted file mode 100644
index a104e675..00000000
--- a/scripts/core/dataProcessor.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { Channel, Feed, GuideChannel, Logo, Stream } from '../models'
-import { DataLoaderData } from '../types/dataLoader'
-import { Collection } from '@freearhey/core'
-
-export class DataProcessor {
-
- process(data: DataLoaderData) {
- let channels = new Collection(data.channels).map(data => new Channel(data))
- const channelsKeyById = channels.keyBy((channel: Channel) => channel.id)
-
- const guideChannels = new Collection(data.guides).map(data => new GuideChannel(data))
- const guideChannelsGroupedByStreamId = guideChannels.groupBy((channel: GuideChannel) =>
- channel.getStreamId()
- )
-
- const streams = new Collection(data.streams).map(data => new Stream(data))
- const streamsGroupedById = streams.groupBy((stream: Stream) => stream.getId())
-
- let feeds = new Collection(data.feeds).map(data =>
- new Feed(data)
- .withGuideChannels(guideChannelsGroupedByStreamId)
- .withStreams(streamsGroupedById)
- .withChannel(channelsKeyById)
- )
- const feedsKeyByStreamId = feeds.keyBy((feed: Feed) => feed.getStreamId())
-
- const logos = new Collection(data.logos).map(data =>
- new Logo(data).withFeed(feedsKeyByStreamId)
- )
- const logosGroupedByChannelId = logos.groupBy((logo: Logo) => logo.channelId)
- const logosGroupedByStreamId = logos.groupBy((logo: Logo) => logo.getStreamId())
-
- feeds = feeds.map((feed: Feed) => feed.withLogos(logosGroupedByStreamId))
- const feedsGroupedByChannelId = feeds.groupBy((feed: Feed) => feed.channelId)
-
- channels = channels.map((channel: Channel) =>
- channel.withFeeds(feedsGroupedByChannelId).withLogos(logosGroupedByChannelId)
- )
-
- return {
- guideChannelsGroupedByStreamId,
- feedsGroupedByChannelId,
- logosGroupedByChannelId,
- logosGroupedByStreamId,
- streamsGroupedById,
- feedsKeyByStreamId,
- channelsKeyById,
- guideChannels,
- channels,
- streams,
- feeds,
- logos
- }
- }
-}
diff --git a/scripts/core/date.js b/scripts/core/date.js
deleted file mode 100644
index 777f9c33..00000000
--- a/scripts/core/date.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import dayjs from 'dayjs'
-import utc from 'dayjs/plugin/utc'
-
-dayjs.extend(utc)
-
-const date = {}
-
-date.getUTC = function (d = null) {
- if (typeof d === 'string') return dayjs.utc(d).startOf('d')
-
- return dayjs.utc().startOf('d')
-}
-
-export default date
diff --git a/scripts/core/grabber.ts b/scripts/core/grabber.ts
deleted file mode 100644
index d1881af7..00000000
--- a/scripts/core/grabber.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import { EPGGrabber, GrabCallbackData, EPGGrabberMock, SiteConfig, Channel } from 'epg-grabber'
-import { Logger, Collection } from '@freearhey/core'
-import { Queue, ProxyParser } from './'
-import { GrabOptions } from '../commands/epg/grab'
-import { TaskQueue, PromisyClass } from 'cwait'
-import { SocksProxyAgent } from 'socks-proxy-agent'
-
-interface GrabberProps {
- logger: Logger
- queue: Queue
- options: GrabOptions
-}
-
-export class Grabber {
- logger: Logger
- queue: Queue
- options: GrabOptions
- grabber: EPGGrabber | EPGGrabberMock
-
- constructor({ logger, queue, options }: GrabberProps) {
- this.logger = logger
- this.queue = queue
- this.options = options
- this.grabber = process.env.NODE_ENV === 'test' ? new EPGGrabberMock() : new EPGGrabber()
- }
-
- async grab(): Promise<{ channels: Collection; programs: Collection }> {
- const proxyParser = new ProxyParser()
- const taskQueue = new TaskQueue(Promise as PromisyClass, this.options.maxConnections)
-
- const total = this.queue.size()
-
- const channels = new Collection()
- let programs = new Collection()
- let i = 1
-
- await Promise.all(
- this.queue.items().map(
- taskQueue.wrap(
- async (queueItem: { channel: Channel; config: SiteConfig; date: string }) => {
- const { channel, config, date } = queueItem
-
- channels.add(channel)
-
- if (this.options.timeout !== undefined) {
- const timeout = parseInt(this.options.timeout)
- config.request = { ...config.request, ...{ timeout } }
- }
-
- if (this.options.delay !== undefined) {
- const delay = parseInt(this.options.delay)
- config.delay = delay
- }
-
- if (this.options.proxy !== undefined) {
- const proxy = proxyParser.parse(this.options.proxy)
-
- if (
- proxy.protocol &&
- ['socks', 'socks5', 'socks5h', 'socks4', 'socks4a'].includes(String(proxy.protocol))
- ) {
- const socksProxyAgent = new SocksProxyAgent(this.options.proxy)
-
- config.request = {
- ...config.request,
- ...{ httpAgent: socksProxyAgent, httpsAgent: socksProxyAgent }
- }
- } else {
- config.request = { ...config.request, ...{ proxy } }
- }
- }
-
- if (this.options.curl === true) {
- config.curl = true
- }
-
- const _programs = await this.grabber.grab(
- channel,
- date,
- config,
- (data: GrabCallbackData, error: Error | null) => {
- const { programs, date } = data
-
- this.logger.info(
- ` [${i}/${total}] ${channel.site} (${channel.lang}) - ${
- channel.xmltv_id
- } - ${date.format('MMM D, YYYY')} (${programs.length} programs)`
- )
- if (i < total) i++
-
- if (error) {
- this.logger.info(` ERR: ${error.message}`)
- }
- }
- )
-
- programs = programs.concat(new Collection(_programs))
- }
- )
- )
- )
-
- return { channels, programs }
- }
-}
diff --git a/scripts/core/guideManager.ts b/scripts/core/guideManager.ts
deleted file mode 100644
index a84304ac..00000000
--- a/scripts/core/guideManager.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import { Collection, Logger, Zip, StringTemplate } from '@freearhey/core'
-import { Storage } from '@freearhey/storage-js'
-import epgGrabber from 'epg-grabber'
-import { OptionValues } from 'commander'
-import { Channel, Feed, Guide } from '../models'
-import path from 'path'
-import { DataLoader, DataProcessor } from '.'
-import { DataLoaderData } from '../types/dataLoader'
-import { DataProcessorData } from '../types/dataProcessor'
-import { DATA_DIR } from '../constants'
-
-interface GuideManagerProps {
- options: OptionValues
- logger: Logger
- channels: Collection
- programs: Collection
-}
-
-export class GuideManager {
- options: OptionValues
- logger: Logger
- channels: Collection
- programs: Collection
-
- constructor({ channels, programs, logger, options }: GuideManagerProps) {
- this.options = options
- this.logger = logger
- this.channels = channels
- this.programs = programs
- }
-
- async createGuides() {
- const pathTemplate = new StringTemplate(this.options.output)
-
- const processor = new DataProcessor()
- const dataStorage = new Storage(DATA_DIR)
- const loader = new DataLoader({ storage: dataStorage })
- const data: DataLoaderData = await loader.load()
- const { feedsKeyByStreamId, channelsKeyById }: DataProcessorData = processor.process(data)
-
- const groupedChannels = this.channels
- .map((channel: epgGrabber.Channel) => {
- if (channel.xmltv_id && !channel.icon) {
- const foundFeed: Feed = feedsKeyByStreamId.get(channel.xmltv_id)
- if (foundFeed && foundFeed.hasLogo()) {
- channel.icon = foundFeed.getLogoUrl()
- } else {
- const [channelId] = channel.xmltv_id.split('@')
- const foundChannel: Channel = channelsKeyById.get(channelId)
- if (foundChannel && foundChannel.hasLogo()) {
- channel.icon = foundChannel.getLogoUrl()
- }
- }
- }
-
- return channel
- })
- .orderBy([
- (channel: epgGrabber.Channel) => channel.index,
- (channel: epgGrabber.Channel) => channel.xmltv_id
- ])
- .uniqBy(
- (channel: epgGrabber.Channel) => `${channel.xmltv_id}:${channel.site}:${channel.lang}`
- )
- .groupBy((channel: epgGrabber.Channel) => {
- return pathTemplate.format({ lang: channel.lang || 'en', site: channel.site || '' })
- })
-
- const groupedPrograms = this.programs
- .orderBy([
- (program: epgGrabber.Program) => program.channel,
- (program: epgGrabber.Program) => program.start
- ])
- .groupBy((program: epgGrabber.Program) => {
- const lang =
- program.titles && program.titles.length && program.titles[0].lang
- ? program.titles[0].lang
- : 'en'
-
- return pathTemplate.format({ lang, site: program.site || '' })
- })
-
- for (const groupKey of groupedPrograms.keys()) {
- const guide = new Guide({
- filepath: groupKey,
- gzip: this.options.gzip,
- channels: new Collection(groupedChannels.get(groupKey)),
- programs: new Collection(groupedPrograms.get(groupKey))
- })
-
- await this.save(guide)
- }
- }
-
- async save(guide: Guide) {
- const storage = new Storage(path.dirname(guide.filepath))
- const xmlFilepath = guide.filepath
- const xmlFilename = path.basename(xmlFilepath)
- this.logger.info(` saving to "${xmlFilepath}"...`)
- const xmltv = guide.toString()
- await storage.save(xmlFilename, xmltv)
-
- if (guide.gzip) {
- const zip = new Zip()
- const compressed = zip.compress(xmltv)
- const gzFilepath = `${guide.filepath}.gz`
- const gzFilename = path.basename(gzFilepath)
- this.logger.info(` saving to "${gzFilepath}"...`)
- await storage.save(gzFilename, compressed)
- }
- }
-}
diff --git a/scripts/core/htmlTable.ts b/scripts/core/htmlTable.ts
index 6b917d6b..fd199e91 100644
--- a/scripts/core/htmlTable.ts
+++ b/scripts/core/htmlTable.ts
@@ -1,55 +1,45 @@
-interface Column {
- name: string
- nowrap?: boolean
- align?: string
- colspan?: number
-}
-
-type DataItem = {
- value: string
- nowrap?: boolean
- align?: string
- colspan?: number
-}[]
-
-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) {
- const nowrap = column.nowrap ? ' nowrap' : ''
- const align = column.align ? ` align="${column.align}"` : ''
- const colspan = column.colspan ? ` colspan="${column.colspan}"` : ''
-
- output += `| ${column.name} | `
- }
- output += '
\r\n \r\n'
-
- output += ' \r\n'
- for (const row of this.data) {
- output += ' '
- for (const item of row) {
- const nowrap = item.nowrap ? ' nowrap' : ''
- const align = item.align ? ` align="${item.align}"` : ''
- const colspan = item.colspan ? ` colspan="${item.colspan}"` : ''
-
- output += `| ${item.value} | `
- }
- output += '
\r\n'
- }
- output += ' \r\n'
-
- output += '
'
-
- return output
- }
-}
+import { HTMLTableColumn, HTMLTableDataItem, HTMLTableRow } from '../types/htmlTable'
+import { Collection } from '@freearhey/core'
+import { EOL } from '../constants'
+
+export class HTMLTable {
+ rows: Collection
+ columns: Collection
+
+ constructor(rows: Collection, columns: Collection) {
+ this.rows = rows
+ this.columns = columns
+ }
+
+ toString() {
+ let output = `${EOL}`
+
+ output += ` ${EOL} `
+ this.columns.forEach((column: HTMLTableColumn) => {
+ const nowrap = column.nowrap ? ' nowrap' : ''
+ const align = column.align ? ` align="${column.align}"` : ''
+ const colspan = column.colspan ? ` colspan="${column.colspan}"` : ''
+
+ output += `| ${column.name} | `
+ })
+ output += `
${EOL} ${EOL}`
+
+ output += ` ${EOL}`
+ this.rows.forEach((row: HTMLTableRow) => {
+ output += ' '
+ row.forEach((item: HTMLTableDataItem) => {
+ const nowrap = item.nowrap ? ' nowrap' : ''
+ const align = item.align ? ` align="${item.align}"` : ''
+ const colspan = item.colspan ? ` colspan="${item.colspan}"` : ''
+
+ output += `| ${item.value} | `
+ })
+ output += `
${EOL}`
+ })
+ output += ` ${EOL}`
+
+ output += '
'
+
+ return output
+ }
+}
diff --git a/scripts/core/index.ts b/scripts/core/index.ts
index 8694174a..6d69e053 100644
--- a/scripts/core/index.ts
+++ b/scripts/core/index.ts
@@ -1,14 +1,4 @@
-export * from './apiClient'
-export * from './channelsParser'
-export * from './configLoader'
-export * from './dataLoader'
-export * from './dataProcessor'
-export * from './grabber'
-export * from './guideManager'
-export * from './htmlTable'
-export * from './issueLoader'
-export * from './issueParser'
-export * from './job'
-export * from './proxyParser'
-export * from './queue'
-export * from './queueCreator'
+export * from './htmlTable'
+export * from './siteConfig'
+export * from './utils'
+export * from './queue'
diff --git a/scripts/core/issueLoader.ts b/scripts/core/issueLoader.ts
deleted file mode 100644
index 855f99e2..00000000
--- a/scripts/core/issueLoader.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { restEndpointMethods } from '@octokit/plugin-rest-endpoint-methods'
-import { paginateRest } from '@octokit/plugin-paginate-rest'
-import { TESTING, OWNER, REPO } from '../constants'
-import { Collection } from '@freearhey/core'
-import { Octokit } from '@octokit/core'
-import { IssueParser } from './'
-
-const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
-const octokit = new CustomOctokit()
-
-export class IssueLoader {
- async load(props?: { labels: string[] | string }) {
- let labels = ''
- if (props && props.labels) {
- labels = Array.isArray(props.labels) ? props.labels.join(',') : props.labels
- }
- let issues: object[] = []
- if (TESTING) {
- issues = (await import('../../tests/__data__/input/sites_update/issues.mjs')).default
- } else {
- issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
- owner: OWNER,
- repo: REPO,
- per_page: 100,
- labels,
- state: 'open',
- 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
deleted file mode 100644
index 2db0f9dd..00000000
--- a/scripts/core/issueParser.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-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/job.ts b/scripts/core/job.ts
deleted file mode 100644
index db37ba15..00000000
--- a/scripts/core/job.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Logger } from '@freearhey/core'
-import { Queue, Grabber, GuideManager } from '.'
-import { GrabOptions } from '../commands/epg/grab'
-
-interface JobProps {
- options: GrabOptions
- logger: Logger
- queue: Queue
-}
-
-export class Job {
- options: GrabOptions
- logger: Logger
- grabber: Grabber
-
- constructor({ queue, logger, options }: JobProps) {
- this.options = options
- this.logger = logger
- this.grabber = new Grabber({ logger, queue, options })
- }
-
- async run() {
- const { channels, programs } = await this.grabber.grab()
-
- const manager = new GuideManager({
- channels,
- programs,
- options: this.options,
- logger: this.logger
- })
-
- await manager.createGuides()
- }
-}
diff --git a/scripts/core/proxyParser.ts b/scripts/core/proxyParser.ts
deleted file mode 100644
index 9cede1af..00000000
--- a/scripts/core/proxyParser.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { URL } from 'node:url'
-
-interface ProxyParserResult {
- protocol: string | null
- auth?: {
- username?: string
- password?: string
- }
- host: string
- port: number | null
-}
-
-export class ProxyParser {
- parse(_url: string): ProxyParserResult {
- const parsed = new URL(_url)
-
- const result: ProxyParserResult = {
- protocol: parsed.protocol.replace(':', '') || null,
- host: parsed.hostname,
- port: parsed.port ? parseInt(parsed.port) : null
- }
-
- if (parsed.username || parsed.password) {
- result.auth = {}
- if (parsed.username) result.auth.username = parsed.username
- if (parsed.password) result.auth.password = parsed.password
- }
-
- return result
- }
-}
diff --git a/scripts/core/queue.ts b/scripts/core/queue.ts
index 106c111e..1237e5d0 100644
--- a/scripts/core/queue.ts
+++ b/scripts/core/queue.ts
@@ -1,45 +1,18 @@
-import { Dictionary } from '@freearhey/core'
-import { SiteConfig, Channel } from 'epg-grabber'
-
-export interface QueueItem {
- channel: Channel
- date: string
- config: SiteConfig
- error: string | null
-}
-
-export class Queue {
- _data: Dictionary
-
- constructor() {
- this._data = new Dictionary()
- }
-
- missing(key: string): boolean {
- return this._data.missing(key)
- }
-
- add(
- key: string,
- { channel, config, date }: { channel: Channel; date: string | null; config: SiteConfig }
- ) {
- this._data.set(key, {
- channel,
- date,
- config,
- error: null
- })
- }
-
- size(): number {
- return Object.values(this._data.data()).length
- }
-
- items(): QueueItem[] {
- return Object.values(this._data.data()) as QueueItem[]
- }
-
- isEmpty(): boolean {
- return this.size() === 0
- }
-}
+import { Collection, Dictionary } from '@freearhey/core'
+import { QueueItem } from '../types/queue'
+
+export class Queue {
+ #items: Dictionary = new Dictionary()
+
+ add(key: string, data: QueueItem) {
+ this.#items.set(key, data)
+ }
+
+ has(key: string): boolean {
+ return this.#items.has(key)
+ }
+
+ getItems(): Collection {
+ return new Collection(Object.values(this.#items.data()))
+ }
+}
diff --git a/scripts/core/queueCreator.ts b/scripts/core/queueCreator.ts
deleted file mode 100644
index 56333dcb..00000000
--- a/scripts/core/queueCreator.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { Storage, Collection, DateTime, Logger } from '@freearhey/core'
-import { SITES_DIR, DATA_DIR } from '../constants'
-import { GrabOptions } from '../commands/epg/grab'
-import { ConfigLoader, Queue } from './'
-import { SiteConfig } from 'epg-grabber'
-import path from 'path'
-
-interface QueueCreatorProps {
- logger: Logger
- options: GrabOptions
- channels: Collection
-}
-
-export class QueueCreator {
- configLoader: ConfigLoader
- logger: Logger
- sitesStorage: Storage
- dataStorage: Storage
- channels: Collection
- options: GrabOptions
-
- constructor({ channels, logger, options }: QueueCreatorProps) {
- this.channels = channels
- this.logger = logger
- this.sitesStorage = new Storage()
- this.dataStorage = new Storage(DATA_DIR)
- this.options = options
- this.configLoader = new ConfigLoader()
- }
-
- async create(): Promise {
- let index = 0
- const queue = new Queue()
- for (const channel of this.channels.all()) {
- channel.index = index++
- if (!channel.site || !channel.site_id || !channel.name) continue
-
- const configPath = path.resolve(SITES_DIR, `${channel.site}/${channel.site}.config.js`)
- const config: SiteConfig = await this.configLoader.load(configPath)
-
- if (!channel.xmltv_id) {
- channel.xmltv_id = channel.site_id
- }
-
- const days = this.options.days || config.days || 1
- const currDate = new DateTime(process.env.CURR_DATE || new Date().toISOString())
- const dates = Array.from({ length: days }, (_, day) => currDate.add(day, 'd'))
- dates.forEach((date: DateTime) => {
- const dateString = date.toJSON()
- const key = `${channel.site}:${channel.lang}:${channel.xmltv_id}:${dateString}`
- if (queue.missing(key)) {
- queue.add(key, {
- channel,
- date: dateString,
- config
- })
- }
- })
- }
-
- return queue
- }
-}
diff --git a/scripts/core/siteConfig.ts b/scripts/core/siteConfig.ts
new file mode 100644
index 00000000..e7895020
--- /dev/null
+++ b/scripts/core/siteConfig.ts
@@ -0,0 +1,71 @@
+import * as epgGrabber from 'epg-grabber'
+import _ from 'lodash'
+
+const _default = {
+ days: 1,
+ delay: 0,
+ output: 'guide.xml',
+ request: {
+ method: 'GET',
+ maxContentLength: 5242880,
+ timeout: 30000,
+ withCredentials: true,
+ jar: null,
+ responseType: 'arraybuffer',
+ cache: false,
+ headers: null,
+ data: null
+ },
+ maxConnections: 1,
+ site: undefined,
+ url: undefined,
+ parser: undefined,
+ channels: undefined,
+ lang: 'en',
+ debug: false,
+ gzip: false,
+ curl: false,
+ logo: ''
+}
+
+export class SiteConfig {
+ days: number
+ lang: string
+ delay: number
+ debug: boolean
+ gzip: boolean
+ curl: boolean
+ maxConnections: number
+ output: string
+ request: epgGrabber.Types.SiteConfigRequestConfig
+ site: string
+ channels?: string | string[]
+ url: ((context: epgGrabber.Types.SiteConfigRequestContext) => string | Promise) | string
+ parser: (
+ context: epgGrabber.Types.SiteConfigParserContext
+ ) =>
+ | epgGrabber.Types.SiteConfigParserResult[]
+ | Promise
+ logo: ((context: epgGrabber.Types.SiteConfigRequestContext) => string | Promise) | string
+ filepath: string
+
+ constructor(config: epgGrabber.Types.SiteConfigObject) {
+ this.site = config.site
+ this.channels = config.channels
+ this.url = config.url
+ this.parser = config.parser
+ this.filepath = config.filepath
+
+ this.days = config.days || _default.days
+ this.lang = config.lang || _default.lang
+ this.delay = config.delay || _default.delay
+ this.debug = config.debug || _default.debug
+ this.maxConnections = config.maxConnections || _default.maxConnections
+ this.gzip = config.gzip || _default.gzip
+ this.curl = config.curl || _default.curl
+ this.output = config.output || _default.output
+ this.logo = config.logo || _default.logo
+
+ this.request = _.merge(_default.request, config.request)
+ }
+}
diff --git a/scripts/core/utils.ts b/scripts/core/utils.ts
new file mode 100644
index 00000000..23d2145e
--- /dev/null
+++ b/scripts/core/utils.ts
@@ -0,0 +1,106 @@
+import { restEndpointMethods } from '@octokit/plugin-rest-endpoint-methods'
+import { paginateRest } from '@octokit/plugin-paginate-rest'
+import { TESTING, OWNER, REPO, EOL } from '../constants'
+import { Collection } from '@freearhey/core'
+import { Channel } from '../models/channel'
+import { AxiosProxyConfig } from 'axios'
+import { Octokit } from '@octokit/core'
+import { pathToFileURL } from 'url'
+import { Issue } from '../models'
+import { URL } from 'node:url'
+
+export function generateChannelsXML(channels: Collection): string {
+ let output = `${EOL}${EOL}`
+
+ channels.forEach((channel: Channel) => {
+ const logo = channel.logo ? ` logo="${escapeString(channel.logo)}"` : ''
+ const xmltv_id = channel.xmltv_id ? escapeString(channel.xmltv_id) : ''
+ const lang = channel.lang || ''
+ const site_id = channel.site_id ? escapeString(channel.site_id) : ''
+ const site = channel.site || ''
+ const displayName = channel.name ? escapeString(channel.name) : ''
+
+ output += ` ${displayName}${EOL}`
+ })
+
+ output += `${EOL}`
+
+ return output
+}
+
+export function escapeString(value: string, defaultValue = '') {
+ if (!value) return defaultValue
+
+ const regex = new RegExp(
+ '((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))|([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDF' +
+ 'FE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uD' +
+ 'FFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])' +
+ '|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\' +
+ 'uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF' +
+ '[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\' +
+ 'uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|' +
+ '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))',
+ 'g'
+ )
+
+ value = String(value || '').replace(regex, '')
+
+ return value
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''')
+ .replace(/\n|\r/g, ' ')
+ .replace(/ +/g, ' ')
+ .trim()
+}
+
+export function parseProxy(string: string): AxiosProxyConfig {
+ const parsed = new URL(string)
+
+ const proxy: AxiosProxyConfig = {
+ protocol: parsed.protocol.replace(':', ''),
+ host: parsed.hostname,
+ port: parsed.port ? parseInt(parsed.port) : 8080
+ }
+
+ if (parsed.username || parsed.password) {
+ proxy.auth = { username: parsed.username, password: parsed.password }
+ }
+
+ return proxy
+}
+
+export async function loadJs(filepath: string) {
+ const fileUrl = pathToFileURL(filepath).toString()
+
+ return (await import(fileUrl)).default
+}
+
+export async function loadIssues(props?: { labels: string[] | string }) {
+ const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
+ const octokit = new CustomOctokit()
+
+ let labels = ''
+ if (props && props.labels) {
+ labels = Array.isArray(props.labels) ? props.labels.join(',') : props.labels
+ }
+ let issues: object[] = []
+ if (TESTING) {
+ issues = (await import('../../tests/__data__/input/sites_update/issues.mjs')).default
+ } else {
+ issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
+ owner: OWNER,
+ repo: REPO,
+ per_page: 100,
+ labels,
+ state: 'open',
+ headers: {
+ 'X-GitHub-Api-Version': '2022-11-28'
+ }
+ })
+ }
+
+ return new Collection(issues).map(data => new Issue(data))
+}
diff --git a/scripts/models/channel.ts b/scripts/models/channel.ts
index e5bbde5e..087a3977 100644
--- a/scripts/models/channel.ts
+++ b/scripts/models/channel.ts
@@ -1,164 +1,23 @@
-import { ChannelData, ChannelSearchableData } from '../types/channel'
-import { Collection, Dictionary } from '@freearhey/core'
-import { Stream, Feed, Logo, GuideChannel } from './'
-
-export class Channel {
- id?: string
- name?: string
- altNames?: Collection
- network?: string
- owners?: Collection
- countryCode?: string
- subdivisionCode?: string
- cityName?: string
- categoryIds?: Collection
- isNSFW = false
- launched?: string
- closed?: string
- replacedBy?: string
- website?: string
- feeds?: Collection
- logos: Collection = new Collection()
-
- constructor(data?: ChannelData) {
- if (!data) return
-
- this.id = data.id
- this.name = data.name
- this.altNames = new Collection(data.alt_names)
- this.network = data.network || undefined
- this.owners = new Collection(data.owners)
- this.countryCode = data.country
- this.subdivisionCode = data.subdivision || undefined
- this.cityName = data.city || undefined
- this.categoryIds = new Collection(data.categories)
- this.isNSFW = data.is_nsfw
- this.launched = data.launched || undefined
- this.closed = data.closed || undefined
- this.replacedBy = data.replaced_by || undefined
- this.website = data.website || undefined
- }
-
- withFeeds(feedsGroupedByChannelId: Dictionary): this {
- if (this.id) this.feeds = new Collection(feedsGroupedByChannelId.get(this.id))
-
- return this
- }
-
- withLogos(logosGroupedByChannelId: Dictionary): this {
- if (this.id) this.logos = new Collection(logosGroupedByChannelId.get(this.id))
-
- return this
- }
-
- getFeeds(): Collection {
- if (!this.feeds) return new Collection()
-
- return this.feeds
- }
-
- getGuideChannels(): Collection {
- let channels = new Collection()
-
- this.getFeeds().forEach((feed: Feed) => {
- channels = channels.concat(feed.getGuideChannels())
- })
-
- return channels
- }
-
- getGuideChannelNames(): Collection {
- return this.getGuideChannels()
- .map((channel: GuideChannel) => channel.siteName)
- .uniq()
- }
-
- getStreams(): Collection {
- let streams = new Collection()
-
- this.getFeeds().forEach((feed: Feed) => {
- streams = streams.concat(feed.getStreams())
- })
-
- return streams
- }
-
- getStreamNames(): Collection {
- return this.getStreams()
- .map((stream: Stream) => stream.getName())
- .uniq()
- }
-
- getFeedFullNames(): Collection {
- return this.getFeeds()
- .map((feed: Feed) => feed.getFullName())
- .uniq()
- }
-
- getName(): string {
- return this.name || ''
- }
-
- getId(): string {
- return this.id || ''
- }
-
- getAltNames(): Collection {
- return this.altNames || new Collection()
- }
-
- getLogos(): Collection {
- function feed(logo: Logo): number {
- if (!logo.feed) return 1
- if (logo.feed.isMain) return 1
-
- return 0
- }
-
- function format(logo: Logo): number {
- const levelByFormat: Record = {
- SVG: 0,
- PNG: 3,
- APNG: 1,
- WebP: 1,
- AVIF: 1,
- JPEG: 2,
- GIF: 1
- }
-
- return logo.format ? levelByFormat[logo.format] : 0
- }
-
- function size(logo: Logo): number {
- return Math.abs(512 - logo.width) + Math.abs(512 - logo.height)
- }
-
- return this.logos.orderBy([feed, format, size], ['desc', 'desc', 'asc'], false)
- }
-
- getLogo(): Logo | undefined {
- return this.getLogos().first()
- }
-
- hasLogo(): boolean {
- return this.getLogos().notEmpty()
- }
-
- getLogoUrl(): string {
- const logo = this.getLogo()
- if (!logo) return ''
-
- return logo.url || ''
- }
-
- getSearchable(): ChannelSearchableData {
- return {
- id: this.getId(),
- name: this.getName(),
- altNames: this.getAltNames().all(),
- guideNames: this.getGuideChannelNames().all(),
- streamNames: this.getStreamNames().all(),
- feedFullNames: this.getFeedFullNames().all()
- }
- }
-}
+import { ChannelGuideObject } from '../types/channel'
+import * as epgGrabber from 'epg-grabber'
+import { SITES_DIR } from '../constants'
+import path from 'node:path'
+
+export class Channel extends epgGrabber.Channel {
+ getGuideObject(): ChannelGuideObject {
+ const [channelId, feedId] = this.xmltv_id.split('@')
+
+ return {
+ channel: channelId || null,
+ feed: feedId || null,
+ site: this.site,
+ site_id: this.site_id,
+ site_name: this.name,
+ lang: this.lang || 'en'
+ }
+ }
+
+ getConfigPath(): string {
+ return path.resolve(SITES_DIR, `${this.site}/${this.site}.config.js`)
+ }
+}
diff --git a/scripts/models/channelList.ts b/scripts/models/channelList.ts
deleted file mode 100644
index 951e0a90..00000000
--- a/scripts/models/channelList.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { Collection } from '@freearhey/core'
-import epgGrabber from 'epg-grabber'
-
-export class ChannelList {
- channels: Collection = new Collection()
-
- constructor(data: { channels: epgGrabber.Channel[] }) {
- this.channels = new Collection(data.channels)
- }
-
- add(channel: epgGrabber.Channel): this {
- this.channels.add(channel)
-
- return this
- }
-
- get(siteId: string): epgGrabber.Channel | undefined {
- return this.channels.find((channel: epgGrabber.Channel) => channel.site_id == siteId)
- }
-
- sort(): this {
- this.channels = this.channels.orderBy([
- (channel: epgGrabber.Channel) => channel.lang || '_',
- (channel: epgGrabber.Channel) => (channel.xmltv_id ? channel.xmltv_id.toLowerCase() : '0'),
- (channel: epgGrabber.Channel) => channel.site_id
- ])
-
- return this
- }
-
- toString() {
- function escapeString(value: string, defaultValue = '') {
- if (!value) return defaultValue
-
- const regex = new RegExp(
- '((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))|([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDF' +
- 'FE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uD' +
- 'FFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])' +
- '|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\' +
- 'uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF' +
- '[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\' +
- 'uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|' +
- '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))',
- 'g'
- )
-
- value = String(value || '').replace(regex, '')
-
- return value
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
- .replace(/\n|\r/g, ' ')
- .replace(/ +/g, ' ')
- .trim()
- }
-
- let output = '\r\n\r\n'
-
- this.channels.forEach((channel: epgGrabber.Channel) => {
- const logo = channel.logo ? ` logo="${channel.logo}"` : ''
- const xmltv_id = channel.xmltv_id ? escapeString(channel.xmltv_id) : ''
- const lang = channel.lang || ''
- const site_id = channel.site_id || ''
- const site = channel.site || ''
- const displayName = channel.name ? escapeString(channel.name) : ''
-
- output += ` ${displayName}\r\n`
- })
-
- output += '\r\n'
-
- return output
- }
-}
diff --git a/scripts/models/feed.ts b/scripts/models/feed.ts
deleted file mode 100644
index 7e91e305..00000000
--- a/scripts/models/feed.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { Collection, Dictionary } from '@freearhey/core'
-import { FeedData } from '../types/feed'
-import { Logo, Channel } from '.'
-
-export class Feed {
- channelId: string
- channel?: Channel
- id: string
- name: string
- isMain: boolean
- broadcastAreaCodes: Collection
- languageCodes: Collection
- timezoneIds: Collection
- videoFormat: string
- guideChannels?: Collection
- streams?: Collection
- logos: Collection = new Collection()
-
- constructor(data: FeedData) {
- this.channelId = data.channel
- this.id = data.id
- this.name = data.name
- this.isMain = data.is_main
- this.broadcastAreaCodes = new Collection(data.broadcast_area)
- this.languageCodes = new Collection(data.languages)
- this.timezoneIds = new Collection(data.timezones)
- this.videoFormat = data.video_format
- }
-
- withChannel(channelsKeyById: Dictionary): this {
- this.channel = channelsKeyById.get(this.channelId)
-
- return this
- }
-
- withStreams(streamsGroupedById: Dictionary): this {
- this.streams = new Collection(streamsGroupedById.get(`${this.channelId}@${this.id}`))
-
- if (this.isMain) {
- this.streams = this.streams.concat(new Collection(streamsGroupedById.get(this.channelId)))
- }
-
- return this
- }
-
- withGuideChannels(guideChannelsGroupedByStreamId: Dictionary): this {
- this.guideChannels = new Collection(
- guideChannelsGroupedByStreamId.get(`${this.channelId}@${this.id}`)
- )
-
- if (this.isMain) {
- this.guideChannels = this.guideChannels.concat(
- new Collection(guideChannelsGroupedByStreamId.get(this.channelId))
- )
- }
-
- return this
- }
-
- withLogos(logosGroupedByStreamId: Dictionary): this {
- this.logos = new Collection(logosGroupedByStreamId.get(this.getStreamId()))
-
- return this
- }
-
- getGuideChannels(): Collection {
- if (!this.guideChannels) return new Collection()
-
- return this.guideChannels
- }
-
- getStreams(): Collection {
- if (!this.streams) return new Collection()
-
- return this.streams
- }
-
- getFullName(): string {
- if (!this.channel) return ''
-
- return `${this.channel.name} ${this.name}`
- }
-
- getStreamId(): string {
- return `${this.channelId}@${this.id}`
- }
-
- getLogos(): Collection {
- function format(logo: Logo): number {
- const levelByFormat: Record = {
- SVG: 0,
- PNG: 3,
- APNG: 1,
- WebP: 1,
- AVIF: 1,
- JPEG: 2,
- GIF: 1
- }
-
- return logo.format ? levelByFormat[logo.format] : 0
- }
-
- function size(logo: Logo): number {
- return Math.abs(512 - logo.width) + Math.abs(512 - logo.height)
- }
-
- return this.logos.orderBy([format, size], ['desc', 'asc'], false)
- }
-
- getLogo(): Logo | undefined {
- return this.getLogos().first()
- }
-
- hasLogo(): boolean {
- return this.getLogos().notEmpty()
- }
-
- getLogoUrl(): string {
- const logo = this.getLogo()
- if (!logo) return ''
-
- return logo.url || ''
- }
-}
diff --git a/scripts/models/guide.ts b/scripts/models/guide.ts
index 4072c8bc..8c367e6e 100644
--- a/scripts/models/guide.ts
+++ b/scripts/models/guide.ts
@@ -1,35 +1,59 @@
-import { Collection, DateTime } from '@freearhey/core'
-import { generateXMLTV } from 'epg-grabber'
-
-interface GuideData {
- channels: Collection
- programs: Collection
- filepath: string
- gzip: boolean
-}
-
-export class Guide {
- channels: Collection
- programs: Collection
- filepath: string
- gzip: boolean
-
- constructor({ channels, programs, filepath, gzip }: GuideData) {
- this.channels = channels
- this.programs = programs
- this.filepath = filepath
- this.gzip = gzip || false
- }
-
- toString() {
- const currDate = new DateTime(process.env.CURR_DATE || new Date().toISOString(), {
- timezone: 'UTC'
- })
-
- return generateXMLTV({
- channels: this.channels.all(),
- programs: this.programs.all(),
- date: currDate.toJSON()
- })
- }
-}
+import { Collection, Logger } from '@freearhey/core'
+import { Storage } from '@freearhey/storage-js'
+import { EPGGrabber } from 'epg-grabber'
+import { Channel, Program } from '.'
+import utc from 'dayjs/plugin/utc'
+import dayjs from 'dayjs'
+import path from 'node:path'
+import pako from 'pako'
+
+dayjs.extend(utc)
+
+interface GuideData {
+ channels: Collection
+ programs: Collection
+ filepath: string
+ gzip: boolean
+}
+
+export class Guide {
+ channels: Collection
+ programs: Collection
+ filepath: string
+ gzip: boolean
+
+ constructor(data: GuideData) {
+ this.channels = data.channels
+ this.programs = data.programs
+ this.filepath = data.filepath
+ this.gzip = data.gzip || false
+ }
+
+ addChannel(channel: Channel) {
+ this.channels.add(channel)
+ }
+
+ toString() {
+ const currDate = dayjs.utc(process.env.CURR_DATE || new Date().toISOString())
+
+ return EPGGrabber.generateXMLTV(this.channels.all(), this.programs.all(), currDate)
+ }
+
+ async save({ logger }: { logger: Logger }) {
+ const dir = path.dirname(this.filepath)
+ const storage = new Storage(dir)
+ const xmlFilepath = this.filepath
+ const xmlFilename = path.basename(xmlFilepath)
+ logger.info(` saving to "${xmlFilepath}"...`)
+ const xmltv = this.toString()
+ await storage.save(xmlFilename, xmltv)
+
+ if (this.gzip) {
+ const compressed = pako.gzip(xmltv)
+ const gzFilepath = `${this.filepath}.gz`
+ const gzFilename = path.basename(gzFilepath)
+ logger.info(` saving to "${gzFilepath}"...`)
+ await storage.save(gzFilename, compressed)
+ }
+ }
+}
diff --git a/scripts/models/guideChannel.ts b/scripts/models/guideChannel.ts
deleted file mode 100644
index 4876a89d..00000000
--- a/scripts/models/guideChannel.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Dictionary } from '@freearhey/core'
-import epgGrabber from 'epg-grabber'
-import { Feed, Channel } from '.'
-
-export class GuideChannel {
- channelId?: string
- channel?: Channel
- feedId?: string
- feed?: Feed
- xmltvId?: string
- languageCode?: string
- siteId?: string
- logoUrl?: string
- siteDomain?: string
- siteName?: string
-
- constructor(data: epgGrabber.Channel) {
- const [channelId, feedId] = data.xmltv_id ? data.xmltv_id.split('@') : [undefined, undefined]
-
- this.channelId = channelId
- this.feedId = feedId
- this.xmltvId = data.xmltv_id
- this.languageCode = data.lang
- this.siteId = data.site_id
- this.logoUrl = data.logo
- this.siteDomain = data.site
- this.siteName = data.name
- }
-
- withChannel(channelsKeyById: Dictionary): this {
- if (this.channelId) this.channel = channelsKeyById.get(this.channelId)
-
- return this
- }
-
- withFeed(feedsKeyByStreamId: Dictionary): this {
- if (this.feedId) this.feed = feedsKeyByStreamId.get(this.getStreamId())
-
- return this
- }
-
- getStreamId(): string {
- if (!this.channelId) return ''
- if (!this.feedId) return this.channelId
-
- return `${this.channelId}@${this.feedId}`
- }
-
- toJSON() {
- return {
- channel: this.channelId || null,
- feed: this.feedId || null,
- site: this.siteDomain || '',
- site_id: this.siteId || '',
- site_name: this.siteName || '',
- lang: this.languageCode || ''
- }
- }
-}
diff --git a/scripts/models/index.ts b/scripts/models/index.ts
index b97d859c..a05f13a8 100644
--- a/scripts/models/index.ts
+++ b/scripts/models/index.ts
@@ -1,9 +1,5 @@
-export * from './channel'
-export * from './feed'
-export * from './guide'
-export * from './guideChannel'
-export * from './issue'
-export * from './logo'
-export * from './site'
-export * from './stream'
-export * from './channelList'
+export * from './guide'
+export * from './issue'
+export * from './site'
+export * from './channel'
+export * from './program'
diff --git a/scripts/models/issue.ts b/scripts/models/issue.ts
index a26e71ff..6710b148 100644
--- a/scripts/models/issue.ts
+++ b/scripts/models/issue.ts
@@ -1,24 +1,47 @@
-import { Dictionary } from '@freearhey/core'
-import { OWNER, REPO } from '../constants'
-
-interface 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 { EOL, OWNER, REPO } from '../constants'
+import { Dictionary } from '@freearhey/core'
+
+const FIELDS = new Dictionary({
+ Site: 'site'
+})
+
+interface IssueData {
+ number: number
+ body: string
+ labels: { name: string }[]
+}
+
+export class Issue {
+ number: number
+ labels: string[]
+ data: Dictionary
+
+ constructor(issue: IssueData) {
+ const fields = typeof issue.body === 'string' ? issue.body.split('###') : []
+
+ this.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(EOL)
+ _value = _value ? _value.trim() : ''
+
+ if (!_label || !_value) return
+
+ const id: string | undefined = FIELDS.get(_label)
+ const value: string = _value === '_No response_' || _value === 'None' ? '' : _value
+
+ if (!id) return
+
+ this.data.set(id, value)
+ })
+
+ this.labels = issue.labels.map(label => label.name)
+ this.number = issue.number
+ }
+
+ getURL() {
+ return `https://github.com/${OWNER}/${REPO}/issues/${this.number}`
+ }
+}
diff --git a/scripts/models/logo.ts b/scripts/models/logo.ts
deleted file mode 100644
index e08f443e..00000000
--- a/scripts/models/logo.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Collection, type Dictionary } from '@freearhey/core'
-import type { LogoData } from '../types/logo'
-import { type Feed } from './feed'
-
-export class Logo {
- channelId?: string
- feedId?: string
- feed?: Feed
- tags: Collection = new Collection()
- width = 0
- height = 0
- format?: string
- url?: string
-
- constructor(data?: LogoData) {
- if (!data) return
-
- this.channelId = data.channel
- this.feedId = data.feed || undefined
- this.tags = new Collection(data.tags)
- this.width = data.width
- this.height = data.height
- this.format = data.format || undefined
- this.url = data.url
- }
-
- withFeed(feedsKeyByStreamId: Dictionary): this {
- if (!this.feedId) return this
-
- this.feed = feedsKeyByStreamId.get(this.getStreamId())
-
- return this
- }
-
- getStreamId(): string {
- if (!this.channelId) return ''
- if (!this.feedId) return this.channelId
-
- return `${this.channelId}@${this.feedId}`
- }
-}
diff --git a/scripts/models/program.ts b/scripts/models/program.ts
new file mode 100644
index 00000000..11051607
--- /dev/null
+++ b/scripts/models/program.ts
@@ -0,0 +1,3 @@
+import * as epgGrabber from 'epg-grabber'
+
+export class Program extends epgGrabber.Program {}
diff --git a/scripts/models/site.ts b/scripts/models/site.ts
index d4ddfdaa..27d9d1ef 100644
--- a/scripts/models/site.ts
+++ b/scripts/models/site.ts
@@ -1,63 +1,63 @@
-import { Collection } from '@freearhey/core'
-import { Issue } from './'
-
-enum StatusCode {
- DOWN = 'down',
- WARNING = 'warning',
- OK = 'ok'
-}
-
-interface Status {
- code: StatusCode
- emoji: string
-}
-
-interface SiteProps {
- domain: string
- totalChannels?: number
- markedChannels?: number
- issues: Collection
-}
-
-export class Site {
- domain: string
- totalChannels: number
- markedChannels: number
- issues: Collection
-
- constructor({ domain, totalChannels = 0, markedChannels = 0, issues }: SiteProps) {
- this.domain = domain
- this.totalChannels = totalChannels
- this.markedChannels = markedChannels
- 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'
+}
+
+export interface Status {
+ code: StatusCode
+ emoji: string
+}
+
+export interface SiteData {
+ domain: string
+ totalChannels?: number
+ markedChannels?: number
+ issues: Collection
+}
+
+export class Site {
+ domain: string
+ totalChannels: number
+ markedChannels: number
+ issues: Collection
+
+ constructor(data: SiteData) {
+ this.domain = data.domain
+ this.totalChannels = data.totalChannels || 0
+ this.markedChannels = data.markedChannels || 0
+ this.issues = data.issues
+ }
+
+ getStatus(): Status {
+ const issuesWithStatusDown = this.issues.filter((issue: Issue) =>
+ issue.labels.find(label => label === 'status:down')
+ )
+ if (issuesWithStatusDown.isNotEmpty())
+ return {
+ code: StatusCode.DOWN,
+ emoji: '🔴'
+ }
+
+ const issuesWithStatusWarning = this.issues.filter((issue: Issue) =>
+ issue.labels.find(label => label === 'status:warning')
+ )
+ if (issuesWithStatusWarning.isNotEmpty())
+ return {
+ code: StatusCode.WARNING,
+ emoji: '🟡'
+ }
+
+ return {
+ code: StatusCode.OK,
+ emoji: '🟢'
+ }
+ }
+
+ getIssueUrls(): Collection {
+ return this.issues.map((issue: Issue) => issue.getURL())
+ }
+}
diff --git a/scripts/models/stream.ts b/scripts/models/stream.ts
deleted file mode 100644
index c519bdfb..00000000
--- a/scripts/models/stream.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import type { StreamData } from '../types/stream'
-import { Feed, Channel } from './index'
-
-export class Stream {
- name?: string
- url: string
- id?: string
- channelId?: string
- channel?: Channel
- feedId?: string
- feed?: Feed
- filepath?: string
- line?: number
- label?: string
- verticalResolution?: number
- isInterlaced?: boolean
- referrer?: string
- userAgent?: string
- groupTitle = 'Undefined'
- removed = false
-
- constructor(data: StreamData) {
- const id = data.channel && data.feed ? [data.channel, data.feed].join('@') : data.channel
- const { verticalResolution, isInterlaced } = parseQuality(data.quality)
-
- this.id = id || undefined
- this.channelId = data.channel || undefined
- this.feedId = data.feed || undefined
- this.name = data.name || undefined
- this.url = data.url
- this.referrer = data.referrer || undefined
- this.userAgent = data.user_agent || undefined
- this.verticalResolution = verticalResolution || undefined
- this.isInterlaced = isInterlaced || undefined
- this.label = data.label || undefined
- }
-
- getId(): string {
- return this.id || ''
- }
-
- getName(): string {
- return this.name || ''
- }
-}
-
-function parseQuality(quality: string | null): {
- verticalResolution: number | null
- isInterlaced: boolean | null
-} {
- if (!quality) return { verticalResolution: null, isInterlaced: null }
- const [, verticalResolutionString] = quality.match(/^(\d+)/) || [null, undefined]
- const isInterlaced = /i$/i.test(quality)
- let verticalResolution = 0
- if (verticalResolutionString) verticalResolution = parseInt(verticalResolutionString)
-
- return { verticalResolution, isInterlaced }
-}
diff --git a/scripts/templates/_config.js b/scripts/templates/_config.js
index b4eb9b46..2e40921d 100644
--- a/scripts/templates/_config.js
+++ b/scripts/templates/_config.js
@@ -1,16 +1,16 @@
-module.exports = {
- site: '',
- url({ channel, date }) {
- return `https://example.com/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
- },
- parser({ content }) {
- try {
- return JSON.parse(content)
- } catch {
- return []
- }
- },
- channels() {
- return []
- }
-}
+module.exports = {
+ site: '',
+ url({ channel, date }) {
+ return `https://example.com/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
+ },
+ parser({ content }) {
+ try {
+ return JSON.parse(content)
+ } catch {
+ return []
+ }
+ },
+ channels() {
+ return []
+ }
+}
diff --git a/scripts/templates/_readme.md b/scripts/templates/_readme.md
index 0b807f7f..4aa94527 100644
--- a/scripts/templates/_readme.md
+++ b/scripts/templates/_readme.md
@@ -1,21 +1,21 @@
-#
-
-https://
-
-### Download the guide
-
-```sh
-npm run grab --- --site=
-```
-
-### Update channel list
-
-```sh
-npm run channels:parse --- --config=./sites//.config.js --output=./sites//.channels.xml
-```
-
-### Test
-
-```sh
-npm test ---
-```
+#
+
+https://
+
+### Download the guide
+
+```sh
+npm run grab --- --site=
+```
+
+### Update channel list
+
+```sh
+npm run channels:parse --- --config=./sites//.config.js --output=./sites//.channels.xml
+```
+
+### Test
+
+```sh
+npm test ---
+```
diff --git a/scripts/templates/_sites.md b/scripts/templates/_sites.md
index d0633a4c..46191a4e 100644
--- a/scripts/templates/_sites.md
+++ b/scripts/templates/_sites.md
@@ -1,3 +1,3 @@
-# Sites
-
-_TABLE_
+# Sites
+
+_TABLE_
diff --git a/scripts/templates/_test.js b/scripts/templates/_test.js
index b02a2648..6375d7e7 100644
--- a/scripts/templates/_test.js
+++ b/scripts/templates/_test.js
@@ -1,38 +1,38 @@
-const { parser, url } = require('./.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('2025-01-12', 'YYYY-MM-DD').startOf('d')
-const channel = { site_id: 'bbc1' }
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe('https://example.com/api/bbc1/2025-01-12')
-})
-
-it('can parse response', () => {
- const content =
- '[{"title":"Program 1","start":"2025-01-12T00:00:00.000Z","stop":"2025-01-12T00:30:00.000Z"},{"title":"Program 2","start":"2025-01-12T00:30:00.000Z","stop":"2025-01-12T01:00:00.000Z"}]'
-
- const results = parser({ content })
-
- expect(results.length).toBe(2)
- expect(results[0]).toMatchObject({
- title: 'Program 1',
- start: '2025-01-12T00:00:00.000Z',
- stop: '2025-01-12T00:30:00.000Z'
- })
- expect(results[1]).toMatchObject({
- title: 'Program 2',
- start: '2025-01-12T00:30:00.000Z',
- stop: '2025-01-12T01:00:00.000Z'
- })
-})
-
-it('can handle empty guide', () => {
- const results = parser({ content: '' })
-
- expect(results).toMatchObject([])
-})
+const { parser, url } = require('./.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('2025-01-12', 'YYYY-MM-DD').startOf('d')
+const channel = { site_id: 'bbc1' }
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe('https://example.com/api/bbc1/2025-01-12')
+})
+
+it('can parse response', () => {
+ const content =
+ '[{"title":"Program 1","start":"2025-01-12T00:00:00.000Z","stop":"2025-01-12T00:30:00.000Z"},{"title":"Program 2","start":"2025-01-12T00:30:00.000Z","stop":"2025-01-12T01:00:00.000Z"}]'
+
+ const results = parser({ content })
+
+ expect(results.length).toBe(2)
+ expect(results[0]).toMatchObject({
+ title: 'Program 1',
+ start: '2025-01-12T00:00:00.000Z',
+ stop: '2025-01-12T00:30:00.000Z'
+ })
+ expect(results[1]).toMatchObject({
+ title: 'Program 2',
+ start: '2025-01-12T00:30:00.000Z',
+ stop: '2025-01-12T01:00:00.000Z'
+ })
+})
+
+it('can handle empty guide', () => {
+ const results = parser({ content: '' })
+
+ expect(results).toMatchObject([])
+})
diff --git a/scripts/types/channel.d.ts b/scripts/types/channel.d.ts
index b2c709e1..3bd35d6f 100644
--- a/scripts/types/channel.d.ts
+++ b/scripts/types/channel.d.ts
@@ -1,27 +1,8 @@
-import { Collection } from '@freearhey/core'
-
-export interface ChannelData {
- id: string
- name: string
- alt_names: string[]
- network: string
- owners: Collection
- country: string
- subdivision: string
- city: string
- categories: Collection
- is_nsfw: boolean
- launched: string
- closed: string
- replaced_by: string
- website: string
-}
-
-export interface ChannelSearchableData {
- id: string
- name: string
- altNames: string[]
- guideNames: string[]
- streamNames: string[]
- feedFullNames: string[]
-}
+export interface ChannelGuideObject {
+ channel: string | null
+ feed: string | null
+ site: string
+ site_id: string
+ site_name: string
+ lang: string
+}
diff --git a/scripts/types/dataLoader.d.ts b/scripts/types/dataLoader.d.ts
deleted file mode 100644
index 98d3d911..00000000
--- a/scripts/types/dataLoader.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Storage } from '@freearhey/core'
-
-export interface DataLoaderProps {
- storage: Storage
-}
-
-export interface DataLoaderData {
- countries: object | object[]
- regions: object | object[]
- subdivisions: object | object[]
- languages: object | object[]
- categories: object | object[]
- blocklist: object | object[]
- channels: object | object[]
- feeds: object | object[]
- timezones: object | object[]
- guides: object | object[]
- streams: object | object[]
- logos: object | object[]
-}
diff --git a/scripts/types/dataProcessor.d.ts b/scripts/types/dataProcessor.d.ts
deleted file mode 100644
index e50915d1..00000000
--- a/scripts/types/dataProcessor.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Collection, Dictionary } from '@freearhey/core'
-
-export interface DataProcessorData {
- guideChannelsGroupedByStreamId: Dictionary
- feedsGroupedByChannelId: Dictionary
- logosGroupedByChannelId: Dictionary
- logosGroupedByStreamId: Dictionary
- feedsKeyByStreamId: Dictionary
- streamsGroupedById: Dictionary
- channelsKeyById: Dictionary
- guideChannels: Collection
- channels: Collection
- streams: Collection
- feeds: Collection
- logos: Collection
-}
diff --git a/scripts/types/feed.d.ts b/scripts/types/feed.d.ts
deleted file mode 100644
index 00c49260..00000000
--- a/scripts/types/feed.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Collection } from '@freearhey/core'
-
-export interface FeedData {
- channel: string
- id: string
- name: string
- is_main: boolean
- broadcast_area: Collection
- languages: Collection
- timezones: Collection
- video_format: string
-}
diff --git a/scripts/types/guide.d.ts b/scripts/types/guide.d.ts
deleted file mode 100644
index 9fbe4da3..00000000
--- a/scripts/types/guide.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export interface GuideData {
- channel: string
- feed: string
- site: string
- site_id: string
- site_name: string
- lang: string
-}
diff --git a/scripts/types/htmlTable.d.ts b/scripts/types/htmlTable.d.ts
new file mode 100644
index 00000000..2dc9a0a0
--- /dev/null
+++ b/scripts/types/htmlTable.d.ts
@@ -0,0 +1,17 @@
+import { Collection } from '@freearhey/core'
+
+export interface HTMLTableColumn {
+ name: string
+ nowrap?: boolean
+ align?: string
+ colspan?: number
+}
+
+export interface HTMLTableDataItem {
+ value: string
+ nowrap?: boolean
+ align?: string
+ colspan?: number
+}
+
+export type HTMLTableRow = Collection
diff --git a/scripts/types/langs.d.ts b/scripts/types/langs.d.ts
index 60fb498a..74921c68 100644
--- a/scripts/types/langs.d.ts
+++ b/scripts/types/langs.d.ts
@@ -1 +1 @@
-declare module 'langs'
+declare module 'langs'
diff --git a/scripts/types/logo.d.ts b/scripts/types/logo.d.ts
deleted file mode 100644
index d8c54b04..00000000
--- a/scripts/types/logo.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export interface LogoData {
- channel: string
- feed: string | null
- tags: string[]
- width: number
- height: number
- format: string | null
- url: string
-}
diff --git a/scripts/types/queue.d.ts b/scripts/types/queue.d.ts
new file mode 100644
index 00000000..26615c15
--- /dev/null
+++ b/scripts/types/queue.d.ts
@@ -0,0 +1,10 @@
+import { SiteConfig } from '../core/siteConfig'
+import { Channel } from '../models/channel'
+import { Dayjs } from 'dayjs'
+
+export interface QueueItem {
+ channel: Channel
+ date: Dayjs
+ siteConfig: SiteConfig
+ error: string | null
+}
diff --git a/scripts/types/stream.d.ts b/scripts/types/stream.d.ts
deleted file mode 100644
index c3365889..00000000
--- a/scripts/types/stream.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export interface StreamData {
- channel: string | null
- feed: string | null
- name?: string
- url: string
- referrer: string | null
- user_agent: string | null
- quality: string | null
- label: string | null
-}
diff --git a/tests/__data__/expected/channels_format/example.com.channels.xml b/tests/__data__/expected/channels_format/example.com.channels.xml
new file mode 100644
index 00000000..398df20e
--- /dev/null
+++ b/tests/__data__/expected/channels_format/example.com.channels.xml
@@ -0,0 +1,5 @@
+
+
+ CNN International
+ BBC World News
+
diff --git a/tests/__data__/expected/channels_parse/example.com.channels.xml b/tests/__data__/expected/channels_parse/example.com.channels.xml
index 71622a50..66ea7de5 100644
--- a/tests/__data__/expected/channels_parse/example.com.channels.xml
+++ b/tests/__data__/expected/channels_parse/example.com.channels.xml
@@ -1,5 +1,5 @@
-
-
- BBC World News
- CNN International
-
+
+
+ BBC World News
+ CNN International
+
diff --git a/tests/__data__/expected/epg_grab/base.guide.xml b/tests/__data__/expected/epg_grab/base.guide.xml
index 0f9c2ca0..a0ed3732 100644
--- a/tests/__data__/expected/epg_grab/base.guide.xml
+++ b/tests/__data__/expected/epg_grab/base.guide.xml
@@ -1,9 +1,12 @@
-
-Channel 2https://example.com36
-Channel 1https://example.com
-Channel 1https://example.com
-Programme1 (example.com)
-Program1 (example.com)
-Programme1 (example.com)
-Program1 (example.com)
+
+Channel 1https://example.com
+Channel 2https://example.com36
+Channel 1https://example.com
+Channel 3https://example.com
+Programme1 (example.com)
+Programme1 (example.com)
+Program1 (example.com)
+Program1 (example.com)
+Program1 (example.com)
+Program1 (example.com)
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/custom_channels.guide.xml b/tests/__data__/expected/epg_grab/custom_channels.guide.xml
index dd84f7dc..932a9e6a 100644
--- a/tests/__data__/expected/epg_grab/custom_channels.guide.xml
+++ b/tests/__data__/expected/epg_grab/custom_channels.guide.xml
@@ -1,15 +1,15 @@
-
-Custom Channel 1https://example.com
-Custom Channel 2https://example.com
-Channel 1https://example.com
-Channel 3https://example2.com
-Channel 4https://example2.com
-Channel 1https://example2.com
-Programme1 (example.com)
-Program1 (example.com)
-Programme1 (example2.com)
-Programme1 (example.com)
-Program1 (example.com)
-Program1 (example2.com)
-Program1 (example2.com)
+
+Custom Channel 1https://example.com
+Custom Channel 2https://example.com
+Channel 1https://example.com
+Channel 3https://example2.com
+Channel 4https://example2.com
+Channel 1https://example2.com
+Programme1 (example.com)
+Program1 (example.com)
+Programme1 (example2.com)
+Programme1 (example.com)
+Program1 (example.com)
+Program1 (example2.com)
+Program1 (example2.com)
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/guides/en/example.com.xml b/tests/__data__/expected/epg_grab/guides/en/example.com.xml
deleted file mode 100644
index 8b20e42a..00000000
--- a/tests/__data__/expected/epg_grab/guides/en/example.com.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-Channel 2https://example.com36
-Channel 1https://example.com
-Program1 (example.com)
-Program1 (example.com)
-
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/guides/fr/example.com.xml b/tests/__data__/expected/epg_grab/guides/fr/example.com.xml
deleted file mode 100644
index 09dc5a3c..00000000
--- a/tests/__data__/expected/epg_grab/guides/fr/example.com.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Channel 1https://example.com
-Programme1 (example.com)
-Programme1 (example.com)
-
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/gzip.guide.xml b/tests/__data__/expected/epg_grab/gzip.guide.xml
new file mode 100644
index 00000000..67968c1b
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/gzip.guide.xml
@@ -0,0 +1,8 @@
+
+Channel 3https://example2.com
+Channel 4https://example2.com
+Channel 1https://example2.com
+Programme1 (example2.com)
+Program1 (example2.com)
+Program1 (example2.com)
+
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/gzip.guide.xml.gz b/tests/__data__/expected/epg_grab/gzip.guide.xml.gz
new file mode 100644
index 00000000..ccce7906
Binary files /dev/null and b/tests/__data__/expected/epg_grab/gzip.guide.xml.gz differ
diff --git a/tests/__data__/expected/epg_grab/lang/fr/guide.xml b/tests/__data__/expected/epg_grab/lang/fr/guide.xml
new file mode 100644
index 00000000..dde894e5
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/lang/fr/guide.xml
@@ -0,0 +1,5 @@
+
+Channel 1https://example.com
+Programme1 (example.com)
+Programme1 (example.com)
+
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/lang.guide.xml b/tests/__data__/expected/epg_grab/multilang.guide.xml
similarity index 57%
rename from tests/__data__/expected/epg_grab/lang.guide.xml
rename to tests/__data__/expected/epg_grab/multilang.guide.xml
index 7016b8e8..40e5b5aa 100644
--- a/tests/__data__/expected/epg_grab/lang.guide.xml
+++ b/tests/__data__/expected/epg_grab/multilang.guide.xml
@@ -1,8 +1,8 @@
-
-Channel 1https://example.com
-Channel 3https://example.com
-Programme1 (example.com)
-Programme1 (example.com)
-Program1 (example.com)
-Program1 (example.com)
+
+Channel 1https://example.com
+Channel 3https://example.com
+Programme1 (example.com)
+Programme1 (example.com)
+Program1 (example.com)
+Program1 (example.com)
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/multiple_channels.guide.xml b/tests/__data__/expected/epg_grab/multiple_channels.guide.xml
new file mode 100644
index 00000000..489914a7
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/multiple_channels.guide.xml
@@ -0,0 +1,18 @@
+
+Channel 1https://example.com
+Channel 2https://example.com36
+Channel 1https://example.com
+Channel 3https://example.com
+Channel 3https://example2.com
+Channel 4https://example2.com
+Channel 1https://example2.com
+Programme1 (example.com)
+Programme1 (example.com)
+Programme1 (example2.com)
+Program1 (example.com)
+Program1 (example.com)
+Program1 (example2.com)
+Program1 (example.com)
+Program1 (example.com)
+Program1 (example2.com)
+
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/proxy.guide.xml b/tests/__data__/expected/epg_grab/proxy.guide.xml
deleted file mode 100644
index 0f9c2ca0..00000000
--- a/tests/__data__/expected/epg_grab/proxy.guide.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-Channel 2https://example.com36
-Channel 1https://example.com
-Channel 1https://example.com
-Programme1 (example.com)
-Program1 (example.com)
-Programme1 (example.com)
-Program1 (example.com)
-
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/template.guide.xml b/tests/__data__/expected/epg_grab/template.guide.xml
deleted file mode 100644
index 8eb79411..00000000
--- a/tests/__data__/expected/epg_grab/template.guide.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-Channel 2https://example.com36
-Channel 1https://example.com
-Channel 1https://example.com
-Channel 3https://example2.com
-Channel 4https://example2.com
-Channel 1https://example2.com
-Programme1 (example.com)
-Program1 (example.com)
-Programme1 (example2.com)
-Programme1 (example.com)
-Program1 (example.com)
-Program1 (example2.com)
-Program1 (example2.com)
-
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/template.guide.xml.gz b/tests/__data__/expected/epg_grab/template.guide.xml.gz
deleted file mode 100644
index 126b426d..00000000
Binary files a/tests/__data__/expected/epg_grab/template.guide.xml.gz and /dev/null differ
diff --git a/tests/__data__/expected/epg_grab/wildcard/example.com/en/guide.xml b/tests/__data__/expected/epg_grab/wildcard/example.com/en/guide.xml
new file mode 100644
index 00000000..6426626a
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/wildcard/example.com/en/guide.xml
@@ -0,0 +1,6 @@
+
+Channel 1https://example.com
+Channel 2https://example.com36
+Program1 (example.com)
+Program1 (example.com)
+
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/wildcard/example.com/fr/guide.xml b/tests/__data__/expected/epg_grab/wildcard/example.com/fr/guide.xml
new file mode 100644
index 00000000..dde894e5
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/wildcard/example.com/fr/guide.xml
@@ -0,0 +1,5 @@
+
+Channel 1https://example.com
+Programme1 (example.com)
+Programme1 (example.com)
+
\ No newline at end of file
diff --git a/tests/__data__/expected/epg_grab/wildcard/example.com/it/guide.xml b/tests/__data__/expected/epg_grab/wildcard/example.com/it/guide.xml
new file mode 100644
index 00000000..9d839e5e
--- /dev/null
+++ b/tests/__data__/expected/epg_grab/wildcard/example.com/it/guide.xml
@@ -0,0 +1,5 @@
+
+Channel 3https://example.com
+Program1 (example.com)
+Program1 (example.com)
+
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/channels.json b/tests/__data__/input/__data__/channels.json
deleted file mode 100644
index d2e6a4d5..00000000
--- a/tests/__data__/input/__data__/channels.json
+++ /dev/null
@@ -1,61 +0,0 @@
-[
- {
- "id": "Bravo.us",
- "name": "Bravo",
- "network": null,
- "country": "US",
- "subdivision": null,
- "city": null,
- "categories": [],
- "is_nsfw": false,
- "closed": "2020-01-01",
- "replaced_by": "R6.co"
- },
- {
- "id": "Bravos.us",
- "name": "Bravos",
- "network": null,
- "country": "US",
- "subdivision": null,
- "city": null,
- "categories": [],
- "is_nsfw": false
- },
- {
- "id": "CNNInternational.us",
- "name": "CNN International",
- "alt_names": ["CNN", "CNN Int"],
- "network": null,
- "country": "US",
- "subdivision": null,
- "city": null,
- "categories": [
- "news"
- ],
- "is_nsfw": false
- },
- {
- "id": "MNetMovies2.za",
- "name": "M-Net Movies 2",
- "network": null,
- "country": "ZA",
- "subdivision": null,
- "city": null,
- "categories": [],
- "is_nsfw": false
- },
- {"id":"6eren.dk","name":"6'eren","alt_names":[],"network":null,"owners":["Warner Bros. Discovery EMEA"],"country":"DK","subdivision":null,"city":null,"broadcast_area":["c/DK"],"languages":["dan"],"categories":[],"is_nsfw":false,"launched":"2009-01-01","closed":null,"replaced_by":null,"website":"http://www.6-eren.dk/"},
- {"id":"BBCNews.uk","name":"BBC News","alt_names":[],"network":null,"owners":[],"country":"UK","subdivision":null,"city":null,"broadcast_area":["c/UK"],"languages":["eng"],"categories":["news"],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":"http://news.bbc.co.uk/"},
- {
- "id": "CNN.us",
- "name": "CNN",
- "network": null,
- "country": "US",
- "subdivision": null,
- "city": null,
- "categories": [],
- "is_nsfw": false
- },
- {"id":"Channel2.us","name":"Channel 2 [API]","alt_names":[],"network":null,"owners":[],"country":"UK","subdivision":null,"city":null,"broadcast_area":["c/US"],"languages":["eng"],"categories":[],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":""},
- {"id":"Channel3.us","name":"Channel 3 [API]","alt_names":[],"network":null,"owners":[],"country":"UK","subdivision":null,"city":null,"broadcast_area":["c/US"],"languages":["eng"],"categories":[],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":""}
-]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/logos.json b/tests/__data__/input/__data__/logos.json
deleted file mode 100644
index 4aa0a9a9..00000000
--- a/tests/__data__/input/__data__/logos.json
+++ /dev/null
@@ -1,4 +0,0 @@
-[
- {"channel":"Channel3.us","feed":null,"tags":[],"width":334,"height":210,"format":"PNG","url":"https://upload.wikimedia.org/wikipedia/commons/6/64/6%27eren_2015.png"},
- {"channel":"Channel4.us","feed":"HD","tags":[],"width":334,"height":210,"format":"PNG","url":"https://i.imgur.com/BPzH88J.png"}
-]
\ No newline at end of file
diff --git a/tests/__data__/input/channels_format/example.com.channels.xml b/tests/__data__/input/channels_format/example.com.channels.xml
new file mode 100644
index 00000000..cbe336df
--- /dev/null
+++ b/tests/__data__/input/channels_format/example.com.channels.xml
@@ -0,0 +1,5 @@
+
+
+ BBC World News
+ CNN International
+
diff --git a/tests/__data__/input/__data__/blocklist.json b/tests/__data__/input/data/blocklist.json
similarity index 100%
rename from tests/__data__/input/__data__/blocklist.json
rename to tests/__data__/input/data/blocklist.json
diff --git a/tests/__data__/input/__data__/categories.json b/tests/__data__/input/data/categories.json
similarity index 100%
rename from tests/__data__/input/__data__/categories.json
rename to tests/__data__/input/data/categories.json
diff --git a/tests/__data__/input/data/channels.json b/tests/__data__/input/data/channels.json
new file mode 100644
index 00000000..269920f6
--- /dev/null
+++ b/tests/__data__/input/data/channels.json
@@ -0,0 +1,138 @@
+[
+ {
+ "id": "Bravo.us",
+ "name": "Bravo",
+ "network": null,
+ "country": "US",
+ "categories": [],
+ "is_nsfw": false,
+ "closed": "2020-01-01",
+ "replaced_by": "R6.co"
+ },
+ {
+ "id": "Bravos.us",
+ "name": "Bravos",
+ "network": null,
+ "country": "US",
+ "categories": [],
+ "is_nsfw": false
+ },
+ {
+ "id": "CNNInternational.us",
+ "name": "CNN International",
+ "alt_names": [
+ "CNN",
+ "CNN Int"
+ ],
+ "network": null,
+ "country": "US",
+ "categories": [
+ "news"
+ ],
+ "is_nsfw": false
+ },
+ {
+ "id": "MNetMovies2.za",
+ "name": "M-Net Movies 2",
+ "network": null,
+ "country": "ZA",
+ "categories": [],
+ "is_nsfw": false
+ },
+ {
+ "id": "6eren.dk",
+ "name": "6'eren",
+ "alt_names": [],
+ "network": null,
+ "owners": [
+ "Warner Bros. Discovery EMEA"
+ ],
+ "country": "DK",
+ "categories": [],
+ "is_nsfw": false,
+ "launched": "2009-01-01",
+ "closed": null,
+ "replaced_by": null,
+ "website": "http://www.6-eren.dk/"
+ },
+ {
+ "id": "BBCNews.uk",
+ "name": "BBC News",
+ "alt_names": [],
+ "network": null,
+ "owners": [],
+ "country": "UK",
+ "categories": [
+ "news"
+ ],
+ "is_nsfw": false,
+ "launched": null,
+ "closed": null,
+ "replaced_by": null,
+ "website": "http://news.bbc.co.uk/"
+ },
+ {
+ "id": "CNN.us",
+ "name": "CNN",
+ "network": null,
+ "country": "US",
+ "categories": [],
+ "is_nsfw": false
+ },
+ {
+ "id": "Channel1.us",
+ "name": "Channel 1",
+ "alt_names": [],
+ "network": null,
+ "owners": [],
+ "country": "US",
+ "categories": [],
+ "is_nsfw": false,
+ "launched": null,
+ "closed": null,
+ "replaced_by": null,
+ "website": ""
+ },
+ {
+ "id": "Channel2.us",
+ "name": "Channel 2",
+ "alt_names": [],
+ "network": null,
+ "owners": [],
+ "country": "UK",
+ "categories": [],
+ "is_nsfw": false,
+ "launched": null,
+ "closed": null,
+ "replaced_by": null,
+ "website": ""
+ },
+ {
+ "id": "Channel3.us",
+ "name": "Channel 3",
+ "alt_names": [],
+ "network": null,
+ "owners": [],
+ "country": "UK",
+ "categories": [],
+ "is_nsfw": false,
+ "launched": null,
+ "closed": null,
+ "replaced_by": null,
+ "website": ""
+ },
+ {
+ "id": "Channel4.us",
+ "name": "Channel 4",
+ "alt_names": [],
+ "network": null,
+ "owners": [],
+ "country": "UK",
+ "categories": [],
+ "is_nsfw": false,
+ "launched": null,
+ "closed": null,
+ "replaced_by": null,
+ "website": ""
+ }
+]
\ No newline at end of file
diff --git a/tests/__data__/input/data/cities.json b/tests/__data__/input/data/cities.json
new file mode 100644
index 00000000..0637a088
--- /dev/null
+++ b/tests/__data__/input/data/cities.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/countries.json b/tests/__data__/input/data/countries.json
similarity index 100%
rename from tests/__data__/input/__data__/countries.json
rename to tests/__data__/input/data/countries.json
diff --git a/tests/__data__/input/__data__/feeds.json b/tests/__data__/input/data/feeds.json
similarity index 75%
rename from tests/__data__/input/__data__/feeds.json
rename to tests/__data__/input/data/feeds.json
index 875f7723..cf0e5e34 100644
--- a/tests/__data__/input/__data__/feeds.json
+++ b/tests/__data__/input/data/feeds.json
@@ -1,58 +1,72 @@
-[
- {
- "channel": "CNNInternational.us",
- "id": "SD",
- "name": "SD",
- "is_main": true,
- "broadcast_area": [
- "r/INT"
- ],
- "timezones": [
- "America/New_York"
- ],
- "languages": [],
- "video_format": "480i"
- },
- {
- "channel": "CNNInternational.us",
- "id": "Europe",
- "name": "Europe",
- "is_main": false,
- "broadcast_area": [
- "r/EUR"
- ],
- "timezones": [
- "America/New_York"
- ],
- "languages": [],
- "video_format": "480i"
- },
- {
- "channel": "Bravo.us",
- "id": "East",
- "name": "East",
- "is_main": true,
- "broadcast_area": [
- "r/EUR"
- ],
- "timezones": [
- "America/New_York"
- ],
- "languages": [],
- "video_format": "480i"
- },
- {
- "channel": "Channel4.us",
- "id": "HD",
- "name": "HD",
- "is_main": true,
- "broadcast_area": [
- "r/EUR"
- ],
- "timezones": [
- "America/New_York"
- ],
- "languages": [],
- "video_format": "480i"
- }
+[
+ {
+ "channel": "CNNInternational.us",
+ "id": "SD",
+ "name": "SD",
+ "is_main": true,
+ "broadcast_area": [
+ "r/INT"
+ ],
+ "timezones": [
+ "America/New_York"
+ ],
+ "languages": [],
+ "video_format": "480i"
+ },
+ {
+ "channel": "CNNInternational.us",
+ "id": "Europe",
+ "name": "Europe",
+ "is_main": false,
+ "broadcast_area": [
+ "r/EUR"
+ ],
+ "timezones": [
+ "America/New_York"
+ ],
+ "languages": [],
+ "video_format": "480i"
+ },
+ {
+ "channel": "Bravo.us",
+ "id": "East",
+ "name": "East",
+ "is_main": true,
+ "broadcast_area": [
+ "r/EUR"
+ ],
+ "timezones": [
+ "America/New_York"
+ ],
+ "languages": [],
+ "video_format": "480i"
+ },
+ {
+ "channel": "Channel1.us",
+ "id": "HD",
+ "name": "HD",
+ "is_main": false,
+ "broadcast_area": [
+ "r/EUR"
+ ],
+ "timezones": [
+ "America/New_York"
+ ],
+ "languages": [],
+ "video_format": "480i"
+ },
+ {
+ "channel": "Channel4.us",
+ "id": "HD",
+ "name": "HD",
+ "is_main": true,
+ "broadcast_area": [
+ "r/EUR"
+ ],
+ "timezones": [
+ "America/New_York"
+ ],
+ "languages": [],
+ "video_format": "480i"
+ }
]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/guides.json b/tests/__data__/input/data/guides.json
similarity index 94%
rename from tests/__data__/input/__data__/guides.json
rename to tests/__data__/input/data/guides.json
index fd21fb22..e0470ab3 100644
--- a/tests/__data__/input/__data__/guides.json
+++ b/tests/__data__/input/data/guides.json
@@ -1,10 +1,10 @@
-[
- {
- "channel": "CNNInternational.us",
- "feed": "SD",
- "site": "9tv.co.il",
- "site_id": "#",
- "site_name": "CNN (guide)",
- "lang": "en"
- }
+[
+ {
+ "channel": "CNNInternational.us",
+ "feed": "SD",
+ "site": "9tv.co.il",
+ "site_id": "#",
+ "site_name": "CNN (guide)",
+ "lang": "en"
+ }
]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/languages.json b/tests/__data__/input/data/languages.json
similarity index 100%
rename from tests/__data__/input/__data__/languages.json
rename to tests/__data__/input/data/languages.json
diff --git a/tests/__data__/input/data/logos.json b/tests/__data__/input/data/logos.json
new file mode 100644
index 00000000..a868b1de
--- /dev/null
+++ b/tests/__data__/input/data/logos.json
@@ -0,0 +1,29 @@
+[
+ {
+ "channel": "Channel3.us",
+ "feed": null,
+ "tags": [],
+ "width": 334,
+ "height": 210,
+ "format": "PNG",
+ "url": "https://upload.wikimedia.org/wikipedia/commons/6/64/6%27eren_2015.png"
+ },
+ {
+ "channel": "Channel4.us",
+ "feed": "HD",
+ "tags": [],
+ "width": 334,
+ "height": 210,
+ "format": "PNG",
+ "url": "https://i.imgur.com/BPzH88J.png"
+ },
+ {
+ "channel": "Channel1.us",
+ "feed": null,
+ "tags": [],
+ "width": 334,
+ "height": 210,
+ "format": "PNG",
+ "url": "https://i.imgur.com/GPzH88J.png"
+ }
+]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/regions.json b/tests/__data__/input/data/regions.json
similarity index 100%
rename from tests/__data__/input/__data__/regions.json
rename to tests/__data__/input/data/regions.json
diff --git a/tests/__data__/input/__data__/streams.json b/tests/__data__/input/data/streams.json
similarity index 96%
rename from tests/__data__/input/__data__/streams.json
rename to tests/__data__/input/data/streams.json
index ce52ae7c..9410f1b2 100644
--- a/tests/__data__/input/__data__/streams.json
+++ b/tests/__data__/input/data/streams.json
@@ -1,10 +1,10 @@
-[
- {
- "channel": "CNNInternational.us",
- "feed": "SD",
- "url": "https://live.relentlessinnovations.net:1936/imantv/imantv/playlist.m3u8",
- "referrer": null,
- "user_agent": null,
- "quality": "480p"
- }
+[
+ {
+ "channel": "CNNInternational.us",
+ "feed": "SD",
+ "url": "https://live.relentlessinnovations.net:1936/imantv/imantv/playlist.m3u8",
+ "referrer": null,
+ "user_agent": null,
+ "quality": "480p"
+ }
]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/subdivisions.json b/tests/__data__/input/data/subdivisions.json
similarity index 93%
rename from tests/__data__/input/__data__/subdivisions.json
rename to tests/__data__/input/data/subdivisions.json
index 88a6d1bd..dea26f94 100644
--- a/tests/__data__/input/__data__/subdivisions.json
+++ b/tests/__data__/input/data/subdivisions.json
@@ -1,352 +1,352 @@
-[
- {
- "country": "CA",
- "name": "Alberta",
- "code": "CA-AB"
- },
- {
- "country": "CA",
- "name": "British Columbia",
- "code": "CA-BC"
- },
- {
- "country": "CA",
- "name": "Manitoba",
- "code": "CA-MB"
- },
- {
- "country": "CA",
- "name": "New Brunswick",
- "code": "CA-NB"
- },
- {
- "country": "CA",
- "name": "Newfoundland and Labrador",
- "code": "CA-NL"
- },
- {
- "country": "CA",
- "name": "Northwest Territories",
- "code": "CA-NT"
- },
- {
- "country": "CA",
- "name": "Nova Scotia",
- "code": "CA-NS"
- },
- {
- "country": "CA",
- "name": "Nunavut",
- "code": "CA-NU"
- },
- {
- "country": "CA",
- "name": "Ontario",
- "code": "CA-ON"
- },
- {
- "country": "CA",
- "name": "Prince Edward Island",
- "code": "CA-PE"
- },
- {
- "country": "CA",
- "name": "Quebec",
- "code": "CA-QC"
- },
- {
- "country": "CA",
- "name": "Saskatchewan",
- "code": "CA-SK"
- },
- {
- "country": "CA",
- "name": "Yukon",
- "code": "CA-YT"
- },
- {
- "country": "US",
- "name": "Alabama",
- "code": "US-AL"
- },
- {
- "country": "US",
- "name": "Alaska",
- "code": "US-AK"
- },
- {
- "country": "US",
- "name": "American Samoa",
- "code": "US-AS"
- },
- {
- "country": "US",
- "name": "Arizona",
- "code": "US-AZ"
- },
- {
- "country": "US",
- "name": "Arkansas",
- "code": "US-AR"
- },
- {
- "country": "US",
- "name": "California",
- "code": "US-CA"
- },
- {
- "country": "US",
- "name": "Colorado",
- "code": "US-CO"
- },
- {
- "country": "US",
- "name": "Connecticut",
- "code": "US-CT"
- },
- {
- "country": "US",
- "name": "Delaware",
- "code": "US-DE"
- },
- {
- "country": "US",
- "name": "District of Columbia",
- "code": "US-DC"
- },
- {
- "country": "US",
- "name": "Florida",
- "code": "US-FL"
- },
- {
- "country": "US",
- "name": "Georgia",
- "code": "US-GA"
- },
- {
- "country": "US",
- "name": "Guam",
- "code": "US-GU"
- },
- {
- "country": "US",
- "name": "Hawaii",
- "code": "US-HI"
- },
- {
- "country": "US",
- "name": "Idaho",
- "code": "US-ID"
- },
- {
- "country": "US",
- "name": "Illinois",
- "code": "US-IL"
- },
- {
- "country": "US",
- "name": "Indiana",
- "code": "US-IN"
- },
- {
- "country": "US",
- "name": "Iowa",
- "code": "US-IA"
- },
- {
- "country": "US",
- "name": "Kansas",
- "code": "US-KS"
- },
- {
- "country": "US",
- "name": "Kentucky",
- "code": "US-KY"
- },
- {
- "country": "US",
- "name": "Louisiana",
- "code": "US-LA"
- },
- {
- "country": "US",
- "name": "Maine",
- "code": "US-ME"
- },
- {
- "country": "US",
- "name": "Maryland",
- "code": "US-MD"
- },
- {
- "country": "US",
- "name": "Massachusetts",
- "code": "US-MA"
- },
- {
- "country": "US",
- "name": "Michigan",
- "code": "US-MI"
- },
- {
- "country": "US",
- "name": "Minnesota",
- "code": "US-MN"
- },
- {
- "country": "US",
- "name": "Mississippi",
- "code": "US-MS"
- },
- {
- "country": "US",
- "name": "Missouri",
- "code": "US-MO"
- },
- {
- "country": "US",
- "name": "Montana",
- "code": "US-MT"
- },
- {
- "country": "US",
- "name": "Nebraska",
- "code": "US-NE"
- },
- {
- "country": "US",
- "name": "Nevada",
- "code": "US-NV"
- },
- {
- "country": "US",
- "name": "New Hampshire",
- "code": "US-NH"
- },
- {
- "country": "US",
- "name": "New Jersey",
- "code": "US-NJ"
- },
- {
- "country": "US",
- "name": "New Mexico",
- "code": "US-NM"
- },
- {
- "country": "US",
- "name": "New York",
- "code": "US-NY"
- },
- {
- "country": "US",
- "name": "North Carolina",
- "code": "US-NC"
- },
- {
- "country": "US",
- "name": "North Dakota",
- "code": "US-ND"
- },
- {
- "country": "US",
- "name": "Northern Mariana Islands",
- "code": "US-MP"
- },
- {
- "country": "US",
- "name": "Ohio",
- "code": "US-OH"
- },
- {
- "country": "US",
- "name": "Oklahoma",
- "code": "US-OK"
- },
- {
- "country": "US",
- "name": "Oregon",
- "code": "US-OR"
- },
- {
- "country": "US",
- "name": "Pennsylvania",
- "code": "US-PA"
- },
- {
- "country": "US",
- "name": "Puerto Rico",
- "code": "US-PR"
- },
- {
- "country": "US",
- "name": "Rhode Island",
- "code": "US-RI"
- },
- {
- "country": "US",
- "name": "South Carolina",
- "code": "US-SC"
- },
- {
- "country": "US",
- "name": "South Dakota",
- "code": "US-SD"
- },
- {
- "country": "US",
- "name": "Tennessee",
- "code": "US-TN"
- },
- {
- "country": "US",
- "name": "Texas",
- "code": "US-TX"
- },
- {
- "country": "US",
- "name": "U.S. Virgin Islands",
- "code": "US-VI"
- },
- {
- "country": "US",
- "name": "United States Minor Outlying Islands",
- "code": "US-UM"
- },
- {
- "country": "US",
- "name": "Utah",
- "code": "US-UT"
- },
- {
- "country": "US",
- "name": "Vermont",
- "code": "US-VT"
- },
- {
- "country": "US",
- "name": "Virginia",
- "code": "US-VA"
- },
- {
- "country": "US",
- "name": "Washington",
- "code": "US-WA"
- },
- {
- "country": "US",
- "name": "West Virginia",
- "code": "US-WV"
- },
- {
- "country": "US",
- "name": "Wisconsin",
- "code": "US-WI"
- },
- {
- "country": "US",
- "name": "Wyoming",
- "code": "US-WY"
- }
+[
+ {
+ "country": "CA",
+ "name": "Alberta",
+ "code": "CA-AB"
+ },
+ {
+ "country": "CA",
+ "name": "British Columbia",
+ "code": "CA-BC"
+ },
+ {
+ "country": "CA",
+ "name": "Manitoba",
+ "code": "CA-MB"
+ },
+ {
+ "country": "CA",
+ "name": "New Brunswick",
+ "code": "CA-NB"
+ },
+ {
+ "country": "CA",
+ "name": "Newfoundland and Labrador",
+ "code": "CA-NL"
+ },
+ {
+ "country": "CA",
+ "name": "Northwest Territories",
+ "code": "CA-NT"
+ },
+ {
+ "country": "CA",
+ "name": "Nova Scotia",
+ "code": "CA-NS"
+ },
+ {
+ "country": "CA",
+ "name": "Nunavut",
+ "code": "CA-NU"
+ },
+ {
+ "country": "CA",
+ "name": "Ontario",
+ "code": "CA-ON"
+ },
+ {
+ "country": "CA",
+ "name": "Prince Edward Island",
+ "code": "CA-PE"
+ },
+ {
+ "country": "CA",
+ "name": "Quebec",
+ "code": "CA-QC"
+ },
+ {
+ "country": "CA",
+ "name": "Saskatchewan",
+ "code": "CA-SK"
+ },
+ {
+ "country": "CA",
+ "name": "Yukon",
+ "code": "CA-YT"
+ },
+ {
+ "country": "US",
+ "name": "Alabama",
+ "code": "US-AL"
+ },
+ {
+ "country": "US",
+ "name": "Alaska",
+ "code": "US-AK"
+ },
+ {
+ "country": "US",
+ "name": "American Samoa",
+ "code": "US-AS"
+ },
+ {
+ "country": "US",
+ "name": "Arizona",
+ "code": "US-AZ"
+ },
+ {
+ "country": "US",
+ "name": "Arkansas",
+ "code": "US-AR"
+ },
+ {
+ "country": "US",
+ "name": "California",
+ "code": "US-CA"
+ },
+ {
+ "country": "US",
+ "name": "Colorado",
+ "code": "US-CO"
+ },
+ {
+ "country": "US",
+ "name": "Connecticut",
+ "code": "US-CT"
+ },
+ {
+ "country": "US",
+ "name": "Delaware",
+ "code": "US-DE"
+ },
+ {
+ "country": "US",
+ "name": "District of Columbia",
+ "code": "US-DC"
+ },
+ {
+ "country": "US",
+ "name": "Florida",
+ "code": "US-FL"
+ },
+ {
+ "country": "US",
+ "name": "Georgia",
+ "code": "US-GA"
+ },
+ {
+ "country": "US",
+ "name": "Guam",
+ "code": "US-GU"
+ },
+ {
+ "country": "US",
+ "name": "Hawaii",
+ "code": "US-HI"
+ },
+ {
+ "country": "US",
+ "name": "Idaho",
+ "code": "US-ID"
+ },
+ {
+ "country": "US",
+ "name": "Illinois",
+ "code": "US-IL"
+ },
+ {
+ "country": "US",
+ "name": "Indiana",
+ "code": "US-IN"
+ },
+ {
+ "country": "US",
+ "name": "Iowa",
+ "code": "US-IA"
+ },
+ {
+ "country": "US",
+ "name": "Kansas",
+ "code": "US-KS"
+ },
+ {
+ "country": "US",
+ "name": "Kentucky",
+ "code": "US-KY"
+ },
+ {
+ "country": "US",
+ "name": "Louisiana",
+ "code": "US-LA"
+ },
+ {
+ "country": "US",
+ "name": "Maine",
+ "code": "US-ME"
+ },
+ {
+ "country": "US",
+ "name": "Maryland",
+ "code": "US-MD"
+ },
+ {
+ "country": "US",
+ "name": "Massachusetts",
+ "code": "US-MA"
+ },
+ {
+ "country": "US",
+ "name": "Michigan",
+ "code": "US-MI"
+ },
+ {
+ "country": "US",
+ "name": "Minnesota",
+ "code": "US-MN"
+ },
+ {
+ "country": "US",
+ "name": "Mississippi",
+ "code": "US-MS"
+ },
+ {
+ "country": "US",
+ "name": "Missouri",
+ "code": "US-MO"
+ },
+ {
+ "country": "US",
+ "name": "Montana",
+ "code": "US-MT"
+ },
+ {
+ "country": "US",
+ "name": "Nebraska",
+ "code": "US-NE"
+ },
+ {
+ "country": "US",
+ "name": "Nevada",
+ "code": "US-NV"
+ },
+ {
+ "country": "US",
+ "name": "New Hampshire",
+ "code": "US-NH"
+ },
+ {
+ "country": "US",
+ "name": "New Jersey",
+ "code": "US-NJ"
+ },
+ {
+ "country": "US",
+ "name": "New Mexico",
+ "code": "US-NM"
+ },
+ {
+ "country": "US",
+ "name": "New York",
+ "code": "US-NY"
+ },
+ {
+ "country": "US",
+ "name": "North Carolina",
+ "code": "US-NC"
+ },
+ {
+ "country": "US",
+ "name": "North Dakota",
+ "code": "US-ND"
+ },
+ {
+ "country": "US",
+ "name": "Northern Mariana Islands",
+ "code": "US-MP"
+ },
+ {
+ "country": "US",
+ "name": "Ohio",
+ "code": "US-OH"
+ },
+ {
+ "country": "US",
+ "name": "Oklahoma",
+ "code": "US-OK"
+ },
+ {
+ "country": "US",
+ "name": "Oregon",
+ "code": "US-OR"
+ },
+ {
+ "country": "US",
+ "name": "Pennsylvania",
+ "code": "US-PA"
+ },
+ {
+ "country": "US",
+ "name": "Puerto Rico",
+ "code": "US-PR"
+ },
+ {
+ "country": "US",
+ "name": "Rhode Island",
+ "code": "US-RI"
+ },
+ {
+ "country": "US",
+ "name": "South Carolina",
+ "code": "US-SC"
+ },
+ {
+ "country": "US",
+ "name": "South Dakota",
+ "code": "US-SD"
+ },
+ {
+ "country": "US",
+ "name": "Tennessee",
+ "code": "US-TN"
+ },
+ {
+ "country": "US",
+ "name": "Texas",
+ "code": "US-TX"
+ },
+ {
+ "country": "US",
+ "name": "U.S. Virgin Islands",
+ "code": "US-VI"
+ },
+ {
+ "country": "US",
+ "name": "United States Minor Outlying Islands",
+ "code": "US-UM"
+ },
+ {
+ "country": "US",
+ "name": "Utah",
+ "code": "US-UT"
+ },
+ {
+ "country": "US",
+ "name": "Vermont",
+ "code": "US-VT"
+ },
+ {
+ "country": "US",
+ "name": "Virginia",
+ "code": "US-VA"
+ },
+ {
+ "country": "US",
+ "name": "Washington",
+ "code": "US-WA"
+ },
+ {
+ "country": "US",
+ "name": "West Virginia",
+ "code": "US-WV"
+ },
+ {
+ "country": "US",
+ "name": "Wisconsin",
+ "code": "US-WI"
+ },
+ {
+ "country": "US",
+ "name": "Wyoming",
+ "code": "US-WY"
+ }
]
\ No newline at end of file
diff --git a/tests/__data__/input/__data__/timezones.json b/tests/__data__/input/data/timezones.json
similarity index 100%
rename from tests/__data__/input/__data__/timezones.json
rename to tests/__data__/input/data/timezones.json
diff --git a/tests/__data__/input/epg_grab/custom.channels.xml b/tests/__data__/input/epg_grab/custom.channels.xml
index e107685e..5643ee72 100644
--- a/tests/__data__/input/epg_grab/custom.channels.xml
+++ b/tests/__data__/input/epg_grab/custom.channels.xml
@@ -1,9 +1,9 @@
-
-
- Custom Channel 1
- Custom Channel 2
- Channel 1
- Channel 3
- Channel 4
- Channel 1
+
+
+ Custom Channel 1
+ Custom Channel 2
+ Channel 1
+ Channel 3
+ Channel 4
+ Channel 1
\ No newline at end of file
diff --git a/tests/__data__/input/epg_grab/example.com/example.com.channels.xml b/tests/__data__/input/epg_grab/example.com/example.com.channels.xml
deleted file mode 100644
index 6f589e0b..00000000
--- a/tests/__data__/input/epg_grab/example.com/example.com.channels.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- Channel 1
- Channel 2
- Channel 1
- Channel 3
-
\ No newline at end of file
diff --git a/tests/__data__/input/epg_grab/example.com/example.com.config.js b/tests/__data__/input/epg_grab/example.com/example.com.config.js
deleted file mode 100644
index 107a761e..00000000
--- a/tests/__data__/input/epg_grab/example.com/example.com.config.js
+++ /dev/null
@@ -1,28 +0,0 @@
-module.exports = {
- site: 'example.com',
- days: 2,
- request: {
- timeout: 1000
- },
- url: 'https://example.com',
- parser({ channel, date }) {
- if (channel.xmltv_id === 'Channel2.us') return []
- else if (channel.xmltv_id === 'Channel1.us' && channel.lang === 'fr') {
- return [
- {
- title: 'Programme1 (example.com)',
- start: `${date.format('YYYY-MM-DD')}T04:30:00.000Z`,
- stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
- }
- ]
- }
-
- return [
- {
- title: 'Program1 (example.com)',
- start: `${date.format('YYYY-MM-DD')}T04:31:00.000Z`,
- stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
- }
- ]
- }
-}
diff --git a/tests/__data__/input/epg_grab/sites/example.com/example.com.channels.xml b/tests/__data__/input/epg_grab/sites/example.com/example.com.channels.xml
index cfd7a7bb..343ff70c 100644
--- a/tests/__data__/input/epg_grab/sites/example.com/example.com.channels.xml
+++ b/tests/__data__/input/epg_grab/sites/example.com/example.com.channels.xml
@@ -1,6 +1,7 @@
-
-
- Channel 2
- Channel 1
- Channel 1
+
+
+ Channel 1
+ Channel 2
+ Channel 1
+ Channel 3
\ No newline at end of file
diff --git a/tests/__data__/input/epg_grab/sites/example.com/example.com.config.js b/tests/__data__/input/epg_grab/sites/example.com/example.com.config.js
index 107a761e..01849370 100644
--- a/tests/__data__/input/epg_grab/sites/example.com/example.com.config.js
+++ b/tests/__data__/input/epg_grab/sites/example.com/example.com.config.js
@@ -1,28 +1,28 @@
-module.exports = {
- site: 'example.com',
- days: 2,
- request: {
- timeout: 1000
- },
- url: 'https://example.com',
- parser({ channel, date }) {
- if (channel.xmltv_id === 'Channel2.us') return []
- else if (channel.xmltv_id === 'Channel1.us' && channel.lang === 'fr') {
- return [
- {
- title: 'Programme1 (example.com)',
- start: `${date.format('YYYY-MM-DD')}T04:30:00.000Z`,
- stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
- }
- ]
- }
-
- return [
- {
- title: 'Program1 (example.com)',
- start: `${date.format('YYYY-MM-DD')}T04:31:00.000Z`,
- stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
- }
- ]
- }
-}
+module.exports = {
+ site: 'example.com',
+ days: 2,
+ request: {
+ timeout: 1000
+ },
+ url: 'https://example.com',
+ parser({ channel, date }) {
+ if (channel.xmltv_id === 'Channel2.us') return []
+ else if (channel.lang === 'fr') {
+ return [
+ {
+ title: 'Programme1 (example.com)',
+ start: `${date.format('YYYY-MM-DD')}T04:30:00.000Z`,
+ stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
+ }
+ ]
+ }
+
+ return [
+ {
+ title: 'Program1 (example.com)',
+ start: `${date.format('YYYY-MM-DD')}T04:31:00.000Z`,
+ stop: `${date.format('YYYY-MM-DD')}T07:10:00.000Z`
+ }
+ ]
+ }
+}
diff --git a/tests/__data__/input/sites_update/issues.mjs b/tests/__data__/input/sites_update/issues.mjs
index 96048350..a4187b8e 100644
--- a/tests/__data__/input/sites_update/issues.mjs
+++ b/tests/__data__/input/sites_update/issues.mjs
@@ -1,2523 +1,2603 @@
-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
- },
- {
- 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-MartialA \r\nchannel="Showtime2East.us">Two British soldiers receive seemingly impossible orders \r\nchannel="Showtime2East.us">There Will Be BloodDaniel \r\n```\r\nor:\r\n\r\n```\r\nchannel="MGMPlusEast.us">A Fistful of DynamiteA thief \r\nchannel="MGMPlusEast.us">The son (Robert De Niro) of a landowner and the son \r\nchannel="MGMPlusEast.us">Indecent ProposalA 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/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
+ },
+ {
+ 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-MartialA \r\nchannel="Showtime2East.us">Two British soldiers receive seemingly impossible orders \r\nchannel="Showtime2East.us">There Will Be BloodDaniel \r\n```\r\nor:\r\n\r\n```\r\nchannel="MGMPlusEast.us">A Fistful of DynamiteA thief \r\nchannel="MGMPlusEast.us">The son (Robert De Niro) of a landowner and the son \r\nchannel="MGMPlusEast.us">Indecent ProposalA 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
+ },
+ {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/12547',
+ repository_url: 'https://api.github.com/repos/iptv-org/epg',
+ labels_url: 'https://api.github.com/repos/iptv-org/epg/issues/12547/labels{/name}',
+ comments_url: 'https://api.github.com/repos/iptv-org/epg/issues/12547/comments',
+ events_url: 'https://api.github.com/repos/iptv-org/epg/issues/12547/events',
+ html_url: 'https://github.com/iptv-org/epg/issues/12547',
+ id: 3960418979,
+ node_id: 'I_kwDOFLVvtM6kiKaj',
+ number: 12547,
+ 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,
+ closed_by: null,
+ reactions: {
+ url: 'https://api.github.com/repos/iptv-org/epg/issues/12547/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/12547/timeline',
+ performed_via_github_app: null,
+ state_reason: null
+ }
+]
diff --git a/tests/commands/channels/edit.test.ts b/tests/commands/channels/edit.test.ts
index b150648a..a232af48 100644
--- a/tests/commands/channels/edit.test.ts
+++ b/tests/commands/channels/edit.test.ts
@@ -1,36 +1,36 @@
-import { execSync } from 'child_process'
-import fs from 'fs-extra'
-
-const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/__data__'
-
-beforeEach(() => {
- fs.emptyDirSync('tests/__data__/output')
- fs.copySync(
- 'tests/__data__/input/channels_edit/example.com.channels.xml',
- 'tests/__data__/output/channels.xml'
- )
-})
-
-describe('channels:edit', () => {
- it('shows list of options for a channel', () => {
- const cmd = `${ENV_VAR} npm run channels:edit --- tests/__data__/output/channels.xml`
- try {
- const stdout = execSync(cmd, { encoding: 'utf8' })
- if (process.env.DEBUG === 'true') console.log(cmd, stdout)
- checkStdout(stdout)
- } catch (error: unknown) {
- // NOTE: for Windows only
- if (process.env.DEBUG === 'true') console.log(cmd, error)
- if (error && typeof error === 'object' && 'stdout' in error) {
- checkStdout(error.stdout as string)
- }
- }
- })
-})
-
-function checkStdout(stdout: string) {
- expect(stdout).toContain('CNNInternational.us (CNN International, CNN, CNN Int)')
- expect(stdout).toContain('Type...')
- expect(stdout).toContain('Skip')
- expect(stdout).toContain("File 'tests/__data__/output/channels.xml' successfully saved")
-}
+import { execSync } from 'child_process'
+import fs from 'fs-extra'
+
+const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data'
+
+beforeEach(() => {
+ fs.emptyDirSync('tests/__data__/output')
+ fs.copySync(
+ 'tests/__data__/input/channels_edit/example.com.channels.xml',
+ 'tests/__data__/output/channels.xml'
+ )
+})
+
+describe('channels:edit', () => {
+ it('shows list of options for a channel', () => {
+ const cmd = `${ENV_VAR} npm run channels:edit --- tests/__data__/output/channels.xml`
+ try {
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+ checkStdout(stdout)
+ } catch (error: unknown) {
+ // NOTE: for Windows only
+ if (process.env.DEBUG === 'true') console.log(cmd, error)
+ if (error && typeof error === 'object' && 'stdout' in error) {
+ checkStdout(error.stdout as string)
+ }
+ }
+ })
+})
+
+function checkStdout(stdout: string) {
+ expect(stdout).toContain('CNNInternational.us (CNN International, CNN, CNN Int)')
+ expect(stdout).toContain('Type...')
+ expect(stdout).toContain('Skip')
+ expect(stdout).toContain("File 'tests/__data__/output/channels.xml' successfully saved")
+}
diff --git a/tests/commands/channels/format.test.ts b/tests/commands/channels/format.test.ts
new file mode 100644
index 00000000..503d2a60
--- /dev/null
+++ b/tests/commands/channels/format.test.ts
@@ -0,0 +1,29 @@
+import { execSync } from 'child_process'
+import { pathToFileURL } from 'node:url'
+import fs from 'fs-extra'
+
+beforeEach(() => {
+ fs.emptyDirSync('tests/__data__/output')
+ fs.copySync(
+ 'tests/__data__/input/channels_format/example.com.channels.xml',
+ 'tests/__data__/output/example.com.channels.xml'
+ )
+})
+
+describe('channels:format', () => {
+ it('can format *.channels.xml files', () => {
+ const cmd = 'npm run channels:format --- tests/__data__/output/example.com.channels.xml'
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/example.com.channels.xml')).toEqual(
+ content('tests/__data__/expected/channels_format/example.com.channels.xml')
+ )
+ })
+})
+
+function content(filepath: string) {
+ return fs.readFileSync(pathToFileURL(filepath), {
+ encoding: 'utf8'
+ })
+}
diff --git a/tests/commands/channels/validate.test.ts b/tests/commands/channels/validate.test.ts
index e3dc123a..bdf2a4ff 100644
--- a/tests/commands/channels/validate.test.ts
+++ b/tests/commands/channels/validate.test.ts
@@ -1,58 +1,58 @@
-import { execSync } from 'child_process'
-
-interface ExecError {
- status: number
- stdout: string
-}
-
-const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/__data__'
-
-describe('channels:validate', () => {
- it('will show a message if the file contains a duplicate', () => {
- try {
- const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/duplicate.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(`
-┌─────────┬─────────────┬──────┬─────────────────┬─────────┬─────────┐
-│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
-├─────────┼─────────────┼──────┼─────────────────┼─────────┼─────────┤
-│ 0 │ 'duplicate' │ 'en' │ 'Bravo.us@East' │ '140' │ 'Bravo' │
-└─────────┴─────────────┴──────┴─────────────────┴─────────┴─────────┘
-
-1 problems (1 errors, 0 warnings) in 1 file(s)
-`)
- }
- })
-
- it('will show a message if the file contains a channel with wrong channel id', () => {
- const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/wrong_channel_id.channels.xml`
- const stdout = execSync(cmd, { encoding: 'utf8' })
- expect(stdout).toContain(`
-┌─────────┬────────────────────┬──────┬────────────────────┬─────────┬─────────────────────┐
-│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
-├─────────┼────────────────────┼──────┼────────────────────┼─────────┼─────────────────────┤
-│ 0 │ 'wrong_channel_id' │ 'en' │ 'CNNInternational' │ '140' │ 'CNN International' │
-└─────────┴────────────────────┴──────┴────────────────────┴─────────┴─────────────────────┘
-
-1 problems (0 errors, 1 warnings) in 1 file(s)
-`)
- })
-
- it('will show a message if the file contains a channel with wrong feed id', () => {
- const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/wrong_feed_id.channels.xml`
- const stdout = execSync(cmd, { encoding: 'utf8' })
- expect(stdout).toContain(`
-┌─────────┬─────────────────┬──────┬─────────────────┬─────────┬─────────┐
-│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
-├─────────┼─────────────────┼──────┼─────────────────┼─────────┼─────────┤
-│ 0 │ 'wrong_feed_id' │ 'en' │ 'Bravo.us@West' │ '150' │ 'Bravo' │
-└─────────┴─────────────────┴──────┴─────────────────┴─────────┴─────────┘
-
-1 problems (0 errors, 1 warnings) in 1 file(s)
-`)
- })
-})
+import { execSync } from 'child_process'
+
+interface ExecError {
+ status: number
+ stdout: string
+}
+
+const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data'
+
+describe('channels:validate', () => {
+ it('will show a message if the file contains a duplicate', () => {
+ try {
+ const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/duplicate.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(`
+┌─────────┬─────────────┬──────┬─────────────────┬─────────┬─────────┐
+│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
+├─────────┼─────────────┼──────┼─────────────────┼─────────┼─────────┤
+│ 0 │ 'duplicate' │ 'en' │ 'Bravo.us@East' │ '140' │ 'Bravo' │
+└─────────┴─────────────┴──────┴─────────────────┴─────────┴─────────┘
+
+1 problems (1 errors, 0 warnings) in 1 file(s)
+`)
+ }
+ })
+
+ it('will show a message if the file contains a channel with wrong channel id', () => {
+ const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/wrong_channel_id.channels.xml`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ expect(stdout).toContain(`
+┌─────────┬────────────────────┬──────┬────────────────────┬─────────┬─────────────────────┐
+│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
+├─────────┼────────────────────┼──────┼────────────────────┼─────────┼─────────────────────┤
+│ 0 │ 'wrong_channel_id' │ 'en' │ 'CNNInternational' │ '140' │ 'CNN International' │
+└─────────┴────────────────────┴──────┴────────────────────┴─────────┴─────────────────────┘
+
+1 problems (0 errors, 1 warnings) in 1 file(s)
+`)
+ })
+
+ it('will show a message if the file contains a channel with wrong feed id', () => {
+ const cmd = `${ENV_VAR} npm run channels:validate --- tests/__data__/input/channels_validate/wrong_feed_id.channels.xml`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ expect(stdout).toContain(`
+┌─────────┬─────────────────┬──────┬─────────────────┬─────────┬─────────┐
+│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
+├─────────┼─────────────────┼──────┼─────────────────┼─────────┼─────────┤
+│ 0 │ 'wrong_feed_id' │ 'en' │ 'Bravo.us@West' │ '150' │ 'Bravo' │
+└─────────┴─────────────────┴──────┴─────────────────┴─────────┴─────────┘
+
+1 problems (0 errors, 1 warnings) in 1 file(s)
+`)
+ })
+})
diff --git a/tests/commands/epg/grab.test.ts b/tests/commands/epg/grab.test.ts
index 37d35da1..afb3ddf0 100644
--- a/tests/commands/epg/grab.test.ts
+++ b/tests/commands/epg/grab.test.ts
@@ -1,162 +1,114 @@
-import { pathToFileURL } from 'node:url'
-import { execSync } from 'child_process'
-import { Zip } from '@freearhey/core'
-import fs from 'fs-extra'
-import path from 'path'
-
-const ENV_VAR =
- 'cross-env SITES_DIR=tests/__data__/input/epg_grab/sites CURR_DATE=2022-10-20 DATA_DIR=tests/__data__/input/__data__'
-
-beforeEach(() => {
- fs.emptyDirSync('tests/__data__/output')
-})
-
-describe('epg:grab', () => {
- it('can grab epg by site name', () => {
- const cmd = `${ENV_VAR} npm run grab --- --site=example.com --output="${path.resolve(
- 'tests/__data__/output/guide.xml'
- )}" --timeout=100`
- 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/epg_grab/base.guide.xml')
- )
- })
-
- 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`
- let errorThrown = false
- try {
- execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
- // If no error is thrown, explicitly fail the test
- fail('Expected command to throw an error due to timeout, but it did not.')
- } catch (error) {
- errorThrown = true
- if (process.env.DEBUG === 'true') {
- const stderr = error.stderr?.toString() || ''
- const stdout = error.stdout?.toString() || ''
- const combined = stderr + stdout
- console.log('stdout:', stdout)
- console.log('stderr:', stderr)
- console.log('combined:', combined)
- console.log('exit code:', error.exitCode)
- console.log('Error output:', combined)
- }
- }
- expect(errorThrown).toBe(true)
- })
-
- 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" --timeout=100`
- 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/epg_grab/guides/en/example.com.xml')
- )
-
- expect(content('tests/__data__/output/guides/fr/example.com.xml')).toEqual(
- content('tests/__data__/expected/epg_grab/guides/fr/example.com.xml')
- )
- })
-
- 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 --timeout=100`
- 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/epg_grab/guides/fr/example.com.xml')
- )
- })
-
- it('can grab epg then using a multi-language filter', () => {
- const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg_grab/example.com/example.com.channels.xml --output=tests/__data__/output/guides/{site}.xml --lang=fr,it --timeout=100`
- const stdout = execSync(cmd, { encoding: 'utf8' })
- if (process.env.DEBUG === 'true') console.log(cmd, stdout)
-
- expect(content('tests/__data__/output/guides/example.com.xml')).toEqual(
- content('tests/__data__/expected/epg_grab/lang.guide.xml')
- )
- })
-
- it('can grab epg via https proxy', () => {
- const cmd = `${ENV_VAR} npm run grab --- --site=example.com --proxy=https://bob:123456@proxy.com:1234 --output="${path.resolve(
- 'tests/__data__/output/guide.xml'
- )}" --timeout=100`
- 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/epg_grab/proxy.guide.xml')
- )
- })
-
- it('can grab epg via socks5 proxy', () => {
- const cmd = `${ENV_VAR} npm run grab --- --site=example.com --proxy=socks5://bob:123456@proxy.com:1234 --output="${path.resolve(
- 'tests/__data__/output/guide.xml'
- )}" --timeout=100`
- 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/epg_grab/proxy.guide.xml')
- )
- })
-
- it('can grab epg with curl option', () => {
- const cmd = `${ENV_VAR} npm run grab --- --site=example.com --curl --output="${path.resolve(
- 'tests/__data__/output/guide.xml'
- )}" --timeout=100`
- const stdout = execSync(cmd, { encoding: 'utf8' })
- if (process.env.DEBUG === 'true') console.log(cmd, stdout)
-
- expect(stdout).toContain('curl https://example.com')
- })
-
- 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 --timeout=100`
- 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/epg_grab/template.guide.xml')
- )
- })
-
- 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 --timeout=100`
- 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/epg_grab/custom_channels.guide.xml')
- )
- })
-
- it('can grab epg with gzip option enabled', () => {
- 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 --timeout=100`
- 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/epg_grab/template.guide.xml')
- )
-
- const zip = new Zip()
- const expected = zip.decompress(fs.readFileSync('tests/__data__/output/guide.xml.gz'))
- const result = zip.decompress(
- fs.readFileSync('tests/__data__/expected/epg_grab/template.guide.xml.gz')
- )
- expect(expected).toEqual(result)
- })
-})
-
-function content(filepath: string) {
- return fs.readFileSync(pathToFileURL(filepath), {
- encoding: 'utf8'
- })
-}
+import { pathToFileURL } from 'node:url'
+import { execSync } from 'child_process'
+import fs from 'fs-extra'
+import path from 'path'
+import pako from 'pako'
+
+const ENV_VAR =
+ 'cross-env SITES_DIR=tests/__data__/input/epg_grab/sites CURR_DATE=2022-10-20 DATA_DIR=tests/__data__/input/data'
+
+beforeEach(() => {
+ fs.emptyDirSync('tests/__data__/output')
+})
+
+describe('epg:grab', () => {
+ it('can grab epg by site name', () => {
+ const cmd = `${ENV_VAR} npm run grab --- --site=example.com --output="${path.resolve(
+ 'tests/__data__/output/guides/base.guide.xml'
+ )}"`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/base.guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/base.guide.xml')
+ )
+ })
+
+ it('can grab epg with curl option', () => {
+ const cmd = `${ENV_VAR} npm run grab --- --site=example.com --curl --output="${path.resolve(
+ 'tests/__data__/output/guides/curl.guide.xml'
+ )}"`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(stdout).toContain('curl https://example.com')
+ })
+
+ 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/wildcard/{site}/{lang}/guide.xml"`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/wildcard/example.com/en/guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/wildcard/example.com/en/guide.xml')
+ )
+
+ expect(content('tests/__data__/output/guides/wildcard/example.com/fr/guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/wildcard/example.com/fr/guide.xml')
+ )
+ })
+
+ 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/{lang}/guide.xml --lang=fr`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/lang/fr/guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/lang/fr/guide.xml')
+ )
+ })
+
+ it('can grab epg then using a multi-language filter', () => {
+ 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/multilang.guide.xml --lang=fr,it`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/multilang.guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/multilang.guide.xml')
+ )
+ })
+
+ 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/guides/custom_channels.guide.xml `
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/custom_channels.guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/custom_channels.guide.xml')
+ )
+ })
+
+ 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/guides/multiple_channels.guide.xml`
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/multiple_channels.guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/multiple_channels.guide.xml')
+ )
+ })
+
+ it('can grab epg with gzip option enabled', () => {
+ const cmd = `${ENV_VAR} npm run grab --- --channels=tests/__data__/input/epg_grab/sites/example2.com/example2.com.channels.xml --output="${path.resolve(
+ 'tests/__data__/output/guides/gzip.guide.xml'
+ )}" --gzip `
+ const stdout = execSync(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd, stdout)
+
+ expect(content('tests/__data__/output/guides/gzip.guide.xml')).toEqual(
+ content('tests/__data__/expected/epg_grab/gzip.guide.xml')
+ )
+
+ const expected = pako.ungzip(fs.readFileSync('tests/__data__/output/guides/gzip.guide.xml.gz'))
+ const result = pako.ungzip(
+ fs.readFileSync('tests/__data__/expected/epg_grab/gzip.guide.xml.gz')
+ )
+ expect(expected).toEqual(result)
+ })
+})
+
+function content(filepath: string) {
+ return fs.readFileSync(pathToFileURL(filepath), {
+ encoding: 'utf8'
+ })
+}
diff --git a/tsconfig.json b/tsconfig.json
index a36345fb..cec89f50 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,8 +1,8 @@
{
"compilerOptions": {
"strict": true,
- "module": "Node16",
- "moduleResolution": "node16",
+ "module": "commonjs",
+ "moduleResolution": "nodenext",
"target": "es2022",
"esModuleInterop": true,
"declaration": true,