From 70e37c6760906d43aba65adb7e5f310e84eda16a Mon Sep 17 00:00:00 2001 From: Toha Date: Sat, 14 Dec 2024 23:36:26 +0700 Subject: [PATCH] Update virgintvgo.virginmedia.com guide. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: ```sh npm test -- virgintvgo.virginmedia.com > test > run-script-os virgintvgo.virginmedia.com > test:win32 > SET "TZ=Pacific/Nauru" && npx jest --runInBand virgintvgo.virginmedia.com PASS sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js √ can generate valid url (3 ms) √ can parse response (1028 ms) √ can handle empty guide (1 ms) Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 0 total Time: 4.181 s, estimated 5 s Ran all test suites matching /virgintvgo.virginmedia.com/i. ``` Grab: ```sh npm run grab -- --site=virgintvgo.virginmedia.com > grab > npx tsx scripts/commands/epg/grab.ts --site=virgintvgo.virginmedia.com starting... config: output: guide.xml maxConnections: 1 gzip: false site: virgintvgo.virginmedia.com loading channels... found 238 channel(s) run #1: [1/476] virgintvgo.virginmedia.com (en) - 138 - Dec 14, 2024 (8 programs) [2/476] virgintvgo.virginmedia.com (en) - 138 - Dec 15, 2024 (8 programs) ... [475/476] virgintvgo.virginmedia.com (en) - 195 - Dec 15, 2024 (39 programs) [476/476] virgintvgo.virginmedia.com (en) - 195 - Dec 14, 2024 (40 programs) saving to "guide.xml"... done in 00h 08m 57s ``` Signed-off-by: Toha --- .../__data__/content00.json | 113 +++++++++ .../__data__/content06.json | 63 +++++ .../__data__/content12.json | 149 +++++++++++ .../__data__/content18.json | 164 ++++++++++++ .../__data__/program01.json | 1 + .../__data__/program02.json | 1 + .../__data__/program03.json | 1 + .../virgintvgo.virginmedia.com.channels.xml | 97 +++---- .../virgintvgo.virginmedia.com.config.js | 238 +++++++++++------- .../virgintvgo.virginmedia.com.test.js | 198 ++++++--------- 10 files changed, 761 insertions(+), 264 deletions(-) create mode 100644 sites/virgintvgo.virginmedia.com/__data__/content00.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/content06.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/content12.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/content18.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/program01.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/program02.json create mode 100644 sites/virgintvgo.virginmedia.com/__data__/program03.json diff --git a/sites/virgintvgo.virginmedia.com/__data__/content00.json b/sites/virgintvgo.virginmedia.com/__data__/content00.json new file mode 100644 index 00000000..90d8a1b8 --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/content00.json @@ -0,0 +1,113 @@ +{ + "duration": 21600, + "entries": [ + { + "channelId": "1958", + "events": [ + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734138300, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16647964~~2FEP012911720228,imi:74a552c465e11e5fe6ed7bfae7aeda5b639322ff", + "mergedId": "8162912|en-GB", + "replayTVDisplayAge": true, + "replayTVMinAge": 1, + "seriesPremiereAirings": true, + "startTime": 1734134400, + "title": "Police Interceptors" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734141900, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F17641069~~2FEP026460800059,imi:23c363d12af79f43134f4a15b96dd12df81b19ab", + "mergedId": "13941739|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734141900, + "replayTVMinAge": 18, + "seriesName": "Nature's Fury", + "seriesPremiereAirings": true, + "startTime": 1734138300, + "title": "The World's Deadliest Weather" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734145500, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F26563001~~2FEP029624800129,imi:9ebff440ff12444a3993e8d64d29782c0964d61c", + "mergedId": "15480970|en-GB", + "replayTVDisplayAge": true, + "replayTVMinAge": 18, + "seriesPremiereAirings": true, + "startTime": 1734141900, + "title": "Trucking Hell" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734148500, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F26605411~~2FEP029624800130,imi:df63b394ca3f7d29124997f022629734d4e0efa0", + "mergedId": "15480970|en-GB", + "replayTVDisplayAge": true, + "replayTVMinAge": 1, + "seriesPremiereAirings": true, + "startTime": 1734145500, + "title": "Trucking Hell" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734148800, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F331597493,imi:6611f51efe08e063237b04cc32824d34fcd4cc13", + "isPlaceHolder": true, + "mergedId": "19221598|en-GB", + "replayAvailabilityEnd": 1734148800, + "replayTVMinAge": 18, + "startTime": 1734148500, + "title": "Entertainment News On 5" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734172200, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F501178~~2FSH012613290000~~2F331597494,imi:7509d470dc1ea76c2dd793aca0aa6762bd661724", + "isPlaceHolder": true, + "mergedId": "501178|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734172200, + "replayTVMinAge": 18, + "startTime": 1734148800, + "title": "Teleshopping" + } + ] + } + ], + "time": 1734134400 +} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/content06.json b/sites/virgintvgo.virginmedia.com/__data__/content06.json new file mode 100644 index 00000000..1be6c19e --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/content06.json @@ -0,0 +1,63 @@ +{ + "duration": 21600, + "entries": [ + { + "channelId": "1958", + "events": [ + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734172200, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F501178~~2FSH012613290000~~2F331597494,imi:7509d470dc1ea76c2dd793aca0aa6762bd661724", + "isPlaceHolder": true, + "mergedId": "501178|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734172200, + "replayTVMinAge": 18, + "startTime": 1734148800, + "title": "Teleshopping" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734176100, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16244933~~2FEP012911720221,imi:fd3eb460d4a3e60c13565fc88c6857b5d812e710", + "mergedId": "8162912|en-GB", + "replayAvailabilityEnd": 1734176100, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734172200, + "title": "Police Interceptors" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734179700, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16298951~~2FEP012911720224,imi:36a6bdc9c192673d8205be38402082c4770c34ab", + "mergedId": "8162912|en-GB", + "replayAvailabilityEnd": 1734179700, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734176100, + "title": "Police Interceptors" + } + ] + } + ], + "time": 1734156000 +} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/content12.json b/sites/virgintvgo.virginmedia.com/__data__/content12.json new file mode 100644 index 00000000..7c9df2ca --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/content12.json @@ -0,0 +1,149 @@ +{ + "duration": 21600, + "entries": [ + { + "channelId": "1958", + "events": [ + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734179700, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16298951~~2FEP012911720224,imi:36a6bdc9c192673d8205be38402082c4770c34ab", + "mergedId": "8162912|en-GB", + "replayAvailabilityEnd": 1734179700, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734176100, + "title": "Police Interceptors" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734183300, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16458103~~2FEP012911720227,imi:a12a943b19f4f3e587ca3d75d36cfb3b3cc73bb5", + "mergedId": "8162912|en-GB", + "replayAvailabilityEnd": 1734183300, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734179700, + "title": "Police Interceptors" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734186900, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F16701376~~2FEP012911720230,imi:911091e999d0162bcffddeb766ab0dcf76cad914", + "mergedId": "8162912|en-GB", + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734183300, + "title": "Police Interceptors" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734190500, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F22539437~~2FEP037839440009,imi:081aafd95b4518fa310a5a93914d4450f22f9a85", + "mergedId": "19579687|en-GB", + "replayAvailabilityEnd": 1734190500, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734186900, + "title": "Motorway Cops: Catching Britain's Speeders" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734194100, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F23046341~~2FEP037839440020,imi:9a632e03121f5f2567112c9f331e5ea96f64d6d4", + "mergedId": "19579687|en-GB", + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734190500, + "title": "Motorway Cops: Catching Britain's Speeders" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734197700, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F1,imi:191d69d4592b3a45a562ec1f90538654ba84677f", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F1,imi:191d69d4592b3a45a562ec1f90538654ba84677f", + "isSplitProgram": true, + "mergedId": "40090|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734201900, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734194100, + "title": "Only the Valiant" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734198000, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458683,imi:b201e2acaa94b189ae5d0d16924f64ab655f6c59", + "isPlaceHolder": true, + "mergedId": "19221598|en-GB", + "replayAvailabilityEnd": 1734198000, + "replayTVMinAge": 11, + "startTime": 1734197700, + "title": "Entertainment News On 5" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734201900, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F1,imi:191d69d4592b3a45a562ec1f90538654ba84677f", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F2,imi:c2e77e3715d7c38ff731362396170d60217ad33c", + "isSplitProgram": true, + "mergedId": "40090|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734201900, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734198000, + "title": "Only the Valiant" + } + ] + } + ], + "time": 1734177600 +} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/content18.json b/sites/virgintvgo.virginmedia.com/__data__/content18.json new file mode 100644 index 00000000..e2cbe06c --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/content18.json @@ -0,0 +1,164 @@ +{ + "duration": 21600, + "entries": [ + { + "channelId": "1958", + "events": [ + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734201900, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F1,imi:191d69d4592b3a45a562ec1f90538654ba84677f", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F40090~~2FMV002875650000~~2F2,imi:c2e77e3715d7c38ff731362396170d60217ad33c", + "isSplitProgram": true, + "mergedId": "40090|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734201900, + "replayTVMinAge": 11, + "seriesPremiereAirings": true, + "startTime": 1734198000, + "title": "Only the Valiant" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734205500, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F929~~2FMV002830000000~~2F1,imi:6f2c2d72750b45c524cac1e1d53cfdc0051c181c", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F929~~2FMV002830000000~~2F1,imi:6f2c2d72750b45c524cac1e1d53cfdc0051c181c", + "isSplitProgram": true, + "mergedId": "929|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734210000, + "replayTVMinAge": 17, + "seriesPremiereAirings": true, + "startTime": 1734201900, + "title": "To Hell and Back" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734205800, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458686,imi:78793423aa26556f0ec844555e3b78dbbcbdf03b", + "isPlaceHolder": true, + "mergedId": "19221598|en-GB", + "replayAvailabilityEnd": 1734205800, + "replayTVMinAge": 11, + "startTime": 1734205500, + "title": "Entertainment News On 5" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734210000, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F929~~2FMV002830000000~~2F1,imi:6f2c2d72750b45c524cac1e1d53cfdc0051c181c", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F929~~2FMV002830000000~~2F2,imi:ab2cc90e1d3db134491071becead8fac20647462", + "isSplitProgram": true, + "mergedId": "929|en-GB", + "minimumAge": 8, + "replayAvailabilityEnd": 1734210000, + "replayTVMinAge": 17, + "seriesPremiereAirings": true, + "startTime": 1734205800, + "title": "To Hell and Back" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734213600, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F10472594~~2FMV005894740000~~2F1,imi:f0521c14c6a7454a7aa6a82829dd725cc1df5904", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F10472594~~2FMV005894740000~~2F1,imi:f0521c14c6a7454a7aa6a82829dd725cc1df5904", + "isSplitProgram": true, + "mergedId": "10472594|en-GB", + "minimumAge": 12, + "replayAvailabilityEnd": 1734217200, + "replayTVMinAge": 18, + "seriesPremiereAirings": true, + "startTime": 1734210000, + "title": "Hercules" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734213900, + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458689,imi:f1060b3f63cd5399e0f97901b25a85ef71097891", + "isPlaceHolder": true, + "mergedId": "19221598|en-GB", + "replayAvailabilityEnd": 1734213900, + "replayTVMinAge": 18, + "startTime": 1734213600, + "title": "Entertainment News On 5" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734217200, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F10472594~~2FMV005894740000~~2F1,imi:f0521c14c6a7454a7aa6a82829dd725cc1df5904", + "hasReplayTV": false, + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F10472594~~2FMV005894740000~~2F2,imi:b3168c256ad617858f87f9d985e4e8f96cbf8b2d", + "isSplitProgram": true, + "mergedId": "10472594|en-GB", + "minimumAge": 12, + "replayAvailabilityEnd": 1734217200, + "replayTVMinAge": 18, + "seriesPremiereAirings": true, + "startTime": 1734213900, + "title": "Hercules" + }, + { + "audioLanguages": [ + { + "lang": "en" + } + ], + "endTime": 1734220800, + "groupedEventIdFirstPart": "crid:~~2F~~2Fgn.tv~~2F4090~~2FMV002844310000~~2F1,imi:4a7646f51afdd15601ff31255af60c673c7f871b", + "hasReplayTVOTT": false, + "id": "crid:~~2F~~2Fgn.tv~~2F4090~~2FMV002844310000~~2F1,imi:4a7646f51afdd15601ff31255af60c673c7f871b", + "isSplitProgram": true, + "mergedId": "4090|en-GB", + "minimumAge": 18, + "replayAvailabilityEnd": 1735592553, + "replayTVMinAge": 18, + "seriesPremiereAirings": true, + "startTime": 1734217200, + "title": "Raw Deal" + } + ] + } + ], + "time": 1734199200 +} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/program01.json b/sites/virgintvgo.virginmedia.com/__data__/program01.json new file mode 100644 index 00000000..030f8b67 --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/program01.json @@ -0,0 +1 @@ +{"imageVersion":"HOwBfQ","eventId":"crid:~~2F~~2Fgn.tv~~2F16647964~~2FEP012911720228,imi:74a552c465e11e5fe6ed7bfae7aeda5b639322ff","channelId":"1958","title":"Police Interceptors","startTime":1734134400,"endTime":1734138300,"mergedId":"8162912|en-GB","replayTvMinAge":1,"seriesId":"crid:~~2F~~2Fgn.tv~~2F16647963~~2FSH012911720000","parentSeriesId":"crid:~~2F~~2Fgn.tv~~2F8162912~~2FSH012911720000","seasonNumber":16,"episodeNumber":1,"shortDescription":"Eight police cars and the eye in the sky hunt down a high powered Porsche Cayenne that is causing carnage. Undertaking at high speeds and goading the interceptors, the driver even manages to take out several police cars.","longDescription":"Eight police cars and the eye in the sky hunt down a high powered Porsche Cayenne that is causing carnage. Undertaking at high speeds and goading the interceptors, the driver even manages to take out several police cars.","directors":["John Everett"],"producers":["Gerry Melling","John Everett"],"audioLanguages":[{"lang":"en"}],"captionLanguages":[{"lang":"en"}],"productionDate":"2019","countryOfOrigin":"GB","genres":["Reality","Crime"],"replayTVDisplayAge":true,"hasReplayTVOTT":false,"seriesPremiereAirings":true} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/program02.json b/sites/virgintvgo.virginmedia.com/__data__/program02.json new file mode 100644 index 00000000..d2c920eb --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/program02.json @@ -0,0 +1 @@ +{"imageVersion":"cx_ZhA","eventId":"crid:~~2F~~2Fgn.tv~~2F17641069~~2FEP026460800059,imi:23c363d12af79f43134f4a15b96dd12df81b19ab","channelId":"1958","title":"The World's Deadliest Weather","startTime":1734138300,"endTime":1734141900,"mergedId":"13941739|en-GB","minimumAge":"8","replayTvMinAge":18,"seriesId":"crid:~~2F~~2Fgn.tv~~2F17641060~~2FSH026460800000","parentSeriesId":"crid:~~2F~~2Fgn.tv~~2F13941739~~2FSH026460800000","episodeName":"Nature's Fury","seasonNumber":3,"episodeNumber":2,"hasReplayTV":false,"replayAvailabilityEnd":1734141900,"strictAvailabilityEnd":1734141900,"shortDescription":"Hurricane Florence brings biblical flooding to North Carolina, a magnitude 7 earthquake rocks Alaska, and a surfer crashes in Nazare's colossal waves.","longDescription":"Hurricane Florence brings biblical flooding to North Carolina, a magnitude 7 earthquake rocks Alaska, and a surfer crashes in Nazare's colossal waves.","directors":["Edmond Buckley"],"producers":["David Notman-Watt","Ed Kellie"],"audioLanguages":[{"lang":"en"}],"productionDate":"2020","countryOfOrigin":"GB","genres":["Documentary","Weather"],"hasReplayTVOTT":false,"seriesPremiereAirings":true} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/__data__/program03.json b/sites/virgintvgo.virginmedia.com/__data__/program03.json new file mode 100644 index 00000000..6bd620fc --- /dev/null +++ b/sites/virgintvgo.virginmedia.com/__data__/program03.json @@ -0,0 +1 @@ +{"imageVersion":"B4hC4A","eventId":"crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458689,imi:f1060b3f63cd5399e0f97901b25a85ef71097891","channelId":"1958","title":"Entertainment News On 5","startTime":1734213600,"endTime":1734213900,"mergedId":"19221598|en-GB","replayTvMinAge":18,"seriesId":"crid:~~2F~~2Fgn.tv~~2F123456789~~2FSH037146530000","parentSeriesId":"crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000","seasonNumber":46530000,"episodeNumber":333458689,"hasReplayTV":false,"replayAvailabilityEnd":1734213900,"strictAvailabilityEnd":1734213900,"shortDescription":"A daily round-up of showbiz news and gossip from around the world, focusing on celebrities, movies, music and entertainment.","longDescription":"A daily round-up of showbiz news and gossip from around the world, focusing on celebrities, movies, music and entertainment.","actors":["Jamie Burton"],"producers":["Rubina Pabani"],"audioLanguages":[{"lang":"en"}],"captionLanguages":[{"lang":"en"}],"countryOfOrigin":"GB","genres":["News","Entertainment"],"hasReplayTVOTT":false,"allowLDVR":false,"allowNDVR":false,"isPlaceholder":true} \ No newline at end of file diff --git a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.channels.xml b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.channels.xml index e09d84e7..bdaa5f0e 100644 --- a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.channels.xml +++ b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.channels.xml @@ -1,18 +1,34 @@ - Nick Jr PAW Patrol Virgin TV Highlights + TRUE CRIME + Store + Sky Sports Main Event + Sky Sports Cricket + Sky Sports NFL + Sky Sports Golf + Ideal World + Nick Jr Too MTV Live HD COLORS HD + Sky Sports Darts I.D.+1 LEGEND XTRA +1 - TRUE CRIME - SkySportsMainEventUHD + Sky Sports PL + Sky Sports + + Sky Sports Football + Channel Update + Sky SportMainEventUHD Sky Sports Ultra HD 1 - Sky Sports F1 UHD + Sky Sports Darts UHD Sky Sports Ultra HD 2 - Store - 4 Music + Sky Sports Tennis + Sky Sports Tennis HD + HobbyMaker HD + NOW XMAS + Zee Punjabi + CNN HD + That's TV2 4SevenHD 5ACTION HD 5Select @@ -20,8 +36,8 @@ 5STAR +1 5 USA 5 USA +1 - alibi HD - alibi +1 + U&Alibi HD + U&Alibi+1 Al Jazeera Arabic Al Jazeera English Animal Planet HD @@ -65,11 +81,10 @@ Comedy Central Extra Comedy Central HD Comedy Central +1 - Create & Craft Crime+Inv HD Crime+Inv +1 - Dave HD - Dave ja vu + U&Dave HD + U&DaveJaVu Discovery HD Discovery Chan +1 Discovery History @@ -79,14 +94,13 @@ Discovery Turbo DMAX DMAX + 1 - Drama HD - Drama +1 + U&Drama HD + U&Drama +1 E4 Extra E4 HD E4 +1 - Eden HD - Eden +1 - E! HD + U&Eden HD + U&Eden +1 euronews Eurosport 1HD Eurosport 2HD @@ -97,11 +111,11 @@ GB News Gems TV GOD TV - GOLD HD - GOLD +1 + U&GOLD HD + U&GOLD+1 GREAT! action GREAT! movies - GREAT! christmas + GREAT! Christmas GREAT! tv HGTV HGTV +1 @@ -119,12 +133,9 @@ ITV4 +1 ITVBe HD ITVBe +1 - Kerrang - Kiss LEGEND Liverpool FC TV London Live - Magic More 4 HD More 4 +1 Christmas 24 @@ -138,15 +149,13 @@ National GeographicHD National Geographic+1 Nat Geo WILD HD - NBC News Now - NDTV 24x7 - NDTV Good Times + NDTV World NHK World-Japan Nick HD Nick +1 - Nick Junior - Nick SpongeBob - NOW XMAS + Nick Jr. HD + Nicktoons + NOW 70s NOW 80s NOW ROCK PBS America @@ -166,13 +175,13 @@ Sky Action HD Sky Animation HD Sky Comedy HD - Sky Christmas HD - Sky Family HD - Sky Favourites HD - Sky Hits HD + Sky Christmas + Sky Kids Books + Sky Favourites + Sky Cinema 90s Sky Premiere HD Sky SciFi & Hor HD - Sky Best of 2023 HD + Sky Best of 2024 Sky Thriller HD Sky Comedy HD Sky Crime HD @@ -189,9 +198,9 @@ Sky Replay Sky Sci-Fi HD Sky Showcase HD - Sky Sports Arena HD + Sky Sports + HD Sky Sports Cricket HD - Sky Sports F1 HD + Sky Sports Darts HD Sky Sports FootballHD Sky Sports Golf HD Sky SportsMainEventHD @@ -207,11 +216,8 @@ SONY MAX HD SONY SAB Talking Pictures - Talk TV - That's 60s + That's Christmas That's TV - Box Christmas - Tiny Pop TJC HD TLC HD TLC+1 @@ -224,13 +230,12 @@ Utsav Bharat Utsav Gold HD Utsav Plus HD - Viaplay Sports 1 - Viaplay Sports 2 - Viaplay Xtra - W HD - W +1 - YESTERDAY HD - YESTERDAY +1 + Premier Sports 1 + Premier Sports 2 + U&W HD + U&W +1 + U&Yesterday HD + U&Yesterday +1 Zee Cinema HD Zee TV HD diff --git a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js index e9be8665..75cc2fcd 100644 --- a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js +++ b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.config.js @@ -1,117 +1,175 @@ -const axios = require('axios') const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const debug = require('debug')('site:virgintvgo.virginmedia.com') -const API_ENDPOINT = 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web' +dayjs.extend(utc) + +const detailedGuide = true +const nworker = 25 module.exports = { site: 'virgintvgo.virginmedia.com', days: 2, request: { cache: { - ttl: 60 * 60 * 1000 // 1 hour + ttl: 24 * 60 * 60 * 1000 // 1 day } }, - url: function ({ date }) { - return `${API_ENDPOINT}/programschedules/${date.format('YYYYMMDD')}/1` + url({ date, segment = 0 }) { + return `https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/${ + date.format('YYYYMMDD') + }${ + segment.toString().padStart(2, '0') + }0000` }, async parser({ content, channel, date }) { - let programs = [] - let items = parseItems(content, channel) - if (!items.length) return programs - const d = date.format('YYYYMMDD') - const promises = [ - axios.get(`${API_ENDPOINT}/programschedules/${d}/2`), - axios.get(`${API_ENDPOINT}/programschedules/${d}/3`), - axios.get(`${API_ENDPOINT}/programschedules/${d}/4`) - ] - await Promise.allSettled(promises) - .then(results => { - results.forEach(r => { - if (r.status === 'fulfilled') { - items = items.concat(parseItems(r.value.data, channel)) + const programs = [] + if (content) { + const items = typeof content === 'string' ? JSON.parse(content) : content + if (Array.isArray(items.entries)) { + // fetch other segments + const queues = [ + module.exports.url({ date, segment: 6}), + module.exports.url({ date, segment: 12}), + module.exports.url({ date, segment: 18}), + ] + await doFetch(queues, (url, res) => { + if (Array.isArray(res.entries)) { + items.entries.push(...res.entries) } }) - }) - .catch(console.error) - // items.forEach(item => { - for (let item of items) { - const detail = await loadProgramDetails(item) - programs.push({ - title: item.t, - description: parseDescription(detail), - category: parseCategory(detail), - season: parseSeason(detail), - episode: parseEpisode(detail), - start: parseStart(item), - stop: parseStop(item) - }) + items.entries + .filter(item => item.channelId === channel.site_id) + .forEach(item => { + if (Array.isArray(item.events)){ + if (detailedGuide) { + queues.push(...item.events + .map(event => + `https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/${ + event.id + }?returnLinearContent=true&forceLinearResponse=true&language=en` + ) + ) + } else { + item.events.forEach(event => { + programs.push({ + title: event.title, + start: dayjs.utc(event.startTime * 1000), + stop: dayjs.utc(event.endTime * 1000) + }) + }) + } + } + }) + // fetch detailed guide + if (queues.length) { + await doFetch(queues, (url, res) => { + programs.push({ + title: res.title, + subTitle: res.episodeName, + description: res.longDescription ? res.longDescription : res.shortDescription, + category: res.genres, + season: res.seasonNumber, + episode: res.episodeNumber, + country: res.countryOfOrigin, + actor: res.actors, + director: res.directors, + producer: res.producers, + date: res.productionDate, + start: dayjs.utc(res.startTime * 1000), + stop: dayjs.utc(res.endTime * 1000) + }) + }) + } + } } - //) return programs }, async channels() { - const data = await axios - .get(`${API_ENDPOINT}/channels`) + const channels = [] + const axios = require('axios') + const res = await axios + .get('https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/channels?cityId=40980&language=en&productClass=Orion-DASH&platform=web') .then(r => r.data) - .catch(console.log) + .catch(console.error) - return data.channels.map(item => { - return { - lang: 'en', - site_id: item.id.replace('lgi-gb-prodobo-master:40980-', ''), - name: item.title - } - }) + if (Array.isArray(res)) { + channels.push(...res + .filter(item => !item.isHidden) + .map(item => { + return { + lang: 'en', + site_id: item.id, + name: item.name + } + }) + ) + } + + return channels } } -async function loadProgramDetails(item) { - if (!item.i) return {} - const url = `${API_ENDPOINT}/listings/${item.i}` - const data = await axios - .get(url) - .then(r => r.data) - .catch(console.log) - return data || {} -} +async function doFetch(queues, cb) { + const axios = require('axios') -function parseStart(item) { - return dayjs(item.s) -} - -function parseStop(item) { - return dayjs(item.e) -} - -function parseItems(content, channel) { - const data = typeof content === 'string' ? JSON.parse(content) : content - if (!data || !Array.isArray(data.entries)) return [] - const entity = data.entries.find(e => e.o === `lgi-gb-prodobo-master:${channel.site_id}`) - - return entity ? entity.l : [] -} - -function parseDescription(detail) { - return detail.program.longDescription || null -} - -function parseCategory(detail) { - let categories = [] - detail.program.categories.forEach(category => { - categories.push(category.title) + let n = Math.min(nworker, queues.length) + const workers = [] + const adjustWorker = () => { + if (queues.length > workers.length && workers.length < nworker) { + let nw = Math.min(nworker, queues.length) + if (n < nw) { + n = nw + createWorker() + } + } + } + const createWorker = () => { + while (workers.length < n) { + startWorker() + } + } + const startWorker = () => { + const worker = () => { + if (queues.length) { + const queue = queues.shift() + const done = res => { + if (res) { + cb(queue, res) + adjustWorker() + } + worker() + } + const url = typeof queue === 'string' ? queue : queue.u + const params = typeof queue === 'object' && queue.params ? queue.params : {} + const method = typeof queue === 'object' && queue.m ? queue.m : 'get' + debug(`fetch %s with %s`, url, JSON.stringify(params)) + if (method === 'post') { + axios + .post(url, params) + .then(response => done(response.data)) + .catch(console.error) + } else { + axios + .get(url, params) + .then(response => done(response.data)) + .catch(console.error) + } + } else { + workers.splice(workers.indexOf(worker), 1) + } + } + workers.push(worker) + worker() + } + createWorker() + await new Promise(resolve => { + const interval = setInterval(() => { + if (workers.length === 0) { + clearInterval(interval) + resolve() + } + }, 500) }) - return categories -} - -function parseSeason(detail) { - if (!detail.program.seriesNumber) return null - if (String(detail.program.seriesNumber).length > 2) return null - return detail.program.seriesNumber -} - -function parseEpisode(detail) { - if (!detail.program.seriesEpisodeNumber) return null - if (String(detail.program.seriesEpisodeNumber).length > 3) return null - return detail.program.seriesEpisodeNumber } diff --git a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js index fe6b2efd..d2213198 100644 --- a/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js +++ b/sites/virgintvgo.virginmedia.com/virgintvgo.virginmedia.com.test.js @@ -1,153 +1,95 @@ const { parser, url } = require('./virgintvgo.virginmedia.com.config.js') +const fs = require('fs') +const path = require('path') const axios = require('axios') const dayjs = require('dayjs') const utc = require('dayjs/plugin/utc') const customParseFormat = require('dayjs/plugin/customParseFormat') + dayjs.extend(customParseFormat) dayjs.extend(utc) jest.mock('axios') -const date = dayjs.utc('2022-03-17', 'YYYY-MM-DD').startOf('d') +const date = dayjs.utc('2024-12-14', 'YYYY-MM-DD').startOf('d') const channel = { - site_id: '1761', - xmltv_id: 'ViaplaySports1.uk' + site_id: '1958', + xmltv_id: '5ActionHD.uk' } +axios.get.mockImplementation(url => { + const urls = { + 'https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/20241214000000': + 'content00.json', + 'https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/20241214060000': + 'content06.json', + 'https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/20241214120000': + 'content12.json', + 'https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/20241214180000': + 'content18.json', + 'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F16647964~~2FEP012911720228,imi:74a552c465e11e5fe6ed7bfae7aeda5b639322ff?returnLinearContent=true&forceLinearResponse=true&language=en': + 'program01.json', + 'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F17641069~~2FEP026460800059,imi:23c363d12af79f43134f4a15b96dd12df81b19ab?returnLinearContent=true&forceLinearResponse=true&language=en': + 'program02.json', + 'https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/linear-service/v2/replayEvent/crid:~~2F~~2Fgn.tv~~2F19221598~~2FSH037146530000~~2F333458689,imi:f1060b3f63cd5399e0f97901b25a85ef71097891?returnLinearContent=true&forceLinearResponse=true&language=en': + 'program03.json', + } + let data = '' + if (urls[url] !== undefined) { + data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString() + if (!urls[url].startsWith('content00')) { + data = JSON.parse(data) + } + } + return Promise.resolve({ data }) +}) + it('can generate valid url', () => { expect(url({ date })).toBe( - 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/programschedules/20220317/1' + 'https://staticqbr-prod-gb.gnp.cloud.virgintvgo.virginmedia.com/eng/web/epg-service-lite/gb/en/events/segments/20241214000000' ) }) -it('can parse response', done => { - const content = - '{"entryCount":410,"totalResults":410,"updated":1647459686755,"expires":1647460298218,"title":"EPG","periods":4,"periodStartTime":1647475200000,"periodEndTime":1647496800000,"entries":[{"o":"lgi-gb-prodobo-master:1761","l":[{"i":"crid:~~2F~~2Fgn.tv~~2F21763419~~2FEP013520125005,imi:de610af9a9b049c8a0245173f273136d36458f6f","t":"Live: NHL Hockey","s":1647473400000,"e":1647484200000,"c":"lgi-gb-prodobo-master:genre-27","a":false,"r":true,"rm":true,"rs":0,"re":2592000,"rst":"cloud","ra":false,"ad":[],"sl":[]}]}]}' - - axios.get.mockImplementation(url => { - if ( - url === 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/programschedules/20220317/2' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"entryCount":410,"totalResults":410,"updated":1647460887411,"expires":1647461895572,"title":"EPG","periods":4,"periodStartTime":1647496800000,"periodEndTime":1647518400000,"entries":[{"o":"lgi-gb-prodobo-master:1761","l":[{"i":"crid:~~2F~~2Fgn.tv~~2F21720572~~2FEP021779870005,imi:d4324f579ad36992f0c3f6e6d35a9b93e98cb78a","t":"Challenge Cup Ice Hockey","s":1647484200000,"e":1647496800000,"c":"lgi-gb-prodobo-master:genre-123","a":false,"r":true,"rm":true,"rs":0,"re":2592000,"rst":"cloud","ra":false,"ad":[],"sl":[]}]}]}' - ) - }) - } else if ( - url === 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/programschedules/20220317/3' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"entryCount":410,"totalResults":410,"updated":1647460871713,"expires":1647461910282,"title":"EPG","periods":4,"periodStartTime":1647518400000,"periodEndTime":1647540000000,"entries":[{"o":"lgi-gb-prodobo-master:1761","l":[{"i":"crid:~~2F~~2Fgn.tv~~2F21763550~~2FEP012830215435,imi:9692f5ceb0b63354262339e8529e3a9cb57add9c","t":"NHL Hockey","s":1647511200000,"e":1647518400000,"c":"lgi-gb-prodobo-master:genre-27","a":false,"r":true,"rm":true,"rs":0,"re":2592000,"rst":"cloud","ra":false,"ad":[],"sl":[]}]}]}' - ) - }) - } else if ( - url === 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/programschedules/20220317/4' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"entryCount":410,"totalResults":410,"updated":1647460871713,"expires":1647461920720,"title":"EPG","periods":4,"periodStartTime":1647540000000,"periodEndTime":1647561600000,"entries":[{"o":"lgi-gb-prodobo-master:1761","l":[{"i":"crid:~~2F~~2Fgn.tv~~2F21764379~~2FEP025886890145,imi:c02da14358110cec07d14dc154717ce62ba2f489","t":"Boxing World Weekly","s":1647539100000,"e":1647540900000,"c":"lgi-gb-prodobo-master:genre-27","a":false,"r":true,"rm":true,"rs":0,"re":2592000,"rst":"cloud","ra":false,"ad":[],"sl":[]}]}]}' - ) - }) - } else if ( - url === - 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/listings/crid:~~2F~~2Fgn.tv~~2F21763419~~2FEP013520125005,imi:de610af9a9b049c8a0245173f273136d36458f6f' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"id":"crid:~~2F~~2Fgn.tv~~2F21763419~~2FEP013520125005,imi:de610af9a9b049c8a0245173f273136d36458f6f","startTime":1647473400000,"endTime":1647484200000,"actualStartTime":1647473400000,"actualEndTime":1647484200000,"expirationDate":1648078200000,"stationId":"lgi-gb-prodobo-master:1761","imi":"imi:de610af9a9b049c8a0245173f273136d36458f6f","scCridImi":"crid:~~2F~~2Fgn.tv~~2F21763419~~2FEP013520125005,imi:de610af9a9b049c8a0245173f273136d36458f6f","mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F8396306~~2FSH013520120000","program":{"id":"crid:~~2F~~2Fgn.tv~~2F21763419~~2FEP013520125005","title":"Live: NHL Hockey","description":"The Boston Bruins make the trip to Xcel Energy Center for an NHL clash with the Minnesota Wild.","longDescription":"The Boston Bruins make the trip to Xcel Energy Center for an NHL clash with the Minnesota Wild.","medium":"TV","categories":[{"id":"lgi-gb-prodobo-master:genre-27","title":"Sport","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"},{"id":"lgi-gb-prodobo-master:genre-123","title":"Ice Hockey","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"}],"isAdult":false,"cast":[],"directors":[],"images":[{"assetType":"HighResLandscapeProductionStill","assetTypes":["HighResLandscapeProductionStill"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p21763419_tb2_h8_aa.jpg"},{"assetType":"HighResPortrait","assetTypes":["HighResPortrait"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p21763419_tb2_v12_aa.jpg"}],"parentId":"crid:~~2F~~2Fgn.tv~~2F123456789~~2FSH013520120000","rootId":"crid:~~2F~~2Fgn.tv~~2F8396306~~2FSH013520120000","parentalRatingDescription":[],"resolutions":[],"mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F8396306~~2FSH013520120000","shortDescription":"The Boston Bruins make the trip to Xcel Energy Center for an NHL clash with the Minnesota Wild.","mediaType":"Episode","year":"2022","seriesEpisodeNumber":"2022031605","seriesNumber":"20120000","videos":[],"videoStreams":[],"entitlements":["VIP","_OPEN_"],"currentProductIds":[],"currentTvodProductIds":[],"secondaryTitle":"Boston Bruins at Minnesota Wild"},"parentId":"crid:~~2F~~2Fgn.tv~~2F123456789~~2FSH013520120000","rootId":"crid:~~2F~~2Fgn.tv~~2F8396306~~2FSH013520120000","replayTvAvailable":true,"audioTracks":[{"lang":"en","audioPurpose":"main"}],"ratings":[],"offersLatestExpirationDate":1647484200000,"replayTvStartOffset":0,"replayTvEndOffset":2592000,"replayEnabledOnMobileClients":true,"replaySource":"cloud","isGoReplayableViaExternalApp":false,"mergedId":"21763419|en-GB"}' - ) - }) - } else if ( - url === - 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/listings/crid:~~2F~~2Fgn.tv~~2F21720572~~2FEP021779870005,imi:d4324f579ad36992f0c3f6e6d35a9b93e98cb78a' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"id":"crid:~~2F~~2Fgn.tv~~2F21720572~~2FEP021779870005,imi:d4324f579ad36992f0c3f6e6d35a9b93e98cb78a","startTime":1647484200000,"endTime":1647496800000,"actualStartTime":1647484200000,"actualEndTime":1647496800000,"expirationDate":1648089000000,"stationId":"lgi-gb-prodobo-master:1761","imi":"imi:d4324f579ad36992f0c3f6e6d35a9b93e98cb78a","scCridImi":"crid:~~2F~~2Fgn.tv~~2F21720572~~2FEP021779870005,imi:d4324f579ad36992f0c3f6e6d35a9b93e98cb78a","mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F11743980~~2FSH021779870000","program":{"id":"crid:~~2F~~2Fgn.tv~~2F21720572~~2FEP021779870005","title":"Challenge Cup Ice Hockey","description":"Exclusive coverage from SSE Arena of the Premier Sports Challenge Final between Belfast Giants and Cardiff Devils.","longDescription":"Exclusive coverage from SSE Arena of the Premier Sports Challenge Final between Belfast Giants and Cardiff Devils.","medium":"TV","categories":[{"id":"lgi-gb-prodobo-master:genre-123","title":"Ice Hockey","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"}],"isAdult":false,"cast":[],"directors":[],"images":[{"assetType":"HighResPortrait","assetTypes":["HighResPortrait"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p11743980_b_v12_aa.jpg"}],"parentId":"crid:~~2F~~2Fgn.tv~~2F123456789~~2FSH021779870000","rootId":"crid:~~2F~~2Fgn.tv~~2F11743980~~2FSH021779870000","parentalRatingDescription":[],"resolutions":[],"mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F11743980~~2FSH021779870000","shortDescription":"Exclusive coverage from SSE Arena of the Premier Sports Challenge Final between Belfast Giants and Cardiff Devils.","mediaType":"Episode","year":"2022","seriesEpisodeNumber":"2022031605","seriesNumber":"79870000","videos":[],"videoStreams":[],"entitlements":["VIP","_OPEN_"],"currentProductIds":[],"currentTvodProductIds":[],"secondaryTitle":"Final: Belfast Giants v Cardiff Devils"},"parentId":"crid:~~2F~~2Fgn.tv~~2F123456789~~2FSH021779870000","rootId":"crid:~~2F~~2Fgn.tv~~2F11743980~~2FSH021779870000","replayTvAvailable":true,"audioTracks":[{"lang":"en","audioPurpose":"main"}],"ratings":[],"offersLatestExpirationDate":1647928800000,"replayTvStartOffset":0,"replayTvEndOffset":2592000,"replayEnabledOnMobileClients":true,"replaySource":"cloud","isGoReplayableViaExternalApp":false,"mergedId":"21720572|en-GB"}' - ) - }) - } else if ( - url === - 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/listings/crid:~~2F~~2Fgn.tv~~2F21763550~~2FEP012830215435,imi:9692f5ceb0b63354262339e8529e3a9cb57add9c' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"id":"crid:~~2F~~2Fgn.tv~~2F21763550~~2FEP012830215435,imi:9692f5ceb0b63354262339e8529e3a9cb57add9c","startTime":1647511200000,"endTime":1647518400000,"actualStartTime":1647511200000,"actualEndTime":1647518400000,"expirationDate":1648116000000,"stationId":"lgi-gb-prodobo-master:1761","imi":"imi:9692f5ceb0b63354262339e8529e3a9cb57add9c","scCridImi":"crid:~~2F~~2Fgn.tv~~2F21763550~~2FEP012830215435,imi:9692f5ceb0b63354262339e8529e3a9cb57add9c","mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F448880~~2FSH012830210000","program":{"id":"crid:~~2F~~2Fgn.tv~~2F21763550~~2FEP012830215435","title":"NHL Hockey","description":"The Calgary Flames play host to the New Jersey Devils in this NHL encounter from Scotiabank Saddledome.","longDescription":"The Calgary Flames play host to the New Jersey Devils in this NHL encounter from Scotiabank Saddledome.","medium":"TV","categories":[{"id":"lgi-gb-prodobo-master:genre-27","title":"Sport","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"},{"id":"lgi-gb-prodobo-master:genre-123","title":"Ice Hockey","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"}],"isAdult":false,"cast":[],"directors":[],"images":[{"assetType":"HighResLandscapeProductionStill","assetTypes":["HighResLandscapeProductionStill"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p448880_b_h8_ak.jpg"},{"assetType":"HighResPortrait","assetTypes":["HighResPortrait"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p448880_b_v12_ak.jpg"}],"parentId":"crid:~~2F~~2Fgn.tv~~2F21275201~~2FSH012830210000","rootId":"crid:~~2F~~2Fgn.tv~~2F448880~~2FSH012830210000","parentalRatingDescription":[],"resolutions":[],"mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F448880~~2FSH012830210000","shortDescription":"The Calgary Flames play host to the New Jersey Devils in this NHL encounter from Scotiabank Saddledome.","mediaType":"Episode","year":"2022","seriesEpisodeNumber":"194","seriesNumber":"102022","videos":[],"videoStreams":[],"entitlements":["VIP","_OPEN_"],"currentProductIds":[],"currentTvodProductIds":[],"secondaryTitle":"New Jersey Devils at Calgary Flames"},"parentId":"crid:~~2F~~2Fgn.tv~~2F21275201~~2FSH012830210000","rootId":"crid:~~2F~~2Fgn.tv~~2F448880~~2FSH012830210000","replayTvAvailable":true,"audioTracks":[{"lang":"en","audioPurpose":"main"}],"ratings":[],"offersLatestExpirationDate":1647583200000,"replayTvStartOffset":0,"replayTvEndOffset":2592000,"replayEnabledOnMobileClients":true,"replaySource":"cloud","isGoReplayableViaExternalApp":false,"mergedId":"21763550|en-GB"}' - ) - }) - } else if ( - url === - 'https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web/listings/crid:~~2F~~2Fgn.tv~~2F21764379~~2FEP025886890145,imi:c02da14358110cec07d14dc154717ce62ba2f489' - ) { - return Promise.resolve({ - data: JSON.parse( - '{"id":"crid:~~2F~~2Fgn.tv~~2F21764379~~2FEP025886890145,imi:c02da14358110cec07d14dc154717ce62ba2f489","startTime":1647539100000,"endTime":1647540900000,"actualStartTime":1647539100000,"actualEndTime":1647540900000,"expirationDate":1648143900000,"stationId":"lgi-gb-prodobo-master:1761","imi":"imi:c02da14358110cec07d14dc154717ce62ba2f489","scCridImi":"crid:~~2F~~2Fgn.tv~~2F21764379~~2FEP025886890145,imi:c02da14358110cec07d14dc154717ce62ba2f489","mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F13641079~~2FSH025886890000","program":{"id":"crid:~~2F~~2Fgn.tv~~2F21764379~~2FEP025886890145","title":"Boxing World Weekly","description":"A weekly series designed to showcase the best of our sport. Boxing World features news, highlights, previews and profiles from the world of pro boxing.","longDescription":"A weekly series designed to showcase the best of our sport. Boxing World features news, highlights, previews and profiles from the world of pro boxing.","medium":"TV","categories":[{"id":"lgi-gb-prodobo-master:genre-27","title":"Sport","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"},{"id":"lgi-gb-prodobo-master:genre-83","title":"Boxing","scheme":"urn:libertyglobal:metadata:cs:ContentCS:2014_1"}],"isAdult":false,"cast":[],"directors":[],"images":[{"assetType":"HighResPortrait","assetTypes":["HighResPortrait"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p19340143_b_v8_aa.jpg"},{"assetType":"TitleTreatment","assetTypes":["TitleTreatment"],"url":"https://staticqbr-gb-prod.prod.cdn.dmdsdp.com/image-service/ImagesEPG/EventImages/p13641079_ttl_h95_aa.png"}],"parentId":"crid:~~2F~~2Fgn.tv~~2F19340143~~2FSH025886890000","rootId":"crid:~~2F~~2Fgn.tv~~2F13641079~~2FSH025886890000","parentalRatingDescription":[],"resolutions":[],"mediaGroupId":"crid:~~2F~~2Fgn.tv~~2F13641079~~2FSH025886890000","shortDescription":"A weekly series designed to showcase the best of our sport. Boxing World features news, highlights, previews and profiles from the world of pro boxing.","mediaType":"Episode","year":"2022","seriesEpisodeNumber":"60","seriesNumber":"4","videos":[],"videoStreams":[],"entitlements":["VIP","_OPEN_"],"currentProductIds":[],"currentTvodProductIds":[]},"parentId":"crid:~~2F~~2Fgn.tv~~2F19340143~~2FSH025886890000","rootId":"crid:~~2F~~2Fgn.tv~~2F13641079~~2FSH025886890000","replayTvAvailable":true,"audioTracks":[{"lang":"en","audioPurpose":"main"}],"ratings":[],"offersLatestExpirationDate":1648142400000,"replayTvStartOffset":0,"replayTvEndOffset":2592000,"replayEnabledOnMobileClients":true,"replaySource":"cloud","isGoReplayableViaExternalApp":false,"mergedId":"21764379|en-GB"}' - ) - }) - } else { - return Promise.resolve({ data: '' }) - } - }) - - parser({ content, channel, date }) - .then(result => { - result = result.map(p => { - p.start = p.start.toJSON() - p.stop = p.stop.toJSON() - return p - }) - - expect(result).toMatchObject([ - { - start: '2022-03-16T23:30:00.000Z', - stop: '2022-03-17T02:30:00.000Z', - title: 'Live: NHL Hockey', - description: - 'The Boston Bruins make the trip to Xcel Energy Center for an NHL clash with the Minnesota Wild.', - category: ['Sport', 'Ice Hockey'] - }, - { - start: '2022-03-17T02:30:00.000Z', - stop: '2022-03-17T06:00:00.000Z', - title: 'Challenge Cup Ice Hockey', - description: - 'Exclusive coverage from SSE Arena of the Premier Sports Challenge Final between Belfast Giants and Cardiff Devils.', - category: ['Ice Hockey'] - }, - { - start: '2022-03-17T10:00:00.000Z', - stop: '2022-03-17T12:00:00.000Z', - title: 'NHL Hockey', - description: - 'The Calgary Flames play host to the New Jersey Devils in this NHL encounter from Scotiabank Saddledome.', - category: ['Sport', 'Ice Hockey'] - }, - { - start: '2022-03-17T17:45:00.000Z', - stop: '2022-03-17T18:15:00.000Z', - title: 'Boxing World Weekly', - description: - 'A weekly series designed to showcase the best of our sport. Boxing World features news, highlights, previews and profiles from the world of pro boxing.', - category: ['Sport', 'Boxing'], - season: '4', - episode: '60' - } - ]) - done() +it('can parse response', async() => { + const content = await axios.get(url({ date })) + .then(response => response.data) + .catch(console.error) + const result = (await parser({ content, channel, date })) + .map(p => { + p.start = p.start.toJSON() + p.stop = p.stop.toJSON() + return p }) - .catch(done) + + expect(result.length).toBe(3) + expect(result[0]).toMatchObject({ + start: '2024-12-14T00:00:00.000Z', + stop: '2024-12-14T01:05:00.000Z', + title: 'Police Interceptors', + description: + 'Eight police cars and the eye in the sky hunt down a high powered Porsche Cayenne that is causing carnage. Undertaking at high speeds and goading the interceptors, the driver even manages to take out several police cars.', + category: ['Reality', 'Crime'], + season: 16, + episode: 1 + }) + expect(result[2]).toMatchObject({ + start: '2024-12-14T22:00:00.000Z', + stop: '2024-12-14T22:05:00.000Z', + title: 'Entertainment News On 5', + description: + 'A daily round-up of showbiz news and gossip from around the world, focusing on celebrities, movies, music and entertainment.', + category: ['News', 'Entertainment'], + season: 46530000, + episode: 333458689, + actor: ['Jamie Burton'] + }) }) -it('can handle empty guide', done => { - parser({ - content: '[{"type":"PATH_PARAM","code":"period","reason":"INVALID"}]', +it('can handle empty guide', async () => { + const result = await parser({ + content: '', channel, date }) - .then(result => { - expect(result).toMatchObject([]) - done() - }) - .catch(done) + expect(result).toMatchObject([]) })