Update virgintvgo.virginmedia.com guide.

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 <tohenk@yahoo.com>
This commit is contained in:
Toha 2024-12-14 23:36:26 +07:00
parent 581f5e0ca9
commit 70e37c6760
No known key found for this signature in database
GPG key ID: 2D7AA6389D44DCAB
10 changed files with 761 additions and 264 deletions

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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}

View file

@ -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}

View file

@ -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}

View file

@ -1,18 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1324">Nick Jr PAW Patrol</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="138">Virgin TV Highlights</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="195">TRUE CRIME</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="276">Store</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="319">Sky Sports Main Event</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="320">Sky Sports Cricket</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="321">Sky Sports NFL</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="322">Sky Sports Golf</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="414">Ideal World</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1324">Nick Jr Too</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1404">MTV Live HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1562">COLORS HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1595">Sky Sports Darts</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1699">I.D.+1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1752">LEGEND XTRA +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="195">TRUE CRIME</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2257">SkySportsMainEventUHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1786">Sky Sports PL</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1921">Sky Sports +</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="1923">Sky Sports Football</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2020">Channel Update</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2257">Sky SportMainEventUHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2258">Sky Sports Ultra HD 1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2259">Sky Sports F1 UHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2259">Sky Sports Darts UHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2265">Sky Sports Ultra HD 2</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="276">Store</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="4Music.uk" site_id="268">4 Music</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2326">Sky Sports Tennis</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2327">Sky Sports Tennis HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2330">HobbyMaker HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2348">NOW XMAS</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2350">Zee Punjabi</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2352">CNN HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="" site_id="2355">That&apos;s TV2</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="4sevenHD.uk" site_id="1903">4SevenHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="5ActionHD.uk" site_id="1958">5ACTION HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="5SELECT.uk" site_id="1474">5Select</channel>
@ -20,8 +36,8 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="5STARPlus1.uk" site_id="1892">5STAR +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="5USA.uk" site_id="2299">5 USA</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="5USAPlus1.uk" site_id="1475">5 USA +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="alibiHD.uk" site_id="1600">alibi HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="alibiPlus1.uk" site_id="1343">alibi +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="alibiHD.uk" site_id="1600">U&amp;Alibi HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="alibiPlus1.uk" site_id="1343">U&amp;Alibi+1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="AlJazeera.qa" site_id="1674">Al Jazeera Arabic</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="AlJazeeraEnglish.qa" site_id="1673">Al Jazeera English</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="AnimalPlanetHD.uk" site_id="1713">Animal Planet HD</channel>
@ -65,11 +81,10 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ComedyCentralExtra.uk" site_id="174">Comedy Central Extra</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ComedyCentralHD.uk" site_id="1497">Comedy Central HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ComedyCentralPlus1.uk" site_id="1325">Comedy Central +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="CreateandCraft.uk" site_id="1717">Create &amp; Craft</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="CrimePlusInvestigationHD.uk" site_id="568">Crime+Inv HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="CrimePlusInvestigationPlus1.uk" site_id="1972">Crime+Inv +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DaveHD.uk" site_id="1571">Dave HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Davejavu.uk" site_id="171">Dave ja vu</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DaveHD.uk" site_id="1571">U&amp;Dave HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Davejavu.uk" site_id="171">U&amp;DaveJaVu</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DiscoveryChannelHD.uk" site_id="1466">Discovery HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DiscoveryChannelPlus1.uk" site_id="228">Discovery Chan +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DiscoveryHistory.uk" site_id="230">Discovery History</channel>
@ -79,14 +94,13 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DiscoveryTurbo.uk" site_id="232">Discovery Turbo</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DMAX.uk" site_id="1346">DMAX</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DMAXPlus1.uk" site_id="1700">DMAX + 1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DramaHD.uk" site_id="1750">Drama HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DramaPlus1.uk" site_id="2061">Drama +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DramaHD.uk" site_id="1750">U&amp;Drama HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="DramaPlus1.uk" site_id="2061">U&amp;Drama +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="E4Extra.uk" site_id="265">E4 Extra</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="E4HD.uk" site_id="1464">E4 HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="E4Plus1.uk" site_id="194">E4 +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EdenHD.uk" site_id="1573">Eden HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EdenPlus1.uk" site_id="1453">Eden +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EHD.uk" site_id="2059">E! HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EdenHD.uk" site_id="1573">U&amp;Eden HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EdenPlus1.uk" site_id="1453">U&amp;Eden +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="EuronewsEnglish.fr" site_id="354">euronews</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Eurosport1.uk" site_id="2084">Eurosport 1HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Eurosport2.uk" site_id="2085">Eurosport 2HD</channel>
@ -97,11 +111,11 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GBNews.uk" site_id="2165">GB News</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GemsTV.uk" site_id="418">Gems TV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GODTV.uk" site_id="250">GOD TV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GOLDHD.uk" site_id="168">GOLD HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GOLDPlus1.uk" site_id="169">GOLD +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GOLDHD.uk" site_id="168">U&amp;GOLD HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GOLDPlus1.uk" site_id="169">U&amp;GOLD+1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GREATaction.uk" site_id="1893">GREAT! action</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GREATmovies.uk" site_id="1894">GREAT! movies</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GREATromance.uk" site_id="1341">GREAT! christmas</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GREATromance.uk" site_id="1341">GREAT! Christmas</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="GREATtv.uk" site_id="1561">GREAT! tv</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="HGTV.uk" site_id="244">HGTV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="HGTVPlus1.uk" site_id="245">HGTV +1</channel>
@ -119,12 +133,9 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ITV4Plus1.uk" site_id="1456">ITV4 +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ITVBeHD.uk" site_id="1800">ITVBe HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ITVBePlus1.uk" site_id="2148">ITVBe +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Kerrang.uk" site_id="555">Kerrang</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="KissTV.uk" site_id="267">Kiss</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Legend.uk" site_id="1579">LEGEND</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="LFCTV.uk" site_id="1816">Liverpool FC TV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="LondonLive.uk" site_id="1767">London Live</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Magic.uk" site_id="270">Magic</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="More4HD.uk" site_id="1753">More 4 HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="More4Plus1.uk" site_id="1652">More 4 +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Movies24.uk" site_id="567">Christmas 24</channel>
@ -138,15 +149,13 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NationalGeographicHD.uk" site_id="1402">National GeographicHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NationalGeographicPlus1.uk" site_id="235">National Geographic+1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NationalGeographicWildHD.uk" site_id="2088">Nat Geo WILD HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NBCNewsNOW.us" site_id="2255">NBC News Now</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NDTV24x7.in" site_id="1587">NDTV 24x7</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NDTVGoodTimes.in" site_id="1676">NDTV Good Times</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NDTV24x7.in" site_id="1587">NDTV World</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NHKWorldJapan.jp" site_id="1731">NHK World-Japan</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NickelodeonHD.uk" site_id="1734">Nick HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NickelodeonPlus1.uk" site_id="396">Nick +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NickJr.uk" site_id="397">Nick Junior</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Nicktoons.uk" site_id="1399">Nick SpongeBob</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Now70s.uk" site_id="2031">NOW XMAS</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NickJr.uk" site_id="397">Nick Jr. HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Nicktoons.uk" site_id="1399">Nicktoons</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Now70s.uk" site_id="2031">NOW 70s</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Now80s.uk" site_id="1956">NOW 80s</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="NOWRock.uk" site_id="2030">NOW ROCK</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="PBSAmerica.uk" site_id="1574">PBS America</channel>
@ -166,13 +175,13 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaActionHD.uk" site_id="1513">Sky Action HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaAnimationHD.uk" site_id="2141">Sky Animation HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaComedyHD.uk" site_id="1512">Sky Comedy HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaDramaHD.uk" site_id="1516">Sky Christmas HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaFamilyHD.uk" site_id="1514">Sky Family HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaGreatsHD.uk" site_id="1518">Sky Favourites HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaHitsHD.uk" site_id="1511">Sky Hits HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaDramaHD.uk" site_id="1516">Sky Christmas</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaFamilyHD.uk" site_id="1514">Sky Kids Books</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaGreatsHD.uk" site_id="1518">Sky Favourites</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaHitsHD.uk" site_id="1511">Sky Cinema 90s</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaPremiereHD.uk" site_id="1510">Sky Premiere HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaSciFiHorrorHD.uk" site_id="1517">Sky SciFi &amp; Hor HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaSelectHD.uk" site_id="1519">Sky Best of 2023 HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaSelectHD.uk" site_id="1519">Sky Best of 2024</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCinemaThrillerHD.uk" site_id="1515">Sky Thriller HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyComedyHD.uk" site_id="2119">Sky Comedy HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyCrimeHD.uk" site_id="2083">Sky Crime HD</channel>
@ -189,9 +198,9 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyReplay.uk" site_id="1383">Sky Replay</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySciFiHD.uk" site_id="1465">Sky Sci-Fi HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkyShowcaseHD.uk" site_id="1548">Sky Showcase HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsArenaHD.uk" site_id="1922">Sky Sports Arena HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsArenaHD.uk" site_id="1922">Sky Sports + HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsCricketHD.uk" site_id="1521">Sky Sports Cricket HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsF1HD.uk" site_id="1771">Sky Sports F1 HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsF1HD.uk" site_id="1771">Sky Sports Darts HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsFootballHD.uk" site_id="1924">Sky Sports FootballHD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsGolfHD.uk" site_id="1770">Sky Sports Golf HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SkySportsMainEventHD.uk" site_id="1520">Sky SportsMainEventHD</channel>
@ -207,11 +216,8 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SonyMaxHD.uk" site_id="422">SONY MAX HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="SonySABAsia.in" site_id="1705">SONY SAB</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TalkingPicturesTV.uk" site_id="1909">Talking Pictures</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TalkTV.uk" site_id="2254">Talk TV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Thats60s.uk" site_id="2297">That&apos;s 60s</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="Thats60s.uk" site_id="2297">That&apos;s Christmas</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ThatsTV.uk" site_id="2298">That&apos;s TV</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TheBox.uk" site_id="266">Box Christmas</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TinyPop.uk" site_id="1340">Tiny Pop</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TJCHD.uk" site_id="1739">TJC HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TLCHD.uk" site_id="1711">TLC HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="TLCPlus1.uk" site_id="1044">TLC+1</channel>
@ -224,13 +230,12 @@
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="UtsavBharat.uk" site_id="1677">Utsav Bharat</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="UtsavGoldHD.in" site_id="1689">Utsav Gold HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="UtsavPlusHD.uk" site_id="424">Utsav Plus HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ViaplaySports1.uk" site_id="1761">Viaplay Sports 1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ViaplaySports2.uk" site_id="1961">Viaplay Sports 2</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ViaplayXtra.uk" site_id="1960">Viaplay Xtra</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="WHD.uk" site_id="1570">W HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="WPlus1.uk" site_id="1363">W +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="YesterdayHD.uk" site_id="222">YESTERDAY HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="YesterdayPlus1.uk" site_id="1452">YESTERDAY +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ViaplaySports1.uk" site_id="1761">Premier Sports 1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ViaplaySports2.uk" site_id="1961">Premier Sports 2</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="WHD.uk" site_id="1570">U&amp;W HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="WPlus1.uk" site_id="1363">U&amp;W +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="YesterdayHD.uk" site_id="222">U&amp;Yesterday HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="YesterdayPlus1.uk" site_id="1452">U&amp;Yesterday +1</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ZeeCinemaHDUK.uk" site_id="427">Zee Cinema HD</channel>
<channel site="virgintvgo.virginmedia.com" lang="en" xmltv_id="ZeeTVHDUK.uk" site_id="426">Zee TV HD</channel>
</channels>

View file

@ -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
}

View file

@ -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([])
})