diff --git a/.github/workflows/i.mjh.nz.yml b/.github/workflows/i.mjh.nz.yml new file mode 100644 index 00000000..5b2fd0ba --- /dev/null +++ b/.github/workflows/i.mjh.nz.yml @@ -0,0 +1,17 @@ +name: i.mjh.nz +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + workflow_run: + workflows: [_trigger] + types: + - completed +jobs: + load: + uses: ./.github/workflows/_load.yml + with: + site: ${{github.workflow}} + secrets: + APP_ID: ${{ secrets.APP_ID }} + APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/package-lock.json b/package-lock.json index 8c3ac996..5204801e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "commander": "^8.2.0", "csv-parser": "^3.0.0", "dayjs": "^1.10.8", - "epg-grabber": "^0.25.4", + "epg-grabber": "^0.26.0", "epg-parser": "^0.1.6", "form-data": "^4.0.0", "fs-extra": "^10.0.1", @@ -26,7 +26,7 @@ "lodash": "^4.17.21", "markdown-include": "^0.4.3", "mockdate": "^3.0.5", - "nedb-promises": "^6.0.3", + "nedb-promises": "^4.1.5", "node-cleanup": "^2.1.2", "node-gzip": "^1.1.2", "parse-duration": "^1.0.0", @@ -867,26 +867,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@seald-io/binary-search-tree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.2.tgz", - "integrity": "sha512-+pYGvPFAk7wUR+ONMOlc6A+LUN4kOCFwyPLjyaeS7wVibADPHWYJNYsNtyIAwjF1AXQkuaXElnIc4XjKt55QZA==" - }, - "node_modules/@seald-io/nedb": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-2.2.2.tgz", - "integrity": "sha512-z91J3pem4ENzHuu9BilOSdlGL2S14OQYePPdvBcPHgHr+s51VIUwQARcOjx21KvtkA27vEpgPqzrVKh7nSlIfw==", - "dependencies": { - "@seald-io/binary-search-tree": "^1.0.2", - "async": "0.2.10", - "localforage": "^1.9.0" - } - }, - "node_modules/@seald-io/nedb/node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" - }, "node_modules/@sindresorhus/is": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", @@ -1270,16 +1250,17 @@ "follow-redirects": "^1.14.0" } }, - "node_modules/axios-cache-adapter": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/axios-cache-adapter/-/axios-cache-adapter-2.7.3.tgz", - "integrity": "sha512-A+ZKJ9lhpjthOEp4Z3QR/a9xC4du1ALaAsejgRGrH9ef6kSDxdFrhRpulqsh9khsEnwXxGfgpUuDp1YXMNMEiQ==", + "node_modules/axios-cache-interceptor": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-0.10.3.tgz", + "integrity": "sha512-oyHlhmA6zzZJDk/ZMPWPNmO3z8gBU3mWIqAZy+GIUsvwpmwyPlC2XvZ3PTOZHgpWI2kEocMUhk3+w9VwMXfZ4w==", "dependencies": { - "cache-control-esm": "1.0.0", - "md5": "^2.2.1" + "cache-parser": "^1.2.4", + "fast-defer": "^1.1.7", + "object-code": "^1.2.2" }, - "peerDependencies": { - "axios": "~0.21.1" + "funding": { + "url": "https://github.com/ArthurFiorette/axios-cache-interceptor?sponsor=1" } }, "node_modules/axios-cookiejar-support": { @@ -1438,6 +1419,14 @@ } ] }, + "node_modules/binary-search-tree": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz", + "integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=", + "dependencies": { + "underscore": "~1.4.4" + } + }, "node_modules/bindings": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", @@ -1541,10 +1530,10 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/cache-control-esm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cache-control-esm/-/cache-control-esm-1.0.0.tgz", - "integrity": "sha512-Fa3UV4+eIk4EOih8FTV6EEsVKO0W5XWtNs6FC3InTfVz+EjurjPfDXY5wZDo/lxjDxg5RjNcurLyxEJBcEUx9g==" + "node_modules/cache-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz", + "integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g==" }, "node_modules/cacheable-lookup": { "version": "5.0.4", @@ -1644,14 +1633,6 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "engines": { - "node": "*" - } - }, "node_modules/cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -1906,14 +1887,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "engines": { - "node": "*" - } - }, "node_modules/css-select": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", @@ -2252,12 +2225,12 @@ } }, "node_modules/epg-grabber": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.25.4.tgz", - "integrity": "sha512-fQh04OaNY+LsxtMerT3tOMfcaiMe0f5ZaXjjcm2TnnB4sPN0+KkSmX/uy24NErggBgV+O0jyl6+zulARciojtA==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.26.0.tgz", + "integrity": "sha512-QOJsPMhWi+s3jcx0U8f7ZlQfBgsaP56w1JdSascZ92yFiR2bvcdEFaAJuzAgKoQiicoXDKdzoK5r18mjLg05KQ==", "dependencies": { "axios": "^0.21.1", - "axios-cache-adapter": "^2.7.3", + "axios-cache-interceptor": "^0.10.3", "axios-cookiejar-support": "^1.0.1", "axios-mock-adapter": "^1.20.0", "commander": "^7.1.0", @@ -2446,6 +2419,11 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-defer": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.7.tgz", + "integrity": "sha512-tJ01ulDWT2WhqxMKS20nXX6wyX2iInBYpbN3GO7yjKwXMY4qvkdBRxak9IFwBLlFDESox+SwSvqMCZDfe1tqeg==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4112,21 +4090,6 @@ "markdown-include": "bin/cli.js" } }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/md5/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4253,14 +4216,31 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, - "node_modules/nedb-promises": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.0.3.tgz", - "integrity": "sha512-pd0N6EsIPhXsfqdLcBJGig1FoTdV8wtuiXB7rBUqycJdUSA6wdI5BlkwEAjDBWIwZc4+xqBHRLtuAB7/bjS+rg==", + "node_modules/nedb": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz", + "integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=", "dependencies": { - "@seald-io/nedb": "^2.2.0" + "async": "0.2.10", + "binary-search-tree": "0.2.5", + "localforage": "^1.3.0", + "mkdirp": "~0.5.1", + "underscore": "~1.4.4" } }, + "node_modules/nedb-promises": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-4.1.5.tgz", + "integrity": "sha512-mnzB7y5tE1MXGDYurFNJeX2Kh4oEyH88uBCXOm4jDXiu6dAALDg8+urIuSuo15oo8spMbWzDsnD03KHKyuBjNw==", + "dependencies": { + "nedb": "^1.8.0" + } + }, + "node_modules/nedb/node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, "node_modules/needle": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", @@ -4466,6 +4446,11 @@ "node": ">=0.10.0" } }, + "node_modules/object-code": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.2.2.tgz", + "integrity": "sha512-ZSbEQdei4ElzuDM4BmazKSwINacocBf3/8rte25aNqXzvT/8dSaNVY9egsjAaBL/UhW55JNxAvXOKPIsL2MwWQ==" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5644,6 +5629,11 @@ "node": ">=4.2.0" } }, + "node_modules/underscore": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", + "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=" + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -6584,28 +6574,6 @@ "chalk": "^4.0.0" } }, - "@seald-io/binary-search-tree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.2.tgz", - "integrity": "sha512-+pYGvPFAk7wUR+ONMOlc6A+LUN4kOCFwyPLjyaeS7wVibADPHWYJNYsNtyIAwjF1AXQkuaXElnIc4XjKt55QZA==" - }, - "@seald-io/nedb": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-2.2.2.tgz", - "integrity": "sha512-z91J3pem4ENzHuu9BilOSdlGL2S14OQYePPdvBcPHgHr+s51VIUwQARcOjx21KvtkA27vEpgPqzrVKh7nSlIfw==", - "requires": { - "@seald-io/binary-search-tree": "^1.0.2", - "async": "0.2.10", - "localforage": "^1.9.0" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" - } - } - }, "@sindresorhus/is": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", @@ -6945,13 +6913,14 @@ "follow-redirects": "^1.14.0" } }, - "axios-cache-adapter": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/axios-cache-adapter/-/axios-cache-adapter-2.7.3.tgz", - "integrity": "sha512-A+ZKJ9lhpjthOEp4Z3QR/a9xC4du1ALaAsejgRGrH9ef6kSDxdFrhRpulqsh9khsEnwXxGfgpUuDp1YXMNMEiQ==", + "axios-cache-interceptor": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-0.10.3.tgz", + "integrity": "sha512-oyHlhmA6zzZJDk/ZMPWPNmO3z8gBU3mWIqAZy+GIUsvwpmwyPlC2XvZ3PTOZHgpWI2kEocMUhk3+w9VwMXfZ4w==", "requires": { - "cache-control-esm": "1.0.0", - "md5": "^2.2.1" + "cache-parser": "^1.2.4", + "fast-defer": "^1.1.7", + "object-code": "^1.2.2" } }, "axios-cookiejar-support": { @@ -7063,6 +7032,14 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "binary-search-tree": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz", + "integrity": "sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=", + "requires": { + "underscore": "~1.4.4" + } + }, "bindings": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", @@ -7139,10 +7116,10 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "cache-control-esm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cache-control-esm/-/cache-control-esm-1.0.0.tgz", - "integrity": "sha512-Fa3UV4+eIk4EOih8FTV6EEsVKO0W5XWtNs6FC3InTfVz+EjurjPfDXY5wZDo/lxjDxg5RjNcurLyxEJBcEUx9g==" + "cache-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz", + "integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g==" }, "cacheable-lookup": { "version": "5.0.4", @@ -7207,11 +7184,6 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" - }, "cheerio": { "version": "1.0.0-rc.10", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", @@ -7422,11 +7394,6 @@ "which": "^2.0.1" } }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" - }, "css-select": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", @@ -7670,12 +7637,12 @@ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "epg-grabber": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.25.4.tgz", - "integrity": "sha512-fQh04OaNY+LsxtMerT3tOMfcaiMe0f5ZaXjjcm2TnnB4sPN0+KkSmX/uy24NErggBgV+O0jyl6+zulARciojtA==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.26.0.tgz", + "integrity": "sha512-QOJsPMhWi+s3jcx0U8f7ZlQfBgsaP56w1JdSascZ92yFiR2bvcdEFaAJuzAgKoQiicoXDKdzoK5r18mjLg05KQ==", "requires": { "axios": "^0.21.1", - "axios-cache-adapter": "^2.7.3", + "axios-cache-interceptor": "^0.10.3", "axios-cookiejar-support": "^1.0.1", "axios-mock-adapter": "^1.20.0", "commander": "^7.1.0", @@ -7812,6 +7779,11 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-defer": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.7.tgz", + "integrity": "sha512-tJ01ulDWT2WhqxMKS20nXX6wyX2iInBYpbN3GO7yjKwXMY4qvkdBRxak9IFwBLlFDESox+SwSvqMCZDfe1tqeg==" + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -9056,23 +9028,6 @@ "q": "^1.2.0" } }, - "md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - } - } - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -9180,12 +9135,31 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, - "nedb-promises": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.0.3.tgz", - "integrity": "sha512-pd0N6EsIPhXsfqdLcBJGig1FoTdV8wtuiXB7rBUqycJdUSA6wdI5BlkwEAjDBWIwZc4+xqBHRLtuAB7/bjS+rg==", + "nedb": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz", + "integrity": "sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=", "requires": { - "@seald-io/nedb": "^2.2.0" + "async": "0.2.10", + "binary-search-tree": "0.2.5", + "localforage": "^1.3.0", + "mkdirp": "~0.5.1", + "underscore": "~1.4.4" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + } + } + }, + "nedb-promises": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-4.1.5.tgz", + "integrity": "sha512-mnzB7y5tE1MXGDYurFNJeX2Kh4oEyH88uBCXOm4jDXiu6dAALDg8+urIuSuo15oo8spMbWzDsnD03KHKyuBjNw==", + "requires": { + "nedb": "^1.8.0" } }, "needle": { @@ -9354,6 +9328,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-code": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.2.2.tgz", + "integrity": "sha512-ZSbEQdei4ElzuDM4BmazKSwINacocBf3/8rte25aNqXzvT/8dSaNVY9egsjAaBL/UhW55JNxAvXOKPIsL2MwWQ==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -10215,6 +10194,11 @@ "optional": true, "peer": true }, + "underscore": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", + "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=" + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/package.json b/package.json index 958e422c..e83b1f13 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "commander": "^8.2.0", "csv-parser": "^3.0.0", "dayjs": "^1.10.8", - "epg-grabber": "^0.25.4", + "epg-grabber": "^0.26.0", "epg-parser": "^0.1.6", "form-data": "^4.0.0", "fs-extra": "^10.0.1", @@ -48,7 +48,7 @@ "lodash": "^4.17.21", "markdown-include": "^0.4.3", "mockdate": "^3.0.5", - "nedb-promises": "^6.0.3", + "nedb-promises": "^4.1.5", "node-cleanup": "^2.1.2", "node-gzip": "^1.1.2", "parse-duration": "^1.0.0", diff --git a/sites/i.mjh.nz/i.mjh.nz.config.js b/sites/i.mjh.nz/i.mjh.nz.config.js new file mode 100644 index 00000000..a58f4f16 --- /dev/null +++ b/sites/i.mjh.nz/i.mjh.nz.config.js @@ -0,0 +1,97 @@ +const dayjs = require('dayjs') +const axios = require('axios') +const parser = require('epg-parser') +const isBetween = require('dayjs/plugin/isBetween') +const customParseFormat = require('dayjs/plugin/customParseFormat') + +dayjs.extend(isBetween) +dayjs.extend(customParseFormat) + +module.exports = { + site: 'i.mjh.nz', + request: { + cache: { + ttl: 6 * 60 * 60 * 1000 // 6h + } + }, + url: function ({ channel }) { + const [source] = channel.site_id.split('#') + + return `https://raw.githubusercontent.com/matthuisman/i.mjh.nz/master/${source}.xml` + }, + parser: function ({ content, channel, date, cached }) { + let programs = [] + const items = parseItems(content, channel, date) + items.forEach(item => { + programs.push({ + title: parseTitle(item, channel), + description: parseDescription(item, channel), + category: parseCategory(item, channel), + start: parseStart(item), + stop: parseStop(item) + }) + }) + + return programs + }, + async channels({ service, region, lang = 'en' }) { + const data = await axios + .get(`https://i.mjh.nz/${service}/app.json`) + .then(r => r.data) + .catch(console.log) + + const channels = [] + const items = !region ? data.channels : data.regions[region].channels + region = region || 'all' + const path = `${service}/${region}` + for (let id in items) { + const channel = items[id] + channels.push({ + lang, + site_id: `${path}#${id}`, + name: channel.name + }) + } + + return channels + } +} + +function parseTitle(item, channel) { + return item.title.length ? item.title[0].value : null +} + +function parseDescription(item, channel) { + return item.desc.length ? item.desc[0].value : null +} + +function parseCategory(item, channel) { + const category = item.category.length ? item.category[0].value : '' + + return category.split(/\s\&\;\s/g).filter(c => c) +} + +function parseStart(item) { + return dayjs(item.start, 'YYYYMMDDHHmmss ZZ') +} + +function parseStop(item) { + return dayjs(item.stop, 'YYYYMMDDHHmmss ZZ') +} + +function parseItems(content, channel, date) { + try { + const curr_day = date + const next_day = date.add(1, 'd') + const [_, site_id] = channel.site_id.split('#') + const data = parser.parse(content) + if (!data || !Array.isArray(data.programs)) return [] + + return data.programs.filter( + p => + p.channel === site_id && dayjs(p.start, 'YYYYMMDDHHmmss ZZ').isBetween(curr_day, next_day) + ) + } catch (error) { + return [] + } +} diff --git a/sites/i.mjh.nz/i.mjh.nz.test.js b/sites/i.mjh.nz/i.mjh.nz.test.js new file mode 100644 index 00000000..eec79db1 --- /dev/null +++ b/sites/i.mjh.nz/i.mjh.nz.test.js @@ -0,0 +1,53 @@ +// npm run channels:parse -- --config=./sites/i.mjh.nz/i.mjh.nz.config.js --output=./sites/i.mjh.nz/i.mjh.nz_us-pluto.channels.xml --set=service:PlutoTV --set=region:us +// npm run channels:parse -- --config=./sites/i.mjh.nz/i.mjh.nz.config.js --output=./sites/i.mjh.nz/i.mjh.nz_us-stirr.channels.xml --set=service:Stirr +// npx epg-grabber --config=sites/i.mjh.nz/i.mjh.nz.config.js --channels=sites/i.mjh.nz/i.mjh.nz_us-pluto.channels.xml --output=guide.xml --days=2 +// npx epg-grabber --config=sites/i.mjh.nz/i.mjh.nz.config.js --channels=sites/i.mjh.nz/i.mjh.nz_us-stirr.channels.xml --output=guide.xml --days=2 + +const { parser, url } = require('./i.mjh.nz.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('2022-05-03', 'YYYY-MM-DD').startOf('d') +const channel = { + site_id: 'PlutoTV/us#51c75f7bb6f26ba1cd00002f', + xmltv_id: 'LittleStarsUniverse.us', + lang: 'en' +} + +it('can generate valid url', () => { + expect(url({ channel })).toBe( + 'https://raw.githubusercontent.com/matthuisman/i.mjh.nz/master/PlutoTV/us.xml' + ) +}) + +it('can parse response', () => { + const content = ` Little Stars Universe Barney and Friends Baby Bop forgets to say "please" and "thank you". Riff shares his dream of becoming an inventor. Children & Family Barney and Friends Baby Bop forgets to say "please" and "thank you". Riff shares his dream of becoming an inventor. Children & Family ` + const result = parser({ content, channel, date }).map(p => { + p.start = p.start.toJSON() + p.stop = p.stop.toJSON() + return p + }) + + expect(result).toMatchObject([ + { + start: '2022-05-03T10:49:22.000Z', + stop: '2022-05-03T11:21:22.000Z', + title: 'Barney and Friends', + description: + 'Baby Bop forgets to say "please" and "thank you". Riff shares his dream of becoming an inventor.', + category: ['Children', 'Family'] + } + ]) +}) + +it('can handle empty guide', () => { + const result = parser({ + content: `404: Not Found`, + channel, + date + }) + expect(result).toMatchObject([]) +}) diff --git a/sites/i.mjh.nz/i.mjh.nz_us-pluto.channels.xml b/sites/i.mjh.nz/i.mjh.nz_us-pluto.channels.xml new file mode 100644 index 00000000..23b6390b --- /dev/null +++ b/sites/i.mjh.nz/i.mjh.nz_us-pluto.channels.xml @@ -0,0 +1,334 @@ + + + + 48 Hours + 70s Cinema + 80s Rewind + 90210 + 90s Throwback + Acapulco Shore + All Reality by WE tv + Always Funny Videos + Amantes del romance + America's Test Kitchen + America's Voice News + Anime All Day + Antiques Roadshow UK + Antiques Road Trip + Awesomeness TV + Baby Shark TV + Badass novelas + Bar Rescue + Baywatch + BBC Food + BBC Home + BBC Kids + Bebecito Bum y sus amigos + beIN SPORTS XTRA en español + beIN SPORTS XTRA + Bellator MMA + Best of Dr. Phil + Best of The Drew Barrymore Show + BET Her + BET Pluto TV + Beverly Hillbillies + Black Cinema + Black Classics + Black Ink Crew + Black Throwbacks + Blaze Live + Bloomberg TV + BNC GO + Bounce XL + BritBox Mysteries + British Comedy + British Drama + BUZZR + Cats 24/7 + CBS News + CBS News Baltimore + CBS News Bay Area + CBS News Boston + CBS News Chicago + CBS News Colorado + CBS News DFW + CBS News Los Angeles + CBS News Miami + CBS News Minnesota + CBS News New York + CBS News Philly + CBS News Pittsburgh + CBS News Sacramento + CBS Sports HQ + Cheddar News + Cine adrenalina + Cine ¡¡jaja!! + Cine Premiere + Cine terror + Cine XOXO + Classica + Classic Movies Channel + Classic Toons TV + Classic TV Comedy + Classic TV Drama + Classic TV: Families + CMT Equal Play + CMT Pluto TV + CNN + Cold Case Files + Combate World + Comedy Central Animation + Comedy Central en español + Comedy Central Pluto TV + COPS + Court TV + Crime 360 + Crímenes imperfectos + CSI + CSI en español + Dabl + Dallas Cowboy Cheerleaders + Dark Shadows + Deal or No Deal + Degrassi + Demand Africa + Doctor Who Classic + Dogs 24/7 + Dog the Bounty Hunter + Dora TV + Emergencia 911 + Entre nosotras + Estrella News + EstrellaTV + ET Live + Euronews + FailArmy + Faith TV + Family Ties + Fear Factor + Fight + Find Out Why + Flicks of Fury + Foodies + Food TV + Forensic Files + Forever Kids + FOX Sports + Funny AF + Fuse Beat + G4 Select + Gameplay: Call of Duty + Gameplay: Fortnite + Gameplay: Roblox + Gameplay: Sports + Game Show Central + Garfield and Friends + GLORY Kickboxing + Gordon Ramsay's Hell's Kitchen + Grande-ish + Gunsmoke + Happy Days + Heartland + Hell's Kitchen en español + IGN + IMPACT Wrestling + Ink Master + Investiga + Iron Chef + Jersey Shore + Johnny Carson TV + Judge Nosey + Julia Child + Kartoon Channel! + K-Content by CJ ENM + Kevin Hart’s LOL! Network + Kids Movie Club + LEGO Kids TV + Little Baby Bum + Little Stars Universe + Lively Place + Live Music Replay + Logo Pluto TV + Love & Hip Hop + Lucha Libre AAA + Lupin the 3rd + Matlock + MAVTV Select + Midsomer Murders + MinecrafTV + Mi obsesión favorita + Mission Impossible + Misterios sin resolver + MLB + MLS + More TV Drama + More TV Sitcoms + MST3K + MTV Biggest Pop + MTV Block Party + MTV Dating + MTV en español + MTV Pluto TV + MTV Spankin' New + Mundo geek + Mundo paranormal + Mundo viajero + Narcos + Narcos en español + Naruto + Naruto en español + Naturescape + NBC News NOW + News 12 New York + Newsmax + Newsy + NFL Channel + Nick en español + Nick Jr. en español + Nick Jr. Pluto TV + Nick Pluto TV + Niños por BBC Kids + No Parents Allowed + Nosey + Nosey escándalos + Novelas con la abuela + Nuestra Visión + OAN Plus + One Piece + Paramount Movie Channel + Paramount+ Picks + PBR RidePass + Pelis y Popcorn + People Are Awesome + Perry Mason + PGA TOUR + Pluto TV Action + Pluto TV Action Sports + Pluto TV Animals + Pluto TV Backcountry + Pluto TV Best Life + Pluto TV Boxing + Pluto TV Cars + Pluto TV Celebrity + Pluto TV Comedy + Pluto TV Courtroom + Pluto TV Crime Drama + Pluto TV Crime Movies + Pluto TV Cult Films + Pluto TV Documentaries + Pluto TV Drama + Pluto TV Drama Life + Pluto TV Fantastic + Pluto TV Gamer + Pluto TV Game Shows + Pluto TV History + Pluto TV Home + Pluto TV Horror + Pluto TV Lives + Pluto TV Love Stories + Pluto TV Military + Pluto TV News + Pluto TV Paranormal + Pluto TV Pranks + Pluto TV Pro Wrestling + Pluto TV Reaction + Pluto TV Reality + Pluto TV Romance + Pluto TV Science + Pluto TV Sci-Fi + Pluto TV Soaps + Pluto TV Sports + Pluto TV Spotlight + Pluto TV Staff Picks + Pluto TV Suspense + Pluto TV Terror + Pluto TV Thrillers + Pluto TV Travel + Pluto TV True Crime + Pluto TV Vs. + Pluto TV Weddings + Pluto TV Westerns + pocket.watch + PokerGo + Rainbow Squad + Realmadrid tv + Rescue 911 + RiffTrax + Ryan and Friends + Sala de parejas + Séptimo arte + Series con Ñ + Shout! Factory TV + Showtime Selects + Skills + Thrills + Sky News + Slightly Off IFC + Slow TV + Smithsonian Channel Selects + Sony Canal Comedias + Sony Canal Escape Perfecto + Spike ¡extremo! + Spike Outdoors + Spike Pluto TV + Stand-Up TV + Star Trek + Stories by AMC + Survivor + TBN + Team Spirit + Teen Mom + Telefe noticias + Telemundo telenovelas clásicas + The Addams Family + The Amazing Race + The Andy Griffith Show + The Asylum + The Bob Ross Channel + The Carol Burnett Show + The Challenge + The Design Network + The First + The Love Boat + The New Detectives + The Pet Collective + The Price Is Right: The Barker Era + The Rifleman + The Walking Dead en español + This Old House + Three's Company + Tiny House Nation + TODAY All Day + TokuSHOUTsu + Top Gear en español + Tosh.0 + TOTALLY TURTLES + TV Land Drama + TV Land Sitcoms + TYT Network + Unsolved Mysteries + Vevo 2K + Vevo '70s + Vevo '80s + Vevo '90s + Vevo Country + Vevo Latino + Vevo Pop + Vevo R&B + Vevo Reggaetón & Trap + Vevo Retro Rock + Vevo True School Hip-Hop + VH1 Hip Hop Family + VH1 I Love Reality + Viaje a las estrellas + Voyager Documentaries + Wanted: Dead or Alive + WeatherNation + Western TV + Wild 'N Out + World Poker Tour + Yahoo Finance + Yo! MTV + Yu-Gi-Oh! + Yu-Gi-Oh! en español + +