From ba706bb6c1480cd1ec1d44c2dfa85b91d9238d3d Mon Sep 17 00:00:00 2001
From: knylbyte <40831653+knylbyte@users.noreply.github.com>
Date: Wed, 29 Jul 2026 18:08:51 +0200
Subject: [PATCH] feat: added sky.com for different europe countries
---
SITES.md | 3 +-
sites/sky.com/__data__/regions.json | 98 --
sites/sky.com/readme.md | 4 +
sites/sky.com/sky.com.channels.xml | 2011 ++++++++++++++++++++-------
sites/sky.com/sky.com.config.js | 374 +++--
sites/sky.com/sky.com.test.js | 249 +++-
sites/sky.de/__data__/content.json | 1 -
sites/sky.de/readme.md | 21 -
sites/sky.de/sky.de.channels.xml | 77 -
sites/sky.de/sky.de.config.js | 78 --
sites/sky.de/sky.de.test.js | 66 -
11 files changed, 2006 insertions(+), 976 deletions(-)
delete mode 100644 sites/sky.com/__data__/regions.json
delete mode 100644 sites/sky.de/__data__/content.json
delete mode 100644 sites/sky.de/readme.md
delete mode 100644 sites/sky.de/sky.de.channels.xml
delete mode 100644 sites/sky.de/sky.de.config.js
delete mode 100644 sites/sky.de/sky.de.test.js
diff --git a/SITES.md b/SITES.md
index caa199cea..fd282a9f4 100644
--- a/SITES.md
+++ b/SITES.md
@@ -158,8 +158,7 @@
| singtel.com | 137 | 🟢 | |
| sjonvarp.is | 13 | 🟢 | |
| sky.co.nz | 91 | 🟢 | |
- | sky.com | 521 | 🟢 | |
- | sky.de | 74 | 🟢 | https://github.com/iptv-org/epg/issues/3200 |
+ | sky.com | 1116 | 🟢 | |
| skylife.co.kr | 257 | 🟢 | |
| skyperfectv.co.jp | 196 | 🟢 | |
| snrt.ma | 11 | 🟢 | |
diff --git a/sites/sky.com/__data__/regions.json b/sites/sky.com/__data__/regions.json
deleted file mode 100644
index b29d5437e..000000000
--- a/sites/sky.com/__data__/regions.json
+++ /dev/null
@@ -1,98 +0,0 @@
-{
- "regions": [
- { "text": "Atherstone HD", "bouquet": 4101, "subBouquet": 19, "value": "4101-19" },
- { "text": "Atherstone SD", "bouquet": 4097, "subBouquet": 19, "value": "4097-19" },
- { "text": "Border England HD", "bouquet": 4101, "subBouquet": 12, "value": "4101-12" },
- { "text": "Border England SD", "bouquet": 4097, "subBouquet": 12, "value": "4097-12" },
- { "text": "Border Scotland HD", "bouquet": 4102, "subBouquet": 36, "value": "4102-36" },
- { "text": "Border Scotland SD", "bouquet": 4098, "subBouquet": 36, "value": "4098-36" },
- { "text": "Brighton HD", "bouquet": 4103, "subBouquet": 65, "value": "4103-65" },
- { "text": "Brighton SD", "bouquet": 4099, "subBouquet": 65, "value": "4099-65" },
- { "text": "Central Midlands HD", "bouquet": 4101, "subBouquet": 3, "value": "4101-3" },
- { "text": "Central Midlands SD", "bouquet": 4097, "subBouquet": 3, "value": "4097-3" },
- { "text": "Channel Isles HD", "bouquet": 4104, "subBouquet": 34, "value": "4104-34" },
- { "text": "Channel Isles SD", "bouquet": 4100, "subBouquet": 34, "value": "4100-34" },
- { "text": "Dundee HD", "bouquet": 4102, "subBouquet": 39, "value": "4102-39" },
- { "text": "Dundee SD", "bouquet": 4098, "subBouquet": 39, "value": "4098-39" },
- { "text": "East Midlands HD", "bouquet": 4101, "subBouquet": 20, "value": "4101-20" },
- { "text": "East Midlands SD", "bouquet": 4097, "subBouquet": 20, "value": "4097-20" },
- { "text": "Essex HD", "bouquet": 4101, "subBouquet": 2, "value": "4101-2" },
- { "text": "Essex SD", "bouquet": 4097, "subBouquet": 2, "value": "4097-2" },
- { "text": "Gloucester HD", "bouquet": 4101, "subBouquet": 24, "value": "4101-24" },
- { "text": "Gloucester SD", "bouquet": 4097, "subBouquet": 24, "value": "4097-24" },
- { "text": "Grampian HD", "bouquet": 4102, "subBouquet": 35, "value": "4102-35" },
- { "text": "Grampian SD", "bouquet": 4098, "subBouquet": 35, "value": "4098-35" },
- { "text": "Granada HD", "bouquet": 4101, "subBouquet": 7, "value": "4101-7" },
- { "text": "Granada SD", "bouquet": 4097, "subBouquet": 7, "value": "4097-7" },
- { "text": "HTV West HD", "bouquet": 4101, "subBouquet": 4, "value": "4101-4" },
- { "text": "HTV West SD", "bouquet": 4097, "subBouquet": 4, "value": "4097-4" },
- { "text": "HTV West / Thames Valley HD", "bouquet": 4103, "subBouquet": 63, "value": "4103-63" },
- { "text": "HTV West / Thames Valley SD", "bouquet": 4099, "subBouquet": 63, "value": "4099-63" },
- { "text": "Henley On Thames HD", "bouquet": 4103, "subBouquet": 70, "value": "4103-70" },
- { "text": "Henley On Thames SD", "bouquet": 4099, "subBouquet": 70, "value": "4099-70" },
- { "text": "Humber HD", "bouquet": 4101, "subBouquet": 29, "value": "4101-29" },
- { "text": "Humber SD", "bouquet": 4097, "subBouquet": 29, "value": "4097-29" },
- { "text": "London HD", "bouquet": 4101, "subBouquet": 1, "value": "4101-1" },
- { "text": "London SD", "bouquet": 4097, "subBouquet": 1, "value": "4097-1" },
- { "text": "London / Essex HD", "bouquet": 4101, "subBouquet": 18, "value": "4101-18" },
- { "text": "London / Essex SD", "bouquet": 4097, "subBouquet": 18, "value": "4097-18" },
- { "text": "London / Thames Valley HD", "bouquet": 4103, "subBouquet": 66, "value": "4103-66" },
- { "text": "London / Thames Valley SD", "bouquet": 4099, "subBouquet": 66, "value": "4099-66" },
- { "text": "London Kent HD", "bouquet": 4103, "subBouquet": 64, "value": "4103-64" },
- { "text": "London Kent SD", "bouquet": 4099, "subBouquet": 64, "value": "4099-64" },
- { "text": "Meridian East HD", "bouquet": 4101, "subBouquet": 11, "value": "4101-11" },
- { "text": "Meridian East SD", "bouquet": 4097, "subBouquet": 11, "value": "4097-11" },
- { "text": "Meridian North HD", "bouquet": 4103, "subBouquet": 68, "value": "4103-68" },
- { "text": "Meridian North SD", "bouquet": 4099, "subBouquet": 68, "value": "4099-68" },
- { "text": "Meridian South HD", "bouquet": 4101, "subBouquet": 5, "value": "4101-5" },
- { "text": "Meridian South SD", "bouquet": 4097, "subBouquet": 5, "value": "4097-5" },
- { "text": "Meridian South East HD", "bouquet": 4101, "subBouquet": 10, "value": "4101-10" },
- { "text": "Meridian South East SD", "bouquet": 4097, "subBouquet": 10, "value": "4097-10" },
- { "text": "Merseyside HD", "bouquet": 4103, "subBouquet": 45, "value": "4103-45" },
- { "text": "Merseyside SD", "bouquet": 4099, "subBouquet": 45, "value": "4099-45" },
- { "text": "Norfolk HD", "bouquet": 4101, "subBouquet": 21, "value": "4101-21" },
- { "text": "Norfolk SD", "bouquet": 4097, "subBouquet": 21, "value": "4097-21" },
- { "text": "North East Midlands HD", "bouquet": 4103, "subBouquet": 62, "value": "4103-62" },
- { "text": "North East Midlands SD", "bouquet": 4099, "subBouquet": 62, "value": "4099-62" },
- { "text": "North West Yorkshire HD", "bouquet": 4101, "subBouquet": 8, "value": "4101-8" },
- { "text": "North West Yorkshire SD", "bouquet": 4097, "subBouquet": 8, "value": "4097-8" },
- { "text": "North Yorkshire HD", "bouquet": 4101, "subBouquet": 26, "value": "4101-26" },
- { "text": "North Yorkshire SD", "bouquet": 4097, "subBouquet": 26, "value": "4097-26" },
- { "text": "Northern Ireland HD", "bouquet": 4104, "subBouquet": 33, "value": "4104-33" },
- { "text": "Northern Ireland SD", "bouquet": 4100, "subBouquet": 33, "value": "4100-33" },
- { "text": "Oxford HD", "bouquet": 4103, "subBouquet": 71, "value": "4103-71" },
- { "text": "Oxford SD", "bouquet": 4099, "subBouquet": 71, "value": "4099-71" },
- { "text": "Republic of Ireland HD", "bouquet": 4104, "subBouquet": 50, "value": "4104-50" },
- { "text": "Republic of Ireland SD", "bouquet": 4100, "subBouquet": 50, "value": "4100-50" },
- { "text": "Ridge Hill HD", "bouquet": 4103, "subBouquet": 41, "value": "4103-41" },
- { "text": "Ridge Hill SD", "bouquet": 4099, "subBouquet": 41, "value": "4099-41" },
- { "text": "Scarborough HD", "bouquet": 4103, "subBouquet": 61, "value": "4103-61" },
- { "text": "Scarborough SD", "bouquet": 4099, "subBouquet": 61, "value": "4099-61" },
- { "text": "Scottish East HD", "bouquet": 4102, "subBouquet": 38, "value": "4102-38" },
- { "text": "Scottish East SD", "bouquet": 4098, "subBouquet": 38, "value": "4098-38" },
- { "text": "Scottish West HD", "bouquet": 4102, "subBouquet": 37, "value": "4102-37" },
- { "text": "Scottish West SD", "bouquet": 4098, "subBouquet": 37, "value": "4098-37" },
- { "text": "Sheffield HD", "bouquet": 4103, "subBouquet": 60, "value": "4103-60" },
- { "text": "Sheffield SD", "bouquet": 4099, "subBouquet": 60, "value": "4099-60" },
- { "text": "South Lakeland HD", "bouquet": 4101, "subBouquet": 28, "value": "4101-28" },
- { "text": "South Lakeland SD", "bouquet": 4097, "subBouquet": 28, "value": "4097-28" },
- { "text": "South Yorkshire HD", "bouquet": 4103, "subBouquet": 72, "value": "4103-72" },
- { "text": "South Yorkshire SD", "bouquet": 4099, "subBouquet": 72, "value": "4099-72" },
- { "text": "Tees HD", "bouquet": 4103, "subBouquet": 69, "value": "4103-69" },
- { "text": "Tees SD", "bouquet": 4099, "subBouquet": 69, "value": "4099-69" },
- { "text": "Thames Valley HD", "bouquet": 4101, "subBouquet": 9, "value": "4101-9" },
- { "text": "Thames Valley SD", "bouquet": 4097, "subBouquet": 9, "value": "4097-9" },
- { "text": "Tring HD", "bouquet": 4101, "subBouquet": 27, "value": "4101-27" },
- { "text": "Tring SD", "bouquet": 4097, "subBouquet": 27, "value": "4097-27" },
- { "text": "Tyne HD", "bouquet": 4101, "subBouquet": 13, "value": "4101-13" },
- { "text": "Tyne SD", "bouquet": 4097, "subBouquet": 13, "value": "4097-13" },
- { "text": "Wales HD", "bouquet": 4104, "subBouquet": 32, "value": "4104-32" },
- { "text": "Wales SD", "bouquet": 4100, "subBouquet": 32, "value": "4100-32" },
- { "text": "West Anglia HD", "bouquet": 4101, "subBouquet": 25, "value": "4101-25" },
- { "text": "West Anglia SD", "bouquet": 4097, "subBouquet": 25, "value": "4097-25" },
- { "text": "West Dorset HD", "bouquet": 4103, "subBouquet": 67, "value": "4103-67" },
- { "text": "West Dorset SD", "bouquet": 4099, "subBouquet": 67, "value": "4099-67" },
- { "text": "Westcountry HD", "bouquet": 4101, "subBouquet": 6, "value": "4101-6" },
- { "text": "Westcountry SD", "bouquet": 4097, "subBouquet": 6, "value": "4097-6" }
- ]
-}
diff --git a/sites/sky.com/readme.md b/sites/sky.com/readme.md
index 65ed6ffe6..56bbafa79 100644
--- a/sites/sky.com/readme.md
+++ b/sites/sky.com/readme.md
@@ -2,6 +2,10 @@
https://www.sky.com/tv-guide
+All Sky countries are covered: Germany, Austria and Switzerland (`DE`), the United Kingdom and Ireland (`GB`), and Italy (`IT`).
+
+Channel IDs use the format `#` (`GB#...`, `IT#...` or `DE#...`).
+
### Download the guide
```sh
diff --git a/sites/sky.com/sky.com.channels.xml b/sites/sky.com/sky.com.channels.xml
index cbe2583f7..cdbe68f38 100644
--- a/sites/sky.com/sky.com.channels.xml
+++ b/sites/sky.com/sky.com.channels.xml
@@ -1,524 +1,1487 @@
-
-
- Really+1
- Sky Intro
- SkySpBoxOffHD
- GTC Punjabi
- Heart 90s
- 55250
- Sky Intro
- Virgin Radio
- Disney Jr HD
- Disney+CineHD
- LBC News
- RTÉ Radio 1
- RTÉ 2FM
- RTÉ R na G
- RTÉ Lyric fm
- BBC R Cymru 2
- BBC R5L
- BBC R5SX
- BBC Three HD
- BBC R1
- BBC R2
- BBC R3
- BBC R4
- BBC R Scot
- BBC R Wales
- BBC R Ulster
- BBC Asian Net
- BBC World Sv
- BBC R Cymru
- BBC R Foyle
- BBC R1X
- BBC R6 Music
- BBC R4 Extra
- BBC RnGÃ id
- BBC R London
- talkSPORT
- Gold Radio
- Radio X
- Capital
- Heart
- Smooth
- Heart Dance
- LBC
- Heart 80s
- Capital XTRA
- BBC ALBA HD
- Sky One HD
- Panjab Radio
- BFBS Radio
- SonLife
- Classic FM
- WRN Europe
- EWTN Catholic
- LEGEND
- Arise News
- QUEST
- My Sky
- My Account
- Program Your Remote
- Help and Support
- Reset your PIN
- Get Sky Products
- 4seven
- 5ACTION
- 5SELECT
- 5STAR+1
- 5STAR
- 5USA+1
- 5 USA
- TVX 40+
- AAJ TAK
- Aastha
- Adult Channel
- Ahlebait TV
- Akaal Channel
- U&Alibi HD
- U&Alibi
- Al Jazeera HD
- Animal Plnt+1
- Animal Planet
- Arirang TV HD
- ARY Digital
- QTV Religious
- ATN
- B4U Movies
- B4U Music
- Babenation
- babes&brazzers
- BabyTV
- BBC Four HD
- BBC Four HD
- BBC NEWS HD
- BBC One CI HD
- BBC One EastHD
- BBC One EMidHD
- BBC One Lon HD
- BBC One NE HD
- BBC One NI HD
- BBC One NI HD
- BBC One NW HD
- BBC One ScotHD
- BBC One SE HD
- BBC One Sth HD
- BBC One SW HD
- BBC One Wal HD
- BBC One Wst HD
- BBC One WM HD
- BBC One Yks HD
- BBC One Y&L HD
- BBC Parl HD
- BBC RB 1 HD
- BBCScotlandHD
- BBC Three HD
- BBC Two HD
- BBC Two NI HD
- BBC Two NI HD
- BBC Two Wal HD
- Best Direct
- BLAZE
- Bloomberg HD
- Boomerang+1
- Boomerang
- Cartoonito
- Cartoon Net HD
- CN+1
- Cartoon Netwrk
- CBBC HD
- CBBC HD
- CBeebies HD
- CBeebies HD
- TRUE CRIME+1
- Challenge
- Challenge
- Channel 4 HD
- Channel 4 HD
- Channel 4+1
- Channel 4 HD
- Channel 4 HD
- Channel 4 HD
- Channel 4 HD
- Channel 4 HD
- Channel 4+1
- Channel 4+1
- Channel 4+1
- Channel 4+1
- 5 HD
- 5+1
- Channels 24
- CHSTV
- Chl Line-up
- Clubland TV
- CNBC HD
- CNN HD
- COLORS
- ColorsCineplex
- ColorsGujarati
- COLORS HD
- ColorsRishtey
- ComedyCentral
- ComedyCentHD
- ComedyCent+1
- ComedyCentral
- ComedyXtra
- ComedyXtra
- Court TV
- Crime+Inv HD
- Crime+Inv+1
- Crime+Inv
- Cruise1st.tv
- Cúla4 HD
- U&Dave HD
- U&Dave
- DAYSTAR HD
- Deen TV
- Discovery
- Discovery
- Discovery HD
- Discovery+1
- Disc.History+1
- Disc.History
- Disc.Science
- Disc.Sci+1
- Disc.Turbo+1
- Disc.Turbo
- DMAX
- DMAX
- DMAX+1
- DM News English
- U&Drama
- Dunamis TV
- E4
- E4 HD
- E4+1
- E4
- E4 Extra
- E4 Extra
- Eman Channel
- Euronews
- EWTN Catholic
- Faith UK
- Faith World TV
- Film4
- Film4 HD
- Film4+1
- Film4
- Food Network
- Food Netwrk+1
- Food Network
- FRANCE 24 HD
- GB News HD
- Gemporia HD
- GEO News
- GEO TV
- GOD Channel
- Great! Action+1
- Great! Action
- Great! Mystery
- Great! Mystery
- G! Mystery+1
- Great! Action
- Great! Romance
- G! Romance+1
- Great! TV
- Great! TV+1
- Great! TV
- HGTV
- High Street TV 1
- High Street TV 2
- Shop Unlimited
- HobbyMakerHD
- LEGEND XTRA+1
- LEGEND XTRA
- HUM EUROPE
- Ideal World HD
- ID+1
- ID
- ID
- iON TV
- IQRA Bangla
- IQRA TV
- Islam Channel
- Islam Ch Urdu
- Islam TV
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1 HD
- ITV1+1
- ITV1+1
- ITV1+1
- ITV1+1
- ITV1 HD
- ITV1 Wales HD
- ITV2 HD
- ITV2+1
- ITV3 HD
- ITV3+1
- ITV4 HD
- ITV4+1
- ITV Quiz HD
- JewelleryMaker
- Kanshi TV
- NTD
- LEGEND
- LFCTV HD
- LoveWorld HD
- Madani Chnl
- HUM News
- APNA MA TV
- More4
- More4 HD
- More4+1
- More4
- Movies24
- Movies24+
- MTA1 World HD
- MTV
- MTV HD
- MTV
- MTV 90s
- Club MTV
- MstHveIdeasHD
- MUTV HD
- Nat Geo HD
- Nat Geo+1
- Nat Geo
- NatGeoWild HD
- Nat Geo Wild
- NDTV World
- New Vision TV
- NHK World HD
- Nickelodeon
- NickelodeonHD
- Nickelodeon+1
- Nickelodeon
- Nick Jr.
- Nick Jr. HD
- Nick Jr+1
- Nick Jr.
- Nick Jr. Too
- Nick Jr. Too
- Nicktoons
- Nicktoons
- Noor TV
- NOW 70s
- NOW 80s
- NOW 90s & 00s
- NOW ROCK
- NTV
- Oireachtas TV
- Panjab TV
- PBC
- PBS America
- PCNE Chinese HD
- Pitaara
- PoliticsPunjab
- Premier 1 HD
- Premier 1 HD
- Premier 2 HD
- Premier 2 HD
- PTC PUNJABI
- QUEST HD
- QUEST HD
- QUEST+1
- Quest Red
- Quest Red+1
- Quest Red
- QVC HD
- QVC Beauty
- QVC Extra
- QVC Style HD
- Racing TV HD
- TRUE CRIME X
- Really
- Really
- revelation
- Rewind TV
- RTÉ2 HD
- RTÉ2+1
- RTÉ KIDSjr
- RTÉ News
- RTÉ One HD
- RTÉ One+1
- S4C HD
- S4C
- Sangat
- Sanskar
- Sikh Channel
- Sky Arts HD
- Sky Arts
- Sky Atlantic
- Sky Atlantic HD
- Sky Atlantic+1
- Sky Atlantic
- Sky Action HD
- Sky Comedy HD
- Sky Drama HD
- Sky Family HD
- Sky Greats HD
- SkyAnimationHD
- SkyPremiereHD
- Sky ScFi/HorHD
- SkyDirectorsHD
- Sky Thriller HD
- Sky Comedy
- Sky Comedy HD
- Sky Comedy
- Sky Crime HD
- Sky Crime
- Sky Crime HD
- Sky Crime+1
- Sky Crime
- SkyDocumntrs
- SkyDocmntrsHD
- SkyDocumntrs
- Sky History2
- Sky HistoryHD
- Sky History
- Sky Kids HD
- Sky One
- Sky One HD
- Sky One
- Sky Mix HD
- Sky Mix HD
- Sky Nature HD
- Sky Nature
- Sky News HD
- Sky News
- Sky News HD
- Sky News
- SkyNewsArabia
- Sky Sci-Fi HD
- Sky Sci-Fi
- SkyShowcase+1
- SkySp+
- SkySp+ HD
- SkySp Cricket
- SkySpCricket HD
- SkySp F1
- SkySp F1 HD
- SkySp F'ball
- SkySp F'ball HD
- SkySp Golf HD
- SkySp Golf
- SkySp Golf HD
- SkySpMainEvHD
- SkySpMainEv
- SkySpMainEvHD
- SkySp Mix HD
- SkySp Mix
- SkySp News HD
- SkySp News
- SkySp News HD
- SkySp News
- SkySp Action
- SkySp ActionHD
- SkySp PL HD
- SkySp PL
- SkySp PL HD
- SkySp Racing HD
- SkySp Racing HD
- SkySp Tennis
- SkySp Tennis HD
- Sky Witness HD
- Sky Witness
- Sky Witness HD
- Sky Witness+1
- Sky Witness
- SONY TV HD
- SONY TV
- SONY MAX 2
- SONY MAX HD
- SONY MAX
- SONY SAB
- STV HD
- STV HD
- STV HD
- STV HD
- STV
- STV
- Takbeer TV
- TalkingPictures
- TBN UK
- Television X
- TG4 HD
- That's TV
- Tiny Pop
- TJC HD
- TLC
- TLC HD
- TLC+1
- TLC
- TNTSports1 HD
- TNTSports1 HD
- TNT Sports 1
- TNTSports2 HD
- TNT Sports 2
- TNTSports3 HD
- TNT Sports 3
- TNTSports4 HD
- TNT Sports 4
- TNTSBoxOff2HD
- TNTSBoxOffHD
- Together
- Travelxp
- TRT World HD
- TRT World
- TRUE CRIME
- TRUE CRIME
- TRUE CRIME X
- TVC News
- TV One
- TV Warehouse
- U&Alibi HD
- U&Alibi+1
- U&Alibi
- U&Dave HD
- U&Dave
- U&DaveJaVu
- U&Drama+1
- U&Drama
- U&Eden+1
- U&Eden
- U&Gold HD
- U&Gold+1
- U&Gold
- U&Gold
- Utsav Bharat
- Utsav Gold HD
- Utsav Gold
- Utsav Plus HD
- Utsav Plus
- UTV HD
- U&W+1
- U&W
- U&Yesterday+1
- U&Yesterday
- Virgin Four HD
- Virgin One HD
- Virgin One+1
- Virgin Three
- Virgin Two HD
- U&W
- Xpanded TV
- XXX Girl Girl
- Zee Cinema
- Zee Punjabi
- Zee TV HD
- Zee TV
-
+
+
+ Sky Cinema 1
+ Dyn Sport Mix
+ RTL Sport 1
+ DFB.TV
+ Sky Sci-Fi HD
+ Sky Cinema 4
+ Sky Sport Bundesliga 11
+ Sky Sport Bundesliga 12
+ sunshine live
+ ANTENNE BAYERN
+ egoFM
+ JAM FM
+ Sky Sport Swiss 01
+ Sky Sport Swiss 02
+ Sky Cinema Blockbuster HD
+ Sky Cinema Feelgood HD
+ Sky Cinema Blockbuster HD +24
+ Sky Cinema Feelgood HD +24
+ Prime Sportsbar
+ BR-KLASSIK
+ Sky Cinema Action HD +24
+ Sky Cinema Classics HD +24
+ Immer etwas Neues TV
+ STEST1
+ STEST2
+ Genius Trend
+ Bayern 1
+ PULS
+ Bayern 2
+ BAYERN 3
+ OLDIE ANTENNE
+ BR24
+ BR24live
+ BR Schlager
+ Bremen NEXT
+ BR Heimat
+ ffn
+ MDR KLASSIK
+ NDR Blue
+ NDR 2 NDS
+ NDR Kultur
+ NDR Info NDS
+ N-JOY
+ NDR 90,3
+ NDR 1 Welle Nord KI
+ NDR 1 Radio MV SN
+ NDR 1 Nieders. HAN
+ NDR Info Spezial
+ NDR Schlager
+ Radio Horeb
+ Radio Paloma
+ RTL RADIO
+ Bremen Eins
+ Bremen Zwei
+ Bremen Vier
+ 1LIVE diGGi
+ Antenne Brbg.
+ SR 1 Europawelle
+ SR kultur
+ SR 3 Saarlandwelle
+ Schlager Radio
+ SWR2 5.1
+ TOGGO Radio
+ SWR1 BW
+ SWR1 RP
+ SWR Kultur
+ SWR3
+ SWR4 BW
+ SWR4 RP
+ SWR Aktuell
+ WDR 2
+ WDR 3
+ WDR 4
+ WDR 5
+ COSMO
+ Die Maus
+ WDR Event
+ hr1
+ hr2
+ hr3
+ hr4
+ YOU FM
+ hr INFO
+ MDR SACHSEN DD
+ MDR S-ANHALT MD
+ MDR THÜR Mitte-W
+ MDR KULTUR
+ MDR JUMP
+ MDR SPUTNIK
+ MDR AKTUELL
+ rbb24 Inforadio
+ radio3
+ rbb 88.8
+ radioeins
+ Fritz
+ Just Cooking
+ One TERRA
+ Crime Time
+ Just Cooking HD
+ One TERRA HD
+ Crime Time HD
+ Hoehenrausch HD
+ SERIEN+ HD
+ Just Fishing HD
+ Hoehenrausch SD
+ SERIEN+
+ Just Fishing
+ AXN White HD
+ Regio TV
+ Prime Sportsbar
+ LT1-OOE
+ Sportdigital EDGE
+ Spirit TV Germany
+ Franken Plus HD
+ Dlf Kultur
+ Dlf
+ DRadio DokDeb
+ Dlf Nova
+ HD Test1
+ HD Test 2
+ Placeholder 1
+ Placeholder 2
+ 3sat HD
+ 13th Street HD
+ 1-2-3.tv
+ 1-2-3.tv HD
+ SAT.1 Bayern
+ SAT.1 RhlPf/Hessen
+ SAT.1 HH/SH
+ SAT.1 NS/Bremen
+ Al Jazeera English
+ Al Jazeera English HD
+ ANIXE HD
+ ANIXE+
+ ARAGON TV INT
+ ARD alpha HD
+ ARD-Alpha HD AT
+ Arirang HD
+ arte HD
+ arte HD AT
+ ATV2 HD AT
+ ATV HD AT
+ a.tv HD
+ AXN Black HD
+ BBC News
+ Beate Uhse HD
+ Bibel TV HD
+ Bibel TV
+ Bloomberg Europe TV
+ Bloomberg Europe TV
+ BR Fernsehen Nord HD
+ BR Fernsehen Süd HD
+ BVN TV
+ Cartoonito
+ Cartoonito
+ Cartoon Network
+ Cartoon Network
+ CGTN News HD
+ CGTN Documentary HD
+ CGTN Francais HD
+ ClipMyHorse.TV
+ CNBC HD
+ CNN Int.
+ Comedy Central HD
+ Comedy Central
+ Crime + Investigation
+ Crime + Investigation
+ DASDING
+ Das Erste HD
+ Das Erste HD AT
+ DAZN 1 HD
+ DAZN 1 HD
+ DAZN 1 HD
+ DAZN 2 HD
+ DAZN 2 HD
+ DAZN 2 HD
+ Deluxe Dance by Kontor
+ Deluxe Dance by Kontor HD
+ Deluxe Music HD
+ Deluxe Music HD Austria
+ DELUXE MUSIC
+ Deluxe Rap
+ Deluxe Rap HD
+ DF1 HD
+ Disney Channel HD
+ Disney Channel HD Austria
+ Disney Channel
+ DMAX HD
+ DMAX Austria HD
+ DMAX
+ DMAX Austria
+ DMF
+ Dokusat
+ eSportsONE
+ EURONEWS GERMAN SD
+ EURONEWS GERMAN
+ Eurosport 1 Deutschland
+ Eurosport 1 HD
+ EWTN katholisches TV
+ EWTN katholisches TV HD
+ France 24 (in English)
+ France 24 (en Français)
+ France 24 (en Francais)
+ Genius Plus
+ Handystar TV 2
+ Handystar TV HD
+ Handystar TV
+ Heimatkanal
+ Heimatkanal
+ HGTV HD
+ HGTV
+ Hip Trips HD
+ HISTORY Channel HD
+ HISTORY Channel
+ Hope TV
+ hr-fernsehen HD
+ HSE HD
+ HSE SD
+ HSE Extra HD
+ HSE Extra
+ HSE Trend SD
+ INPLUS.
+ Jukebox
+ Jukebox
+ Juwelo TV
+ Juwelo HD
+ kabel eins HD
+ kabel eins
+ kabel eins HD Austria
+ Kabel 1 Austria
+ Kabel Eins Doku HD
+ kabel eins Doku
+ Kabel 1 Doku HD Austria
+ kabel1 Doku austria
+ KiKA HD
+ KiKA
+ krone.tv
+ K-TV
+ K-TV HD
+ L-TV
+ MDR Sachsen HD
+ MDR S-Anhalt HD
+ MDR Thüringen HD
+ MediaShop-Meine Einkaufswelt
+ MediaShop- Neuheiten
+ meinTVshop
+ Melodie TV NEU
+ Motorvision+
+ Motorvision+
+ MTV HD
+ MTV
+ münchen.tv HD
+ N24 Doku HD
+ N24 DOKU
+ NatGeo HD
+ NatGeo Wild HD
+ NDR FS HH HD
+ NDR FS MV HD
+ NDR FS NDS HD
+ NDR FS SH HD
+ NHK WORLD-JPN
+ NICK / Comedy Central+1
+ Nick Jr.
+ Nick Jr.
+ Nicktoons
+ Nicktoons
+ NIEDERBAYERN TV HD
+ NITRO HD
+ NITRO Austria HD
+ NITRO
+ NITRO Austria
+ ntv Austria HD
+ ntv Austria
+ ntv HD
+ ntv
+ oe24.TV HD
+ ONE HD
+ ORF1 HD
+ ORF2B HD
+ ORF2K HD
+ ORF2N HD
+ ORF2O HD
+ ORF2S HD
+ ORF2St HD
+ ORF2T HD
+ ORF2V HD
+ ORF2W HD
+ ORF III HD
+ ORF SPORT+ HD
+ OTVA HD
+ pearl.tv Shop
+ pearl.tv HD Shop
+ phoenix HD
+ ProSieben HD
+ ProSieben
+ ProSieben HD Austria
+ ProSieben Austria
+ Pro7 MAXX HD
+ Pro7 MAXX
+ Pro7 MAXX HD Austria
+ Pro7 MAXX Austria
+ PULS 4 HD Austria
+ PULS 4 Austria
+ PULS 24 HD
+ QVC HD
+ QVC Deutschland
+ QVC STYLE HD
+ QVC ZWEI HD
+ R9 Oesterreich HD
+ Radio Bremen HD
+ RAI News 24
+ rbb Berlin HD
+ rbb Brandenburg HD
+ RFO
+ RiC
+ ROCK ANTENNE
+ Romance TV HD
+ Romance TV
+ RTL HD Austria
+ RTL Austria
+ RTL HD
+ RTL
+ RTL Television
+ RTL Bayern
+ RTL HH SH
+ RTL HB NDS
+ SUPER RTL HD
+ Super RTL A HD
+ SUPER RTL
+ SUPER RTL A
+ RTLup HD
+ RTLup Austria HD
+ RTLup
+ RTLup Austria
+ RTL Regional NRW
+ RTLZWEI HD
+ RTLZWEI HD Austria
+ RTLZWEI
+ RTLZWEI Austria
+ SACHSEN EINS
+ SAT.1 HD
+ SAT.1
+ SAT.1 HD Austria
+ SAT.1 A
+ SAT.1 Gold HD
+ SAT.1 Gold
+ SAT.1 Gold HD Austria
+ SAT.1 Gold Österreich
+ SAT.1 NRW
+ Schlager Deluxe
+ ServusTV HD Oesterreich
+ ShopLC HD
+ Shop LC
+ SIXX HD
+ SIXX
+ sixx HD Austria
+ sixx AUSTRIA
+ Sky Atlantic HD
+ Sky Cinema Action HD
+ Sky Cinema Classics HD
+ Sky Cinema Classics
+ Sky Cinema Fun
+ Sky Cinema Premiere HD
+ Sky Cinema Premiere HD +24
+ Sky Crime HD
+ Sky Documentaries HD
+ Sky Krimi HD
+ Sky Nature HD
+ Sky News
+ Sky News Intl
+ Sky One HD
+ Sky Showcase HD
+ Sky Sport 1 HD
+ Sky Sport 1 HD
+ Sky Sport 1 HD
+ Sky Sport 2 HD
+ Sky Sport 2 HD
+ Sky Sport 2 HD
+ Sky Sport 3 HD
+ Sky Sport 3 HD
+ Sky Sport 3 HD
+ Sky Sport 4 HD
+ Sky Sport 4 HD
+ Sky Sport 4 HD
+ Sky Sport 5 HD
+ Sky Sport 5 HD
+ Sky Sport 5 HD
+ Sky Sport 6 HD
+ Sky Sport 6 HD
+ Sky Sport 6 HD
+ Sky Sport 7 HD
+ Sky Sport 7 HD
+ Sky Sport 7 HD
+ Sky Sport 8 HD
+ Sky Sport 8 HD
+ Sky Sport 8 HD
+ Sky Sport 9 HD
+ Sky Sport 9 HD
+ Sky Sport 9 HD
+ Sky Sport 10 HD
+ Sky Sport 10 HD
+ Sky Sport 10 HD
+ Sky Sport Austria 1 HD
+ Sky Sport Austria 1 HD
+ Sky Sport Austria 1 HD
+ Sky Sport Austria 2 HD
+ Sky Sport Austria 2 HD
+ Sky Sport Austria 2 HD
+ Sky Sport Austria 3 HD
+ Sky Sport Austria 3 HD
+ Sky Sport Austria 3 HD
+ Sky Sport Austria 4 HD
+ Sky Sport Austria 4 HD
+ Sky Sport Austria 4 HD
+ Sky Sport Austria 5 HD
+ Sky Sport Austria 5 HD
+ Sky Sport Austria 5 HD
+ Sky Sport Austria 6 HD
+ Sky Sport Austria 6 HD
+ Sky Sport Austria 6 HD
+ Sky Sport Austria 7 HD
+ Sky Sport Austria 7 HD
+ Sky Sport Austria 7 HD
+ Sky Sport Austria 8 HD
+ Sky Sport Austria 8 HD
+ Sky Sport Austria 8 HD
+ Sky Sport Bundesliga 1 HD
+ Sky Sport Bundesliga 1 HD
+ Sky Sport Bundesliga 2 HD
+ Sky Sport Bundesliga 2 HD
+ Sky Sport Bundesliga 3 HD
+ Sky Sport Bundesliga 3 HD
+ Sky Sport Bundesliga 4 HD
+ Sky Sport Bundesliga 4 HD
+ Sky Sport Bundesliga 5 HD
+ Sky Sport Bundesliga 5 HD
+ Sky Sport Bundesliga 6 HD
+ Sky Sport Bundesliga 6 HD
+ Sky Sport Bundesliga 7 HD
+ Sky Sport Bundesliga 7 HD
+ Sky Sport Bundesliga 8 HD
+ Sky Sport Bundesliga 8 HD
+ Sky Sport Bundesliga 9 HD
+ Sky Sport Bundesliga 9 HD
+ Sky Sport Bundesliga 10 HD
+ Sky Sport Bundesliga 10 HD
+ Sky Sport Bundesliga HD
+ Sky Sport Bundesliga HD
+ Sky Sport F1 HD
+ Sky Sport F1 HD
+ Sky Sport Golf HD
+ Sky Sport Golf HD
+ Sky Sport Mix HD
+ Sky Sport Mix HD
+ Sky Sport News HD
+ Sky Sport News HD
+ Sky Sport Premier League HD
+ Sky Sport Premier League HD
+ Sky Sport Tennis HD
+ Sky Sport Tennis HD
+ Sky Sport Tennis HD
+ Sky Sport Tennis HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sky Sport Top Event HD
+ Sonnenklar TV
+ sonnenklar.TV HD
+ SPORT1 HD
+ SPORT1
+ Sportdigital1+
+ SPORTDIGITAL FUSSBALL
+ SR Fernsehen HD
+ Stimmungsgarten TV
+ SWR BW HD
+ SWR RP HD
+ tagesschau24 HD
+ TELE 5 HD
+ TELE 5
+ TELE 5 HD Austria
+ TELEGOLD
+ TLC Austria HD
+ TLC Austria
+ TLC HD
+ TLC
+ TOGGO plus
+ TOGGO plus HD
+ TRT World HD
+ TV5MONDE EUROPE HD
+ tv.ingolstadt HD
+ Mainfranken
+ TVRI WORLD HD
+ Universal TV HD
+ Volksmusik.TV
+ VOX HD Austria
+ VOX Austria
+ VOX HD
+ VOX
+ VOXup HD
+ VOXup
+ WAIDWERK
+ Warner TV Comedy HD
+ Warner TV Comedy
+ Warner TV Film HD
+ Warner TV Film
+ Warner TV Serie HD
+ 1LIVE
+ WDR HD Aachen
+ WDR HD Bielefeld
+ WDR HD Bonn
+ WDR HD Dortmund
+ WDR HD Duisburg
+ WDR HD Düsseldorf
+ WDR HD Essen
+ WDR HD Köln
+ WDR HD Münster
+ WDR HD Siegen
+ WDR HD Wuppertal
+ WELT HD
+ WELT HD AT
+ WELT
+ XPLORE
+ XPLORE HD
+ ZDF HD
+ ZDF HD AT
+ ZDFinfo HD
+ ZDFinfo
+ zdf_neo HD
+ ZDFneo HD AT
+ zdf_neo
+ Zwei Music Television
+ Times Radio
+ Really+1
+ 2975
+ HDTest2
+ 53158
+ SNR/IRN DVB-S2
+ Heart 90s
+ 3100
+ Virgin Radio
+ Disney+CineHD
+ LBC News
+ Sky RB
+ RTÉ Radio 1
+ RTÉ 2FM
+ RTÉ R na G
+ RTÉ Lyric fm
+ 5
+ BBC R Cymru 2
+ BBC R5L
+ BBC R5SX
+ ETV4
+ BBC R1
+ BBC R2
+ BBC R3
+ BBC R4
+ BBC R Scot
+ BBC R Wales
+ BBC R Ulster
+ BBC Asian Net
+ ETV5
+ BBC World Sv
+ BBC R Cymru
+ BBC R Foyle
+ BBC R1X
+ BBC R6 Music
+ BBC R4 Extra
+ BBC RnGÃ id
+ BBC R London
+ Gold Radio
+ Radio X
+ Capital
+ Heart
+ Smooth
+ Heart Dance
+ LBC
+ Heart 80s
+ Capital XTRA
+ Panjab Radio
+ BFBS Radio
+ SonLife
+ Classic FM
+ 50682
+ 50683
+ WRN Europe
+ 50662
+ 50663
+ My Sky
+ My Account
+ Program Your Remote
+ Help and Support
+ Reset your PIN
+ Get Sky Products
+ H1Test
+ ___4109
+ (sub b +1000)
+ 4seven
+ 5ACTION
+ 5SELECT
+ 5STAR+1
+ 5STAR
+ 5USA+1
+ 5 USA
+ TVX 40+
+ AAJ TAK
+ Aastha
+ Adult Channel
+ Ahlebait TV
+ Akaal Channel
+ U&Alibi HD
+ U&Alibi
+ Al Jazeera HD
+ Animal Plnt+1
+ Animal Planet
+ Arirang TV HD
+ Arise News
+ ARY Digital
+ QTV Religious
+ ATN
+ B4U Movies
+ B4U Music
+ Babenation
+ babes&brazzers
+ BabyTV
+ BBC ALBA HD
+ BBC Four HD
+ BBC Four HD
+ BBC NEWS HD
+ BBC One CI HD
+ BBC One EastHD
+ BBC One EMidHD
+ BBC One Lon HD
+ BBC One NE HD
+ BBC One NI HD
+ BBC One NI HD
+ BBC One NW HD
+ BBC One ScotHD
+ BBC One SE HD
+ BBC One Sth HD
+ BBC One SW HD
+ BBC One Wal HD
+ BBC One Wst HD
+ BBC One WM HD
+ BBC One Yks HD
+ BBC One Y&L HD
+ BBC Parl HD
+ BBC RB 1 HD
+ BBCScotlandHD
+ BBC Three HD
+ BBC Three HD
+ BBC Two HD
+ BBC Two NI HD
+ BBC Two NI HD
+ BBC Two Wal HD
+ Best Direct
+ BLAZE
+ Bloomberg HD
+ Boomerang+1
+ Boomerang
+ BT Sport Mosaic 2
+ BT Sport Mosaic
+ Cartoonito
+ Cartoon Net HD
+ CN+1
+ Cartoon Netwrk
+ CBBC HD
+ CBBC HD
+ CBeebies HD
+ CBeebies HD
+ Challenge
+ Challenge
+ Channel 4 HD
+ Channel 4 HD
+ Channel 4+1
+ Channel 4 HD
+ Channel 4 HD
+ Channel 4 HD
+ Channel 4 HD
+ Channel 4 HD
+ Channel 4+1
+ Channel 4+1
+ Channel 4+1
+ Channel 4+1
+ 5 HD
+ 5+1
+ Channels 24
+ CHSTV
+ Chl Line-up
+ Clubland TV
+ CNBC HD
+ CNN HD
+ COLORS
+ ColorsCineplex
+ ColorsGujarati
+ COLORS HD
+ ColorsRishtey
+ ComedyCentral
+ ComedyCentHD
+ ComedyCent+1
+ ComedyCentral
+ ComedyXtra
+ ComedyXtra
+ Crime+Inv HD
+ Crime+Inv+1
+ Crime+Inv
+ Cruise1st.tv
+ Cúla4 HD
+ U&Dave HD
+ U&Dave
+ DAYSTAR HD
+ Deen TV
+ Discovery
+ Discovery
+ Discovery HD
+ Discovery+1
+ Disc.History+1
+ Disc.History
+ Disc.Science
+ Disc.Sci+1
+ Disc.Turbo+1
+ Disc.Turbo
+ Disney Jr HD
+ DMAX
+ DMAX
+ DMAX+1
+ DM News English
+ U&Drama
+ Dunamis TV
+ E4
+ E4 HD
+ E4+1
+ E4
+ E4 Extra
+ E4 Extra
+ Eman Channel
+ Euronews
+ EWTN Catholic
+ EWTN Catholic
+ Faith World TV
+ Film4
+ Film4 HD
+ Film4+1
+ Film4
+ Food Network
+ Food Netwrk+1
+ Food Network
+ FRANCE 24 HD
+ GB News HD
+ Gemporia HD
+ GEO News
+ GEO TV
+ GOD Channel
+ Great! Action+1
+ Great! Action
+ Great! Mystery
+ Great! Mystery
+ G! Mystery+1
+ Great! Action
+ Great! Romance
+ G! Romance+1
+ Great! TV
+ Great! TV+1
+ Great! TV
+ High Street TV 1
+ High Street TV 2
+ Shop Unlimited
+ HobbyMakerHD
+ LEGEND XTRA+1
+ LEGEND XTRA
+ HUM EUROPE
+ Ideal World HD
+ ID+1
+ ID
+ ID
+ iON TV
+ IQRA Bangla
+ IQRA TV
+ Islam Channel
+ Islam Ch Urdu
+ Islam TV
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1 HD
+ ITV1+1
+ ITV1+1
+ ITV1+1
+ ITV1+1
+ ITV1 HD
+ ITV1 Wales HD
+ ITV2 HD
+ ITV2+1
+ ITV3 HD
+ ITV3+1
+ ITV4 HD
+ ITV4+1
+ ITV Quiz HD
+ JewelleryMaker
+ Kanshi TV
+ NTD
+ LEGEND
+ LEGEND
+ LFCTV HD
+ LoveWorld HD
+ Madani Chnl
+ HUM News
+ APNA MA TV
+ More4
+ More4 HD
+ More4+1
+ More4
+ Movies24
+ Movies24+
+ MTA1 World HD
+ MTV
+ MTV HD
+ MTV
+ MstHveIdeasHD
+ MUTV HD
+ Nat Geo HD
+ Nat Geo
+ NatGeoWild HD
+ Nat Geo Wild
+ NDTV World
+ New Vision TV
+ NHK World HD
+ Nickelodeon
+ NickelodeonHD
+ Nickelodeon+1
+ Nickelodeon
+ Nick Jr.
+ Nick Jr. HD
+ Nick Jr+1
+ Nick Jr.
+ NickJrPeppa
+ NickJrPeppa
+ Nick Alvinnn!!!
+ Nick Alvinnn!!!
+ Noor TV
+ NOW 70s
+ NOW 80s
+ NOW 90s & 00s
+ NOW ROCK
+ NTV
+ Oireachtas TV
+ Panjab TV
+ PBC
+ PBS America
+ PCNE Chinese HD
+ Pitaara
+ PoliticsPunjab
+ Premier 1 HD
+ Premier 1 HD
+ Premier 1 HD
+ Premier 2 HD
+ Premier 2 HD
+ Premier 2 HD
+ PTC PUNJABI
+ QUEST HD
+ QUEST HD
+ QUEST+1
+ Quest Red
+ Quest Red+1
+ Quest Red
+ QVC HD
+ QVC Beauty
+ QVC Extra
+ QVC Style HD
+ Racing TV HD
+ Really
+ Really
+ revelation
+ Rewind TV
+ RTÉ2 HD
+ RTÉ2+1
+ RTÉ KIDSjr
+ RTÉ News
+ RTÉ One HD
+ RTÉ One+1
+ S4C HD
+ S4C
+ Sangat
+ Sanskar
+ Sikh Channel
+ Sky Arts HD
+ Sky Arts
+ Sky Atlantic
+ Sky Atlantic HD
+ Sky Atlantic+1
+ Sky Atlantic
+ Sky Action HD
+ Sky Comedy HD
+ Sky Drama HD
+ Sky Family HD
+ Sky Greats HD
+ PitchPerfectHD
+ SkyPremiereHD
+ Sky ScFi/HorHD
+ SkyAnimationHD
+ Sky Thriller HD
+ Sky Comedy
+ Sky Comedy HD
+ Sky Comedy
+ Sky Crime HD
+ Sky Crime
+ Sky Crime HD
+ Sky Crime+1
+ Sky Crime
+ SkyDocumntrs
+ SkyDocmntrsHD
+ SkyDocumntrs
+ Sky History2
+ Sky HistoryHD
+ Sky History
+ Sky Kids HD
+ Sky Mix HD
+ Sky Mix HD
+ Sky Nature HD
+ Sky Nature
+ Sky News HD
+ Sky News
+ Sky News HD
+ Sky News
+ SkyNewsArabia
+ Sky One HD
+ Sky One
+ Sky One
+ Sky One
+ Sky One HD
+ Sky One HD
+ Sky Sci-Fi HD
+ Sky Sci-Fi
+ SkySpBoxOffHD
+ SkySp Cricket
+ SkySpCricket HD
+ SkySpCricket HD
+ SkySpCricket HD
+ SkySp Cricket
+ SkySp F1
+ SkySp F1 HD
+ SkySp F1 HD
+ SkySp F1 HD
+ SkySp F1
+ SkySp F'ball
+ SkySp F'ball HD
+ SkySp F'ball HD
+ SkySp F'ball HD
+ SkySp F'ball
+ SkySp Golf HD
+ SkySp Golf
+ SkySp Golf HD
+ SkySp Golf HD
+ SkySp Golf HD
+ SkySp Golf HD
+ SkySp Golf
+ SkySpMainEvHD
+ SkySpMainEv
+ SkySpMainEvHD
+ SkySpMainEvHD
+ SkySpMainEvHD
+ SkySpMainEv
+ SkySp Mix HD
+ SkySp Mix HD
+ SkySp Mix
+ SkySp Mix
+ SkySp News HD
+ SkySp News
+ SkySp News HD
+ SkySp News HD
+ SkySp News HD
+ SkySp News
+ SkySp News
+ SkySp News
+ SkySp Action
+ SkySp ActionHD
+ SkySp ActionHD
+ SkySp ActionHD
+ SkySp Action
+ SkySp+
+ SkySp+ HD
+ SkySp+
+ SkySp+ HD
+ SkySp+ HD
+ SkySp PL HD
+ SkySp PL
+ SkySp PL HD
+ SkySp PL HD
+ SkySp PL HD
+ SkySp PL HD
+ SkySp PL
+ SkySp Racing HD
+ SkySp Racing HD
+ SkySp Racing HD
+ SkySp Racing HD
+ SkySp Tennis
+ SkySp Tennis HD
+ SkySp Tennis HD
+ SkySp Tennis
+ SkySp Tennis HD
+ Sky Witness HD
+ Sky Witness
+ Sky Witness HD
+ Sky Witness+1
+ Sky Witness
+ SONY TV HD
+ SONY TV
+ SONY MAX 2
+ SONY MAX HD
+ SONY MAX
+ SONY SAB
+ STV HD
+ STV HD
+ STV HD
+ STV HD
+ STV
+ STV
+ Takbeer TV
+ TalkingPictures
+ talkSPORT
+ TBN UK
+ Television X
+ TG4 HD
+ That's TV
+ TJC HD
+ TLC
+ TLC HD
+ TLC+1
+ TLC
+ TNTSports1 HD
+ TNTSports1 HD
+ TNTSports1 HD
+ TNTSports1 HD
+ TNTSports2 HD
+ TNTSports2 HD
+ TNTSports3 HD
+ TNTSports3 HD
+ TNTSports4 HD
+ TNTSports4 HD
+ TNTSports5 HD
+ TNTSports6 HD
+ TNT Sports 6
+ TNTSports7 HD
+ TNT Sports 7
+ TNTSports8 HD
+ TNT Sports 8
+ TNTSports9 HD
+ TNT Sports 9
+ TNTSports10 HD
+ TNT Sports 10
+ TNTSBoxOff2HD
+ TNTSBoxOff2HD
+ TNTSBoxOffHD
+ TNTSBoxOffHD
+ Together
+ Travelxp
+ TRT World HD
+ TRT World
+ TRUE CRIME+1
+ TRUE CRIME
+ TRUE CRIME
+ TRUE CRIME X
+ TRUE CRIME X
+ TVC News
+ TV One
+ TV Warehouse
+ U&Alibi HD
+ U&Alibi+1
+ U&Alibi
+ U&Dave HD
+ U&Dave
+ U&DaveJaVu
+ U&Drama+1
+ U&Drama
+ U&Eden+1
+ U&Eden
+ U&Gold HD
+ U&Gold+1
+ U&Gold
+ U&Gold
+ Utsav Bharat
+ Utsav Gold HD
+ Utsav Gold
+ Utsav Plus HD
+ Utsav Plus
+ UTV HD
+ U&W+1
+ U&W
+ U&Yesterday+1
+ U&Yesterday
+ Virgin Four HD
+ Virgin One HD
+ Virgin One+1
+ Virgin Three
+ Virgin Two HD
+ U&W
+ Xpanded TV
+ XXX Girl Girl
+ Zee Cinema
+ Zee Punjabi
+ Zee TV HD
+ Zee TV
+ Sky Sport Uno
+ Sky Sport Arena
+ Sky Cinema Comedy
+ Sky Sport24
+ Sky Sport24
+ Nick Jr. +1
+ Sky Sport24
+ Sky Cinema Suspense
+ History +1
+ Sky Arte
+ Sky Arte
+ Fox News
+ Sky News
+ Discovery HD
+ Prime Video Sportsbar
+ cielo
+ cielo
+ Sky Crime
+ Sky Primafila
+ Eurosport 2
+ Sky Classica
+ TV2000 HD
+ Radio Vaticana Europa
+ Sky Cinema Uno
+ Sky Cinema Uno
+ Western Collection
+ Sky Cinema Action
+ Sky Sport Calcio
+ CNN Intl.
+ Sky Cinema Uno +24
+ Sky Atlantic
+ NOVE HD
+ Gambero Rosso HD
+ Gambero Rosso HD
+ Sky Sport Calcio
+ Sky Cinema Romance
+ Sky Sport
+ Sky Sport
+ Sky Serie Maratone
+ Calcio Overlay HD
+ CNBC HD
+ Sky Sport Max
+ Sky Crime
+ Classica HD
+ Sky Arte +1
+ Sky Cinema Family
+ Cartoon Network
+ TV8 HD
+ Milan TV
+ Sky Uno +1
+ TV8 HD
+ Deejay TV
+ Sky Sport Info
+ DeAJunior
+ Nickelodeon
+ Sky Meteo24
+ Discovery +1
+ TG24PrimoPiano
+ Boomerang +1
+ CACCIA e Pesca
+ Caccia e PESCA
+ Cartoon Network +1
+ Boomerang
+ Comedy Central
+ LA7 HD
+ -frisbee-
+ Super!
+ Nick Jr
+ MTV Music
+ MTV Music
+ Sky Collection
+ Sky Uno +
+ Class CNBC
+ ACI SPORT TV
+ DeAKids
+ K2
+ Sky Uno
+ Sky Sport F1
+ Sky Sport MotoGP
+ Inter TV
+ Real Time HD
+ History
+ Sky TG24
+ Sky Atlantic +1
+ Sky TG24
+ History
+ Comedy +1
+ DAZN 2
+ Fox Business
+ Radio DeeJay
+ M2O
+ Radio 105
+ Virgin Radio
+ Radio Capital
+ Radio KissKiss
+ RTL 102.5
+ R 101
+ Radio 24
+ RDS
+ Radio Montecarlo
+ Sky Sport Tennis
+ Sky Sport Business 1
+ Sky Sport Business 2
+ Sky Cinema Stories
+ Sky Sport Business 3
+ DAZN 1
+ Sky Sport Legend
+ Sky Sport Mix
+ Disney Jr.
+ Sky Sport
+ Sky Sport
+ Sky Sport
+ Sky Selection
+ Gestione Collegam. Telefonico
+ Connessione internet Primafila
+ Sky Serie
+ Sky Investigation
+ Sky Nature
+ Sky Documentaries
+ Sky Documentaries
+ Sky Nature
+ Food Network HD
+ MTV HD
+ Sky Sport Basket
+ Sky Sport Golf
+ Sky Cinema Drama
+ Sky Sport
+ Sky Sport
+ Sky Cinema Due +24
+ Euronews
+ Rai Storia
+ Rai Scuola
+ RAI Sport
+ Class Tv Moda
+ RTL 102.5 HD
+ Vatican Media Europa
+ Uninettuno
+ Senato Italiano
+ Camera dei Deputati
+ Canale Italia 83
+ People TV-Rete7
+ TelePadrePio HD
+ Napoli Mia
+ RAI Gulp
+ Rai News 24
+ Rai 3 HD
+ Rai 2 HD
+ Rai 1 HD
+ Sky Sport
+ Sky Sport
+ Sky Sport
+ Dimensione Suono Soft
+ Sky Documentaries +1
+ Sky Investigation Maratone
+ Sky Documentaries +1
+ Sky Selection
+ Sky Sport
+ Sky Adventure
+ Sky Adventure
+ Kiss Kiss Tv HD
+ TVA Vicenza
+ InBlu
+ Documentari HD
+ Bambini HD
+ News HD
+ Cinema HD
+ Primafila HD
+ Sport HD
+ Intrattenim. HD
+ Sky Sport HD
+ CIAO
+ Radio Maria
+ Radio Padre Pio
+ Radio Radicale
+ Orler TV
+ PUSH REF SD 3000
+ PUSH REF HD 3001
+ REF 3010
+ REF 3020
+ REF 3030
+ REF 3040
+ REF 3050
+ REF 3055
+ REF 3060
+ Eurosport 1
+ Sky TG24 HD
+ GIALLO HD
+ Discovery Turbo HD
+ Sky Cinema Restart
+ RFI Francais
+ Rai Radio Tutta Italiana
+ HGTV HD
+ Canale Italia 84
+ Al Jazeera Intl. HD
+ Al Jazeera HD
+ France 24 Francais HD
+ CGTN
+ Kurdistan 24 HD
+ Dubai TV HD
+ Al Arabiya
+ Dubai Sports 1 HD
+ Abu Dhabi TV HD
+ Aljazeera Mubasher
+ Al Alam TV HD
+ Jordan TV
+ Iraqia News HD
+ KTV 1 HD
+ ALMAGHRIBIA
+ TVP Polonia
+ TVR Intl.
+ BBC Arabic
+ ESC - Al Masriyah
+ Tunis 7
+ Deutsche Welle HD
+ Daystar Tv HD
+ Sender Neu Jerusalem
+ SuperTennis HD
+ Bloomberg
+ Rai Radio 1
+ Rai Radio 2
+ Rai Radio 3
+ EWTN
+ The Word Network
+ Horse TV HD
+ France 24 English HD
+ NHK World TV HD
+ Arirang TV
+ San Marino RTV
+ TeleItalia
+ TgCom24 HD
+ DMAX HD
+ Radio Monte Carlo
+ RTL 102.5 Caliente
+ Italian Fishing Tv
+ Canale Italia
+ Radio San Marino
+ TRM h24
+ Sky News Arabia HD
+ Virgin Radio
+ San Marino RTV HD
+ Parole di Vita
+ LaC Sat
+ RADIONORBA TV
+ SonLife Broadcasting Network
+ Euronews English HD
+ Canale 5 HD
+ Iris HD
+ La 5 HD
+ Radio Italia Live
+ EQUtv
+ Mediaset Extra HD
+ Mediaset Italia2 HD
+ TOPcrime HD
+ Focus HD
+ Rai Radio 2 Indie
+ 27Twentyseven HD
+ Radio Italia TV HD
+ RADIO ZETA HD
+ 20Mediaset HD
+ Italia 1 HD
+ ArteIn
+ Rete 4 HD
+ RADIOFRECCIA HD
+ Rai Radio Kids
+ Rai Radio Live
+ Rai Radio Techete
+ TELERADIOPACE
+ Rai Radio 1 Sport
+ RDS Social TV
+ Cine34 HD
+ GO-TV CHANNEL
+ Videolina
+ BYOBLU
+ Telecupole
+ INBLU2000
+ Well Tv
+ Radio Gamma Stereo
+ Radio Sintony
+ Radio Super Sound
+ MARCOPOLO
+ LA7CINEMA
+ Giornale Radio
+ Canzoni Napoletane
+ Med.TV
+ JUWELO
+ wedotv Movies
+ wedotv Big Stories
+ TELESARDEGNA
+ Urania TV
+ Discovery HD
+ PRIMASET
+ VALUE 24 TV
+ BeJoy.kids
+ Canale Italia 2
+ LA7 HD
+ TV8 HD
+ NOVE HD
+ Real Time HD
+ QVC
+ RTL 102.5 HD
+ K2
+ -frisbee-
+ Super!
+ TV8 HD
+ SuperTennis HD
+ DMAX HD
+ GIALLO HD
+ Discovery HD
+ Discovery Turbo HD
+ Sky Sport Uno
+ HGTV HD
+ 27 Twentyseven
+ Radio Italia
+ Sky Primafila Active
+ BBC English (Europe)
+ Radio Sportiva
+ Dimensione Suono Roma
+ Discoradio
+ Radio Margherita
+ Rai Radio3 Classica
+ Rai GR PARLAMENTO
+ Rai ISORADIO
+ Radio Iglesias
+ Radio Italia Anni '60
+ Radio Onda d'Urto
+ Radio Number One
+ Radio Popolare
+ Radio Radio
+ Radio Swiss Classic
+ Radio Swiss Jazz
+ Radio Swiss Pop
+ RADIO ZETA
+ Rsi Rete 1
+ Rsi Rete 2
+ Rsi Rete 3
+ RADIOFRECCIA
+ Canale 5
+ La 5
+ Iris
+ LA7CINEMA
+ Mediaset Extra
+ Rete 4 HD
+ Canale 5 HD
+ Italia 1 HD
+ Mediaset Italia2
+ TOPcrime
+ Rete 4
+ Italia 1
+ 20Mediaset HD
+ Focus
+ TgCom24
+ Food Network HD
+ RADIOFRECCIA HD
+ RADIO ZETA
+ Radio DeeJay
+ Radio Capital
+ M2O
+ Radio Italia
+ RTL 102.5
+ Cine34
+ VH1
+ Radio Montecarlo
+ Radio 105
+ Virgin Radio
+ R 101
+ DAZN 1
+ ZONA DAZN 2
+ Radio Italia TV
+
diff --git a/sites/sky.com/sky.com.config.js b/sites/sky.com/sky.com.config.js
index febbfe3d8..817495d41 100644
--- a/sites/sky.com/sky.com.config.js
+++ b/sites/sky.com/sky.com.config.js
@@ -1,137 +1,313 @@
+const axios = require('axios')
const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
const doFetch = require('@ntlab/sfetch')
const debug = require('debug')('site:sky.com')
+const fs = require('fs')
const path = require('path')
-const fs = require('fs/promises')
+const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
doFetch.setCheckResult(false).setDebugger(debug)
-const eventIds = []
+const API_ENDPOINT = 'https://awk.epgsky.com/hawk/linear'
+const CHANNELS_FILE = path.join(__dirname, 'sky.com.channels.xml')
+const LANG_BY_TERRITORY = {
+ DE: 'de',
+ GB: 'en',
+ IT: 'it'
+}
+const MAX_SIDS_PER_REQUEST = 20
+const GRAB_START_DATE = dayjs
+ .utc(process.env.CURR_DATE || new Date().toISOString())
+ .startOf('d')
+const eventIds = new Set()
+const scheduleRequests = new Map()
+let scheduleBatches
module.exports = {
site: 'sky.com',
days: 2,
request: {
+ headers({ channel }) {
+ return getHeaders(parseSiteId(channel.site_id).territory)
+ },
cache: {
- ttl: 24 * 60 * 60 * 1000 // 1 day
+ ttl: 24 * 60 * 60 * 1000, // 1 day
+ vary: ['X-SkyOTT-Territory']
}
},
url({ date, channel }) {
- return `https://awk.epgsky.com/hawk/linear/schedule/${date.format('YYYYMMDD')}/${
- channel.site_id
- }`
+ const { sid } = parseSiteId(channel.site_id)
+ const sids = getScheduleBatch(channel.site_id) || [sid]
+
+ return `${API_ENDPOINT}/schedule/${date.format('YYYYMMDD')}/${sids.join(',')}`
},
- async parser({ content, channel, date }) {
+ async parser({ content, channel, date, config }) {
const programs = []
- if (content) {
- const events = {}
- const ev = items => {
- if (typeof items === 'string' || Buffer.isBuffer(items)) {
- items = JSON.parse(items)
- }
- if (Array.isArray(items?.schedule)) {
- items.schedule
- .filter(schedule => schedule.sid === channel.site_id)
- .forEach(schedule => {
- if (Array.isArray(schedule.events)) {
- schedule.events
- .filter(event => !eventIds.includes(event.eid))
- .forEach(event => {
- // use event id (eid) as unique filter
- if (events[event.eid] === undefined) {
- events[event.eid] = event
- }
- })
- }
- })
- }
+ const events = new Map()
+ const range = getGrabRange(config)
+
+ collectEvents(content, channel, events)
+
+ date = date.startOf('d')
+ if (date.isSame(range.lastDate, 'd')) {
+ try {
+ const response = await getSchedule(channel, date.add(1, 'd'))
+ collectEvents(response, channel, events)
+ } catch (error) {
+ debug('Unable to load the final Sky schedule batch: %s', error.message)
}
- ev(content)
- if (Object.keys(events).length) {
- date = date.startOf('d')
- // fetch next day schedule to get 24 hours schedule
- await doFetch([module.exports.url({ channel, date: date.add(1, 'd') })], (url, res) => {
- if (res) {
- ev(res)
- }
+ }
+
+ for (const event of events.values()) {
+ const start = dayjs.utc(event.st * 1000)
+ const stop = start.add(event.d, 's')
+ const eventId = getEventId(channel, event)
+ if (
+ start.isBefore(range.stop) &&
+ stop.isAfter(range.start) &&
+ !eventIds.has(eventId)
+ ) {
+ eventIds.add(eventId)
+ const image = event.programmeuuid
+ ? `https://images.metadata.sky.com/pd-image/${event.programmeuuid}/16-9/640`
+ : null
+
+ programs.push({
+ title: event.t,
+ description: event.sy,
+ season: event.seasonnumber,
+ episode: event.episodenumber,
+ start,
+ stop,
+ icon: image,
+ image
})
- Object.values(events)
- .forEach(event => {
- const start = dayjs.utc(event.st * 1000)
- const stop = start.add(event.d, 's')
- if (date.isSame(start, 'd') || (date.isSame(stop, 'd') && stop > date)) {
- eventIds.push(event.eid)
- const image = `https://images.metadata.sky.com/pd-image/${event.programmeuuid}/16-9/640`
- programs.push({
- title: event.t,
- description: event.sy,
- season: event.seasonnumber,
- episode: event.episodenumber,
- start,
- stop,
- icon: image,
- image
- })
- }
- })
}
}
return programs
},
async channels() {
- const dataPath = path.join(__dirname, '__data__', 'regions.json')
- const regions = []
-
- try {
- const raw = await fs.readFile(dataPath, 'utf8')
- const payload = JSON.parse(raw)
- if (Array.isArray(payload.regions)) {
- regions.push(...payload.regions)
+ const territories = Object.entries(LANG_BY_TERRITORY)
+ const queue = territories.map(([territory, lang]) => ({
+ type: 'regions',
+ lang,
+ territory,
+ url: `${API_ENDPOINT}/regions`,
+ params: {
+ headers: getHeaders(territory)
}
- } catch (err) {
- debug('Failed to read regions from %s: %o', dataPath, err)
- throw err
- }
-
- if (regions.length === 0) {
- debug('No regions defined in %s', dataPath)
- return []
- }
-
- const uniqueRegions = new Map()
- regions.forEach(region => {
- if (!region || region.bouquet === undefined || region.subBouquet === undefined) return
- const key = `${region.bouquet}-${region.subBouquet}`
- if (!uniqueRegions.has(key)) uniqueRegions.set(key, region)
- })
-
- const channels = {}
- const queues = Array.from(uniqueRegions.values()).map(region => ({
- t: 'c',
- url: `https://awk.epgsky.com/hawk/linear/services/${region.bouquet}/${region.subBouquet}`
}))
+ const channels = new Map()
+ const regions = new Set()
+ const failures = []
+ const states = new Map(
+ territories.map(([territory]) => [
+ territory,
+ {
+ channels: 0,
+ regionsLoaded: false,
+ serviceRequests: 0,
+ serviceResponses: 0
+ }
+ ])
+ )
- await doFetch(queues, (queue, res) => {
- // process channels
- if (queue.t === 'c') {
- if (Array.isArray(res.services)) {
- for (const ch of res.services) {
- if (channels[ch.sid] === undefined) {
- channels[ch.sid] = {
- lang: 'en',
- site_id: ch.sid,
- name: ch.t
- }
- }
+ await doFetch(queue, (request, response) => {
+ const state = states.get(request.territory)
+ if (request.type === 'regions') {
+ if (!Array.isArray(response?.regions) || !response.regions.length) {
+ failures.push(`${request.territory}: ${request.url}`)
+ return
+ }
+
+ state.regionsLoaded = true
+ for (const region of response.regions) {
+ if (region?.bouquetId === undefined || region?.subBouquetId === undefined) {
+ failures.push(`${request.territory}: ${request.url} (invalid region)`)
+ continue
}
+
+ const regionId = `${region.bouquetId}/${region.subBouquetId}`
+ const key = `${request.territory}:${regionId}`
+ if (regions.has(key)) continue
+
+ regions.add(key)
+ state.serviceRequests++
+ queue.push({
+ type: 'services',
+ lang: request.lang,
+ territory: request.territory,
+ url: `${API_ENDPOINT}/services/${regionId}`,
+ params: {
+ headers: getHeaders(request.territory)
+ }
+ })
+ }
+ return
+ }
+
+ if (!Array.isArray(response?.services)) {
+ failures.push(`${request.territory}: ${request.url}`)
+ return
+ }
+
+ state.serviceResponses++
+ for (const service of response.services) {
+ if (service?.sid === undefined) {
+ failures.push(`${request.territory}: ${request.url} (invalid service)`)
+ continue
+ }
+
+ if (!service.t) continue
+
+ const siteId = `${request.territory}#${service.sid}`
+ if (!channels.has(siteId)) {
+ channels.set(siteId, {
+ lang: request.lang,
+ site_id: siteId,
+ name: service.t
+ })
+ state.channels++
}
}
})
- return Object.values(channels)
+ const incomplete = [...states]
+ .filter(
+ ([, state]) =>
+ !state.regionsLoaded ||
+ !state.serviceRequests ||
+ state.serviceResponses !== state.serviceRequests ||
+ !state.channels
+ )
+ .map(([territory]) => territory)
+
+ if (incomplete.length || failures.length) {
+ const reasons = [...new Set([...failures, ...incomplete])].join(', ')
+ throw new Error(
+ `Unable to load complete Sky channel list: ${reasons || 'no channels found'}`
+ )
+ }
+
+ return [...channels.values()]
+ }
+}
+
+function getHeaders(territory) {
+ return {
+ 'X-SkyOTT-Territory': territory
+ }
+}
+
+function getEventId(channel, event) {
+ return `${channel.site_id}:${event.eid}`
+}
+
+function getGrabRange(config) {
+ const configuredDays = Number(config?.days)
+ const days = Number.isInteger(configuredDays) && configuredDays > 0
+ ? configuredDays
+ : module.exports.days
+ const stop = GRAB_START_DATE.add(days, 'd')
+
+ return {
+ lastDate: stop.subtract(1, 'd'),
+ start: GRAB_START_DATE,
+ stop
+ }
+}
+
+function getSchedule(channel, date) {
+ const { territory } = parseSiteId(channel.site_id)
+ const url = module.exports.url({ channel, date })
+ const key = `${territory}:${url}`
+
+ if (!scheduleRequests.has(key)) {
+ const request = axios
+ .get(url, {
+ headers: getHeaders(territory)
+ })
+ .then(response => response.data)
+ .catch(error => {
+ scheduleRequests.delete(key)
+ throw error
+ })
+
+ scheduleRequests.set(key, request)
+ }
+
+ return scheduleRequests.get(key)
+}
+
+function getScheduleBatch(siteId) {
+ if (!scheduleBatches) scheduleBatches = loadScheduleBatches()
+
+ return scheduleBatches.get(siteId)
+}
+
+function loadScheduleBatches() {
+ const channelsXml = fs.readFileSync(CHANNELS_FILE, 'utf8')
+ const sidsByTerritory = new Map(
+ Object.keys(LANG_BY_TERRITORY).map(territory => [territory, new Set()])
+ )
+
+ for (const match of channelsXml.matchAll(/\bsite_id="([^"]+)"/g)) {
+ const { sid, territory } = parseSiteId(match[1])
+ sidsByTerritory.get(territory).add(sid)
+ }
+
+ const batches = new Map()
+ for (const [territory, sidSet] of sidsByTerritory) {
+ const sids = [...sidSet]
+ for (let index = 0; index < sids.length; index += MAX_SIDS_PER_REQUEST) {
+ const batch = sids.slice(index, index + MAX_SIDS_PER_REQUEST)
+ for (const sid of batch) {
+ batches.set(`${territory}#${sid}`, batch)
+ }
+ }
+ }
+
+ return batches
+}
+
+function collectEvents(content, channel, events) {
+ const data = parseContent(content)
+ if (!Array.isArray(data?.schedule)) return
+
+ const { sid } = parseSiteId(channel.site_id)
+ for (const schedule of data.schedule) {
+ if (String(schedule.sid) !== sid || !Array.isArray(schedule.events)) continue
+
+ for (const event of schedule.events) {
+ if (event?.eid !== undefined && !events.has(event.eid)) {
+ events.set(event.eid, event)
+ }
+ }
+ }
+}
+
+function parseSiteId(siteId) {
+ const [territory, sid, ...extra] = String(siteId || '').split('#')
+ if (!LANG_BY_TERRITORY[territory] || !sid || extra.length) {
+ throw new Error(
+ `Invalid Sky site_id "${siteId || ''}". Expected "#" with territory "DE", "GB" or "IT".`
+ )
+ }
+
+ return { sid, territory }
+}
+
+function parseContent(content) {
+ if (!content) return null
+
+ try {
+ if (Buffer.isBuffer(content)) content = content.toString()
+
+ return typeof content === 'string' ? JSON.parse(content) : content
+ } catch {
+ return null
}
}
diff --git a/sites/sky.com/sky.com.test.js b/sites/sky.com/sky.com.test.js
index 05aacdc8f..706926267 100644
--- a/sites/sky.com/sky.com.test.js
+++ b/sites/sky.com/sky.com.test.js
@@ -1,4 +1,6 @@
-const { parser, url } = require('./sky.com.config.js')
+process.env.CURR_DATE = '2026-06-08'
+
+const { channels, parser, request, url } = require('./sky.com.config.js')
const fs = require('fs')
const path = require('path')
const axios = require('axios')
@@ -13,29 +15,73 @@ jest.mock('axios')
const date = dayjs.utc('2026-06-08').startOf('d')
const channel = {
- site_id: '4086',
+ lang: 'en',
+ site_id: 'GB#4086',
xmltv_id: 'SkyHistory.uk@HD'
}
-axios.get.mockImplementation(url => {
+function mockScheduleRequest(url) {
const urls = {
- 'https://awk.epgsky.com/hawk/linear/schedule/20260608/4086': 'content1.json',
- 'https://awk.epgsky.com/hawk/linear/schedule/20260609/4086': 'content2.json'
+ '20260608': 'content1.json',
+ '20260609': 'content2.json'
}
let data = ''
- if (urls[url] !== undefined) {
- data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString()
+ const match = url.match(/\/schedule\/(\d{8})\/([^/]+)$/)
+ if (match && match[2].split(',').includes('4086') && urls[match[1]] !== undefined) {
+ data = fs.readFileSync(path.join(__dirname, '__data__', urls[match[1]])).toString()
}
- return Promise.resolve({ data })
+ return Promise.resolve({ data, headers: {}, request: {} })
+}
+
+beforeEach(() => {
+ jest.clearAllMocks()
+ axios.get.mockImplementation(mockScheduleRequest)
})
it('can generate valid url', () => {
- expect(url({ channel, date })).toBe('https://awk.epgsky.com/hawk/linear/schedule/20260608/4086')
+ const result = url({ channel, date })
+ const sids = result.split('/').pop().split(',')
+
+ expect(result).toContain('https://awk.epgsky.com/hawk/linear/schedule/20260608/')
+ expect(sids).toHaveLength(20)
+ expect(sids).toContain('4086')
+ expect(new Set(sids)).toHaveProperty('size', 20)
+
+ const companion = {
+ ...channel,
+ site_id: `GB#${sids.find(sid => sid !== '4086')}`
+ }
+ expect(url({ channel: companion, date })).toBe(result)
+})
+
+it('falls back to a single SID for a channel outside the repository XML', () => {
+ expect(url({ channel: { ...channel, site_id: 'GB#999999' }, date })).toBe(
+ 'https://awk.epgsky.com/hawk/linear/schedule/20260608/999999'
+ )
+})
+
+it('rejects an unsupported territory in the site ID', () => {
+ expect(() => url({ channel: { ...channel, site_id: 'XX#4086' }, date })).toThrow(
+ 'Expected "#"'
+ )
+})
+
+it('can generate territory headers from the site ID', () => {
+ expect(request.headers({ channel })).toEqual({
+ 'X-SkyOTT-Territory': 'GB'
+ })
+ expect(request.headers({ channel: { ...channel, lang: 'en', site_id: 'DE#4086' } })).toEqual({
+ 'X-SkyOTT-Territory': 'DE'
+ })
+ expect(request.headers({ channel: { ...channel, lang: 'it', site_id: 'IT#4086' } })).toEqual({
+ 'X-SkyOTT-Territory': 'IT'
+ })
+ expect(request.cache.vary).toEqual(['X-SkyOTT-Territory'])
})
it('can parse response', async () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content1.json'))
- const result = (await parser({ content, channel, date }))
+ const result = (await parser({ config: { days: 1 }, content, channel, date }))
.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
@@ -65,13 +111,196 @@ it('can parse response', async () => {
icon: 'https://images.metadata.sky.com/pd-image/68152ae7-97d6-44c8-8a54-e78710b94a76/16-9/640',
image: 'https://images.metadata.sky.com/pd-image/68152ae7-97d6-44c8-8a54-e78710b94a76/16-9/640'
})
+ expect(axios.get).toHaveBeenCalledWith(
+ url({ channel, date: date.add(1, 'd') }),
+ {
+ headers: {
+ 'X-SkyOTT-Territory': 'GB'
+ }
+ }
+ )
+})
+
+it('only loads a follow-up batch for the final requested date', async () => {
+ await parser({
+ config: { days: 2 },
+ content: '',
+ channel,
+ date
+ })
+ expect(axios.get).not.toHaveBeenCalled()
+
+ await parser({
+ config: { days: 2 },
+ content: '',
+ channel,
+ date: date.add(1, 'd')
+ })
+ expect(axios.get).toHaveBeenCalledTimes(1)
+ expect(axios.get).toHaveBeenCalledWith(
+ url({ channel, date: date.add(2, 'd') }),
+ {
+ headers: {
+ 'X-SkyOTT-Territory': 'GB'
+ }
+ }
+ )
+})
+
+it('loads a shared follow-up batch only once', async () => {
+ const sids = url({ channel, date }).split('/').pop().split(',')
+ const companion = {
+ ...channel,
+ site_id: `GB#${sids.find(sid => sid !== '4086')}`
+ }
+ const finalDate = date.add(2, 'd')
+
+ await Promise.all([
+ parser({ config: { days: 3 }, content: '', channel, date: finalDate }),
+ parser({ config: { days: 3 }, content: '', channel: companion, date: finalDate })
+ ])
+
+ expect(axios.get).toHaveBeenCalledTimes(1)
+ expect(axios.get).toHaveBeenCalledWith(
+ url({ channel, date: finalDate.add(1, 'd') }),
+ {
+ headers: {
+ 'X-SkyOTT-Territory': 'GB'
+ }
+ }
+ )
})
it('can handle empty guide', async () => {
const result = await parser({
+ config: { days: 2 },
date,
channel,
content: ''
})
expect(result).toMatchObject([])
})
+
+it('keeps identical event IDs isolated by territory', async () => {
+ const content = JSON.stringify({
+ schedule: [
+ {
+ sid: '123',
+ events: [
+ {
+ eid: 'shared-event',
+ st: date.unix(),
+ d: 3600,
+ t: 'Shared event'
+ }
+ ]
+ }
+ ]
+ })
+ const englishChannel = { lang: 'en', site_id: 'GB#123' }
+ const germanChannel = { lang: 'de', site_id: 'DE#123' }
+
+ expect(await parser({ content, channel: englishChannel, date })).toHaveLength(1)
+ expect(await parser({ content, channel: germanChannel, date })).toHaveLength(1)
+ expect(await parser({ content, channel: englishChannel, date })).toHaveLength(0)
+})
+
+it('can load and deduplicate all territories by language and site ID', async () => {
+ axios.get.mockImplementation((url, options) => {
+ const territory = options.headers['X-SkyOTT-Territory']
+ const titles = {
+ DE: 'Sky One Deutschland HD',
+ GB: 'Sky One HD',
+ IT: 'Sky Uno HD'
+ }
+
+ if (url.endsWith('/regions')) {
+ return Promise.resolve({
+ data: {
+ regions: [
+ { bouquetId: 1, subBouquetId: 2 },
+ { bouquetId: 1, subBouquetId: 2 }
+ ]
+ },
+ headers: {},
+ request: {}
+ })
+ }
+
+ return Promise.resolve({
+ data: {
+ services: [
+ { sid: '123', t: titles[territory] },
+ { sid: '123', t: titles[territory] },
+ ...(territory === 'IT' ? [{ sid: '582' }] : [])
+ ]
+ },
+ headers: {},
+ request: {}
+ })
+ })
+
+ await expect(channels()).resolves.toEqual([
+ {
+ lang: 'de',
+ site_id: 'DE#123',
+ name: 'Sky One Deutschland HD'
+ },
+ {
+ lang: 'en',
+ site_id: 'GB#123',
+ name: 'Sky One HD'
+ },
+ {
+ lang: 'it',
+ site_id: 'IT#123',
+ name: 'Sky Uno HD'
+ }
+ ])
+ expect(axios.get).toHaveBeenCalledTimes(6)
+ expect(axios.get.mock.calls.map(([, options]) => options.headers)).toEqual(
+ expect.arrayContaining([
+ { 'X-SkyOTT-Territory': 'GB' },
+ { 'X-SkyOTT-Territory': 'DE' },
+ { 'X-SkyOTT-Territory': 'IT' }
+ ])
+ )
+})
+
+it('rejects unsupported channel territories', () => {
+ expect(() => request.headers({ channel: { ...channel, site_id: 'FR#4086' } })).toThrow(
+ 'territory "DE", "GB" or "IT"'
+ )
+})
+
+it('rejects an incomplete channel list', async () => {
+ axios.get.mockImplementation((url, options) => {
+ if (url.endsWith('/regions')) {
+ return Promise.resolve({
+ data: {
+ regions: [{ bouquetId: 1, subBouquetId: 2 }]
+ },
+ headers: {},
+ request: {}
+ })
+ }
+
+ if (options.headers['X-SkyOTT-Territory'] === 'DE') {
+ return Promise.resolve({
+ data: {
+ services: [{ sid: '123', t: 'Sky One Deutschland HD' }]
+ },
+ headers: {},
+ request: {}
+ })
+ }
+
+ return Promise.resolve({
+ data: {},
+ headers: {},
+ request: {}
+ })
+ })
+
+ await expect(channels()).rejects.toThrow('Unable to load complete Sky channel list')
+})
diff --git a/sites/sky.de/__data__/content.json b/sites/sky.de/__data__/content.json
deleted file mode 100644
index 89a208b09..000000000
--- a/sites/sky.de/__data__/content.json
+++ /dev/null
@@ -1 +0,0 @@
-{"cl":[{"ci":522,"el":[{"ei":122309300,"bsdt":1645916700000,"bst":"00:05","bedt":1645918200000,"len":25,"et":"King of Queens","ec":"Comedyserie","cop":"USA","yop":2001,"fsk":"ab 0 Jahre","epit":"Der Experte","sn":"4","en":"11","pu":"/static/img/program_guide/1522936_s.jpg"},{"ei":122309301,"bsdt":1645918200000,"bst":"00:30","bedt":1645919700000,"len":25,"et":"King of Queens","ec":"Comedyserie","cop":"USA","yop":2001,"fsk":"ab 0 Jahre","epit":"Speedy Gonzales","sn":"4","en":"12","pu":"/static/img/program_guide/1522937_s.jpg"}]}]}
\ No newline at end of file
diff --git a/sites/sky.de/readme.md b/sites/sky.de/readme.md
deleted file mode 100644
index 5d9b2f168..000000000
--- a/sites/sky.de/readme.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# sky.de
-
-https://www.sky.de/tvguide-7599
-
-### Download the guide
-
-```sh
-npm run grab --- --sites=sky.de
-```
-
-### Update channel list
-
-```sh
-npm run channels:parse --- --config=./sites/sky.de/sky.de.config.js --output=./sites/sky.de/sky.de.channels.xml
-```
-
-### Test
-
-```sh
-npm test --- sky.de
-```
diff --git a/sites/sky.de/sky.de.channels.xml b/sites/sky.de/sky.de.channels.xml
deleted file mode 100644
index 2a5905a16..000000000
--- a/sites/sky.de/sky.de.channels.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
- 13th Street HD
- Beate Uhse HD
- Cartoonito
- Cartoon Network
- Crime + Investigation
- DAZN 1 HD
- DAZN 2 HD
- Heimatkanal
- HISTORY Channel HD
- Jukebox
- Motorvision+
- NatGeo HD
- NatGeo Wild HD
- Nick Jr.
- Nicktoons
- Romance TV HD
- Sky Atlantic HD
- Sky Cinema Action HD
- Sky Cinema Highlights HD
- Sky Cinema Classics HD
- Sky Cinema Family HD
- Sky Cinema Premiere HD
- Sky Crime HD
- Sky Documentaries HD
- Sky Krimi HD
- Sky Nature HD
- Sky One HD
- Sky Replay HD
- Sky Showcase HD
- Sky Sport 1 HD
- Sky Sport 2 HD
- Sky Sport 3 HD
- Sky Sport 4 HD
- Sky Sport 5 HD
- Sky Sport 6 HD
- Sky Sport 7 HD
- Sky Sport 8 HD
- Sky Sport 9 HD
- Sky Sport 10 HD
- Sky Sport UHD
- Sky Sport Austria 1 HD
- Sky Sport Austria 2 HD
- Sky Sport Austria 3 HD
- Sky Sport Austria 4 HD
- Sky Sport Austria 5 HD
- Sky Sport Austria 6 HD
- Sky Sport Austria 7 HD
- Sky Sport Austria 8 HD
- Sky Sport Bundesliga 1 HD
- Sky Sport Bundesliga 2 HD
- Sky Sport Bundesliga 3 HD
- Sky Sport Bundesliga 4 HD
- Sky Sport Bundesliga 5 HD
- Sky Sport Bundesliga 6 HD
- Sky Sport Bundesliga 7 HD
- Sky Sport Bundesliga 8 HD
- Sky Sport Bundesliga 9 HD
- Sky Sport Bundesliga 10 HD
- Sky Sport Bundesliga HD
- Sky Sport Bundesliga UHD
- Sky Sport F1 HD
- Sky Sport Golf HD
- Sky Sport Mix HD
- Sky Sport News HD
- Sky Sport Premier League HD
- Sky Sport Tennis HD
- Sky Sport Top Event HD
- SPORTDIGITAL FUSSBALL
- SYFY HD
- Universal TV HD
- Warner TV Comedy HD
- Warner TV Film HD
- Warner TV Film
- Warner TV Serie HD
-
diff --git a/sites/sky.de/sky.de.config.js b/sites/sky.de/sky.de.config.js
deleted file mode 100644
index e91451bfa..000000000
--- a/sites/sky.de/sky.de.config.js
+++ /dev/null
@@ -1,78 +0,0 @@
-const dayjs = require('dayjs')
-
-module.exports = {
- site: 'sky.de',
- days: 2,
- url: 'https://www.sky.de/sgtvg/service/getBroadcastsForGrid',
- request: {
- method: 'POST',
- headers: {
- 'accept-language': 'en-GB',
- 'accept-encoding': 'gzip, deflate, br',
- accept: 'application/json'
- },
- data: function ({ channel, date }) {
- return {
- cil: [channel.site_id],
- d: date.valueOf()
- }
- }
- },
- parser: function ({ content, channel }) {
- const programs = []
- const items = parseItems(content, channel)
- items.forEach(item => {
- programs.push({
- title: item.et,
- description: item.epit,
- category: item.ec,
- start: dayjs(item.bsdt),
- stop: dayjs(item.bedt),
- season: item.sn,
- episode: item.en,
- image: item.pu ? `http://sky.de${item.pu}` : null
- })
- })
-
- return programs
- },
- async channels() {
- const axios = require('axios')
- const data = await axios
- .post(
- 'https://www.sky.de/sgtvg/service/getChannelList',
- { dom: 'de', s: 0, feed: 1 },
- {
- headers: {
- 'Content-Type': 'application/json',
- Referer: 'https://www.sky.de/tvguide-7599',
- 'X-Requested-With': 'XMLHttpRequest'
- }
- }
- )
- .then(r => r.data)
- .catch(console.log)
-
- let channels = []
- data.cl.forEach(item => {
- channels.push({
- lang: 'de',
- name: item.cn,
- site_id: item.ci
- })
- })
-
- return channels
- }
-}
-
-function parseContent(content, channel) {
- const json = JSON.parse(content)
- if (!Array.isArray(json.cl)) return null
- return json.cl.find(i => i.ci == channel.site_id)
-}
-
-function parseItems(content, channel) {
- const data = parseContent(content, channel)
- return data && Array.isArray(data.el) ? data.el : []
-}
diff --git a/sites/sky.de/sky.de.test.js b/sites/sky.de/sky.de.test.js
deleted file mode 100644
index bdcb8a15d..000000000
--- a/sites/sky.de/sky.de.test.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const { parser, url, request } = require('./sky.de.config.js')
-const fs = require('fs')
-const path = require('path')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-dayjs.extend(utc)
-
-const date = dayjs.utc('2022-02-28', 'YYYY-MM-DD').startOf('d')
-const channel = {
- site_id: '522',
- xmltv_id: 'WarnerTVComedyHD.de'
-}
-
-it('can generate valid url', () => {
- expect(url).toBe('https://www.sky.de/sgtvg/service/getBroadcastsForGrid')
-})
-
-it('can generate valid request method', () => {
- expect(request.method).toBe('POST')
-})
-
-it('can generate valid request data', () => {
- expect(request.data({ channel, date })).toMatchObject({
- cil: [channel.site_id],
- d: date.valueOf()
- })
-})
-
-it('can parse response', () => {
- const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
- const result = parser({ content, channel }).map(p => {
- p.start = p.start.toJSON()
- p.stop = p.stop.toJSON()
- return p
- })
-
- expect(result).toMatchObject([
- {
- title: 'King of Queens',
- description: 'Der Experte',
- category: 'Comedyserie',
- start: '2022-02-26T23:05:00.000Z',
- stop: '2022-02-26T23:30:00.000Z',
- season: '4',
- episode: '11',
- image: 'http://sky.de/static/img/program_guide/1522936_s.jpg'
- },
- {
- title: 'King of Queens',
- description: 'Speedy Gonzales',
- category: 'Comedyserie',
- start: '2022-02-26T23:30:00.000Z',
- stop: '2022-02-26T23:55:00.000Z',
- season: '4',
- episode: '12',
- image: 'http://sky.de/static/img/program_guide/1522937_s.jpg'
- }
- ])
-})
-
-it('can handle empty guide', () => {
- const result = parser({
- content: '[]'
- })
- expect(result).toMatchObject([])
-})