From e38c5138bdbd67eea20ec81c57f86378f322c2bf Mon Sep 17 00:00:00 2001 From: thomraider12 <168651587+thomraider12@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:33:51 +0000 Subject: [PATCH 01/31] =?UTF-8?q?Remove=20some=20MTV=20channels=20from=20P?= =?UTF-8?q?ortugal=20providers=20and=20fix=20Conta=20L=C3=A1=20feed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MEO removed E! Entertainment, Trace Toca, Trace Toca, MTV Portugal, MTV00s, MTV Live; fixed Conta Lá feed NOS removed MTV 00s and MTV Live; fixed Conta Lá feed Vodafone PT removed MTV 00s and MTV Live; fixed Conta Lá feed --- sites/meo.pt/meo.pt.channels.xml | 10 ++-------- sites/nostv.pt/nostv.pt.channels.xml | 7 +++---- sites/vodafone.pt/vodafone.pt.channels.xml | 3 +-- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/sites/meo.pt/meo.pt.channels.xml b/sites/meo.pt/meo.pt.channels.xml index 58d7164e8..1f6cc070b 100644 --- a/sites/meo.pt/meo.pt.channels.xml +++ b/sites/meo.pt/meo.pt.channels.xml @@ -48,7 +48,7 @@ CNN CNN Portugal Canção Nova - Conta Lá + Conta Lá Cubavision DAZN 1 DAZN 2 @@ -66,7 +66,6 @@ DORCEL TV Duck TV DEUTSCHE WELLE - E! Entertainment English Club TV Eurosport 1 Euronews @@ -112,9 +111,6 @@ MCM Top Mezzo Live Mezzo - MTV 00s - MTV Live - MTV Portugal NBA TV NEW Brasil News Now @@ -185,8 +181,6 @@ Telesur TLC TPA Notícias - Trace Brasil - Trace Toca Trace Urban Travelxp HD Travelxp 4K HDR @@ -217,4 +211,4 @@ ZDFNEO ZEE CINEMA ZEE TV - + \ No newline at end of file diff --git a/sites/nostv.pt/nostv.pt.channels.xml b/sites/nostv.pt/nostv.pt.channels.xml index 378f158c1..af1534cfc 100644 --- a/sites/nostv.pt/nostv.pt.channels.xml +++ b/sites/nostv.pt/nostv.pt.channels.xml @@ -1,3 +1,4 @@ + Canal Hollywood HD @@ -12,7 +13,6 @@ Record News TeleSUR MCM Top - MTV 00s M6 Sky News RTL @@ -142,7 +142,6 @@ TVI HD RTP Noticias HD CNN Portugal HD - MTV Live Discovery HD Eurosport 2 HD Canal 11 HD @@ -168,5 +167,5 @@ Dizi Now Sport TV 7 HD - Conta Lá - + Conta Lá + \ No newline at end of file diff --git a/sites/vodafone.pt/vodafone.pt.channels.xml b/sites/vodafone.pt/vodafone.pt.channels.xml index 7f2c332d8..092a70ba8 100644 --- a/sites/vodafone.pt/vodafone.pt.channels.xml +++ b/sites/vodafone.pt/vodafone.pt.channels.xml @@ -33,7 +33,6 @@ 24h CNBC TPA - MTV 00s Pro TV International Bloomberg Mezzo @@ -146,5 +145,5 @@ BabyTV História W-Sport - Conta Lá + Conta Lá From 44ec0a886d9bfad7deb0f62ce6cbc79cfe58624a Mon Sep 17 00:00:00 2001 From: thomraider12 <168651587+thomraider12@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:40:19 +0000 Subject: [PATCH 02/31] Fix bug in NOS xml --- sites/nostv.pt/nostv.pt.channels.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/sites/nostv.pt/nostv.pt.channels.xml b/sites/nostv.pt/nostv.pt.channels.xml index af1534cfc..0eb5ba713 100644 --- a/sites/nostv.pt/nostv.pt.channels.xml +++ b/sites/nostv.pt/nostv.pt.channels.xml @@ -1,4 +1,3 @@ - Canal Hollywood HD From 73ec5ee0fb8faf63676ca42ddeb2966272f19dd2 Mon Sep 17 00:00:00 2001 From: CasperMcFadden95 <145611964+CasperMcFadden95@users.noreply.github.com> Date: Sat, 10 Jan 2026 15:35:52 +0000 Subject: [PATCH 03/31] Update freeview.co.uk.channels.xml --- .../freeview.co.uk.channels.xml | 217 +++++++++--------- 1 file changed, 108 insertions(+), 109 deletions(-) diff --git a/sites/freeview.co.uk/freeview.co.uk.channels.xml b/sites/freeview.co.uk/freeview.co.uk.channels.xml index 10e9fec90..eee24034c 100644 --- a/sites/freeview.co.uk/freeview.co.uk.channels.xml +++ b/sites/freeview.co.uk/freeview.co.uk.channels.xml @@ -1,14 +1,6 @@ - BBC ONE Lon - BBC TWO - BBC THREE - BBC NEWS BBC Red Button - BBC FOUR - CBBC - CBeebies - BBC Parliament BBC R5L BBC 5SX BBC 6 Music @@ -25,146 +17,153 @@ BBC Radio 2 BBC Radio 3 BBC Radio 4 - BBC RB 1 - ITV1 - ITV3 - ITV2 - ITV4 - ITV Quiz - ITV1+1 - Channel 4 - Film4 - More 4 - E4 - Channel 4+1 - E4+1 - 4seven - 5 That's TV 3 - 5STAR - YAAAS! - 5USA - U&DaveJaVu - 5 +1 - QVC - MBC - Blaze - Blaze+1 - QVC2 - TRUE CRIME - TRUE CRIME XTRA - WildEarth - LEGEND Sonlife On Demand 365 Channelbox - UK RADIO PORTAL - Great! Action - Great! Movies - TJC That's Oldies - ITV4+1 - ITV2+1 - ITV3+1 - 5ACTION CNA Originals GIGS EuroNews Trailblazer Odyssey TV - Ketchup TV - U&Drama Ketchup Too ROK - Revelation TV - God TV - Nolly Africa - Alaraby Network - POP Max - Al Jazeera English - Tiny Pop - Al Jazeera Arabic Global Arabic + - NHK WORLD - Newsmax Amazing Facts New Media TV - Together TV - FRANCE 24 Nosey Shop On TV Purpose Media - Talk - BBC TWO HD - BBC ONE Lon HD - ITV1 HD - Channel 4 HD - 5 HD - BBC THREE HD - BBC FOUR HD - CBBC HD - CBeebies HD - U&Eden LEGEND XTRA - TBN UK - 5SELECT - Sky News - Sky Arts - Sky Mix - Challenge - U&Dave - U&Drama+1 - E4 Extra - Film4+1 - talkSPORT RNIB Connect Heart Capital Classic FM LBC - Food Network That's TV 2 SonLife Must Have Ideas - Really - Quest Red - QUEST+1 - Gems TV - U&Yesterday - Ideal World + That's 80s Smooth Radio - Great! TV - Jewellery Maker Hobbycraft TV - Great! Christmas - QUEST - GB News - Together TV+1 - POP UP - DMAX Rewind TV - POP Together TV IP - HobbyMaker - Great! Mystery - That's TV (UK) - PBS America - HGTV That's Melody - U&W Premier Radio - TalkingPictures TV Great! Player - GREAT! romance mix - London TV - 3ABN + Great! Romance Mix India Today - TRACE UK - Pop Player + MBC Group wedotv movies It Is Written TV OUTflix Proud High Street TV + Cartoon Classics + wedotv Movies UK + Nolly Africa + 4seven + 5ACTION + 5SELECT + 5STAR + 5USA AL ARABIYA + Alaraby Network + Al Jazeera Arabic + Al Jazeera English ASHARQ NEWS + BBC FOUR HD + BBC FOUR + BBC NEWS + BBC ONE Lon + BBC ONE Lon HD + BBC Parliament + BBC RB 1 + BBC THREE HD + BBC THREE + BBC TWO + BBC TWO HD + Blaze+1 + Blaze + CBBC HD + CBBC + CBeebies HD + CBeebies + Challenge + Channel 4 HD + Channel 4+1 + Channel 4 + 5 HD + 5 +1 + 5 + DMAX + E4+1 + E4 + E4 Extra + Film4+1 + Film4 + Food Network + FRANCE 24 + GB News + Gemporia + God TV + Great! Action + Great! Mystery + Great! Movies + Great! Romance + Great! TV + HGTV + HobbyMaker + Ideal World + ITV1 HD + ITV1 + ITV1+1 + ITV2+1 + ITV2 + ITV3+1 + ITV3 + ITV4+1 + ITV4 + ITV Quiz + Jewellery Maker + Ketchup TV + LEGEND + London TV + MBC + More 4 + Newsmax + NHK WORLD + PBS America + POP + POP UP + QUEST+1 + QUEST + Quest Red + QVC2 + QVC + Really + Revelation TV + Sky Arts + Sky Mix + Sky News + TalkingPictures TV + talkSPORT + Talk + TBN UK + That's TV (UK) + Tiny Pop + TJC + Together TV+1 + Together TV + TRUE CRIME + TRUE CRIME XTRA + U&Dave + U&DaveJaVu + U&Drama+1 + U&Drama + U&Eden + U&W + U&Yesterday + WildEarth + YAAAS! From 57a82236f5a3e527a24a0121b9b4dd1b4fe1515d Mon Sep 17 00:00:00 2001 From: CyberPoison <60718477+CyberPoison@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:28:27 +0100 Subject: [PATCH 04/31] Update Init --- sites/meo.pt/__data__/content.json | 27 ++++- sites/meo.pt/meo.pt.config.js | 155 ++++++++++------------------- sites/meo.pt/meo.pt.test.js | 35 +++---- 3 files changed, 94 insertions(+), 123 deletions(-) diff --git a/sites/meo.pt/__data__/content.json b/sites/meo.pt/__data__/content.json index 66e68008a..7dd23d0f6 100644 --- a/sites/meo.pt/__data__/content.json +++ b/sites/meo.pt/__data__/content.json @@ -1 +1,26 @@ -{"d":{"__type":"Ptsi.Isites.GridTv.CanaisService.GridTV","ExtensionData":{},"services":[],"channels":[{"__type":"Ptsi.Isites.GridTv.CanaisService.Channels","ExtensionData":{},"id":100,"name":"RTP MEMÓRIA","sigla":"RTPM","friendlyUrlName":"RTP_Memoria","url":"https://meogo.meo.pt/direto?canalUrl=RTP_Memoria","meogo":true,"logo":"https://www.meo.pt/PublishingImages/canais/rtp-memoria.png","isAdult":false,"categories":[{"ExtensionData":{},"id":4,"name":"Entretenimento"}],"types":[{"ExtensionData":{},"id":0,"name":"Gravações Automáticas"},{"ExtensionData":{},"id":1,"name":"Restart TV"}],"programs":[{"ExtensionData":{},"date":"1-12-2022","timeIni":"23:35","timeEnd":"00:17","number":15992358,"uniqueId":"27621378","name":"Walker, O Ranger Do Texas T6 - Ep. 14","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"103787"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"00:17","timeEnd":"01:07","number":17690651,"uniqueId":"27621379","name":"O Barco Do Amor T7 - Ep. 21","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"117870"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"01:07","timeEnd":"01:57","number":17690652,"uniqueId":"27621380","name":"Um Anjo Na Terra T3 - Ep. 22","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"117869"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"01:57","timeEnd":"02:39","number":15992358,"uniqueId":"27621381","name":"Walker, O Ranger Do Texas T6 - Ep. 14","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"103787"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"02:39","timeEnd":"03:42","number":17690659,"uniqueId":"27621382","name":"5 Para A Meia-Noite T7 - Ep. 29","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"118268"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"03:42","timeEnd":"04:33","number":13223378,"uniqueId":"27621383","name":"O Conde D´Abranhos - Ep. 9","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"1367"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"04:33","timeEnd":"05:02","number":17690660,"uniqueId":"27621384","name":"Quebra-Cabeças T4 - Ep. 60","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"91370"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"05:02","timeEnd":"05:19","number":17690661,"uniqueId":"27621385","name":"As Aventuras De Eva - Ep. 9","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"118559"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"05:19","timeEnd":"06:02","number":13338966,"uniqueId":"27621386","name":"Bem-Vindos A Beirais T4 - Ep. 36","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"80897"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"06:02","timeEnd":"06:29","number":12414718,"uniqueId":"27621387","name":"Horizontes Da Memória T6 - Ep. 19","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"74413"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"06:29","timeEnd":"06:56","number":13492284,"uniqueId":"27621388","name":"SMS - Ser Mais Sabedor T1 - Ep. 49","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"81681"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"06:56","timeEnd":"07:00","number":17733452,"uniqueId":"27621389","name":"A Música Portuguesa A Gostar Dela Própria T1 - Ep. 103","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"87775"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"07:00","timeEnd":"07:45","number":13290499,"uniqueId":"27564192","name":"Vila Faia - Ep. 47","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"47671"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"07:45","timeEnd":"08:15","number":17690662,"uniqueId":"27564176","name":"Palavras Cruzadas - Ep. 16","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"71429"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"08:15","timeEnd":"09:00","number":12441944,"uniqueId":"27564188","name":"Portugueses Pelo Mundo T5 - Ep. 24","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"72818"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"09:00","timeEnd":"09:50","number":12663593,"uniqueId":"27564181","name":"Gente Fina É Outra Coisa - Ep. 9","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"76694"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"09:50","timeEnd":"10:35","number":17690663,"uniqueId":"27636531","name":"Só Visto! T1 - Ep. 24","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"116128"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"10:35","timeEnd":"11:00","number":17690670,"uniqueId":"27636532","name":"A Essência","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"961481536"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"11:00","timeEnd":"11:43","number":17690671,"uniqueId":"27636533","name":"Patrulha Da Noite T2 - Ep. 9","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"118560"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"11:43","timeEnd":"12:35","number":17690664,"uniqueId":"27636534","name":"Terra Mãe - Ep. 93","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"71427"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"12:35","timeEnd":"13:00","number":17647748,"uniqueId":"27564194","name":"As Aventuras De Eva - Ep. 5","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"118559"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"13:00","timeEnd":"14:00","number":17690665,"uniqueId":"27564168","name":"Em Mouriscas Acontece","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":""},{"ExtensionData":{},"date":"2-12-2022","timeIni":"14:00","timeEnd":"14:51","number":13732638,"uniqueId":"27564162","name":"Donos Disto Tudo T2 - Ep. 15","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"85899"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"14:51","timeEnd":"15:00","number":17621219,"uniqueId":"27636535","name":"Fragmentos - Ep. 43","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"116736"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"15:00","timeEnd":"15:45","number":12723927,"uniqueId":"27564197","name":"Bem-Vindos A Beirais T3 - Ep. 124","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"71872"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"15:45","timeEnd":"16:00","number":17690673,"uniqueId":"27564159","name":"A Cidade Na Ponta Dos Dedos T2 - Ep. 43","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"116737"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"16:00","timeEnd":"17:00","number":12852209,"uniqueId":"27564209","name":"As Grandes Batalhas De Portugal - Ep. 1","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"74660"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"17:00","timeEnd":"17:33","number":12939074,"uniqueId":"27573164","name":"Na Paz Dos Anjos - Ep. 137","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"72967"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"17:33","timeEnd":"18:18","number":17690666,"uniqueId":"27636536","name":"Filhos Do Vento - Ep. 138","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"47657"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"18:18","timeEnd":"18:43","number":10334871,"uniqueId":"27636537","name":"Telerural T3 - Ep. 6","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"51886"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"18:43","timeEnd":"19:40","number":8319968,"uniqueId":"27636538","name":"Herman Enciclopédia T2 - Ep. 5","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"39546"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"19:40","timeEnd":"20:09","number":17690667,"uniqueId":"27636539","name":"Sim, Chef! T2 - Ep. 1","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"119065"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"20:09","timeEnd":"21:00","number":12414714,"uniqueId":"27636540","name":"Mulheres De Abril - Ep. 5","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"74937"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"21:00","timeEnd":"21:45","number":12723927,"uniqueId":"27573170","name":"Bem-Vindos A Beirais T3 - Ep. 124","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"71872"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"21:45","timeEnd":"22:36","number":17690668,"uniqueId":"27636541","name":"O Barco Do Amor T7 - Ep. 22","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"117870"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"22:36","timeEnd":"23:25","number":17690669,"uniqueId":"27636542","name":"Um Anjo Na Terra T3 - Ep. 23","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"117869"},{"ExtensionData":{},"date":"2-12-2022","timeIni":"23:25","timeEnd":"00:08","number":16036114,"uniqueId":"27573173","name":"Walker, O Ranger Do Texas T6 - Ep. 15","synopse":null,"imageM":null,"imageL":null,"imageXL":null,"recordType":0,"recordingDefinitionID":"00000000-0000-0000-0000-000000000000","recordingProgramID":"00000000-0000-0000-0000-000000000000","seriesID":"103787"}],"moreInfo":{"ExtensionData":{},"Label":"","Link":""},"programacaoCanal":{"ExtensionData":{},"Label":"Programação","Link":"canal=RTPM"}}],"filters":{"ExtensionData":{},"types":[{"ExtensionData":{},"id":0,"name":"Gravações Automáticas"},{"ExtensionData":{},"id":1,"name":"Restart TV"}],"categories":[{"ExtensionData":{},"id":4,"name":"Entretenimento"}]}}} \ No newline at end of file +{ + "Status": "OK", + "StatusCode": 200, + "Result": [ + { + "CallLetter": "RTP1", + "EndDate": "2026-01-23T00:04:00", + "Id": 42314383, + "IsAdultContent": false, + "ProgramId": 22604754, + "StartDate": "2026-01-22T23:40:00", + "Synopsis": "'Barman' é uma série de comédia dramática sobre um jovem comediante que começa a trabalhar como Barman porque precisa de arranjar dinheiro depressa, pelo caminho é obrigado a lidar com a vida noturna e conciliar duas realidades diferentes.", + "Title": "Barman - Ep. 4" + }, + { + "CallLetter": "RTP1", + "EndDate": "2026-01-23T00:30:00", + "Id": 42314384, + "IsAdultContent": false, + "ProgramId": 22604763, + "StartDate": "2026-01-23T00:04:00", + "Synopsis": "'Barman' é uma série de comédia dramática sobre um jovem comediante que começa a trabalhar como Barman porque precisa de arranjar dinheiro depressa, pelo caminho é obrigado a lidar com a vida noturna e conciliar duas realidades diferentes.", + "Title": "Barman - Ep. 5" + } + ] +} \ No newline at end of file diff --git a/sites/meo.pt/meo.pt.config.js b/sites/meo.pt/meo.pt.config.js index e5c9f2b0f..82d5f1cf9 100644 --- a/sites/meo.pt/meo.pt.config.js +++ b/sites/meo.pt/meo.pt.config.js @@ -3,65 +3,55 @@ const { DateTime } = require('luxon') module.exports = { site: 'meo.pt', days: 2, - url: 'https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getProgramsFromChannels', + url: function ({ channel, date }) { + return `https://meogouser.apps.meo.pt/Services/GridTv/GridTv.svc/GetLiveChannelProgramsByDate?callLetter=${channel.site_id}&date=${date.format('YYYY-MM-DD')}&userAgent=IPTV_OFR_GTV` + }, request: { - method: 'POST', + method: 'GET', headers: { - Origin: 'https://www.meo.pt', - 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; en-US Trident/4.0)' - }, - data: function ({ channel, date }) { - return { - service: 'channelsguide', - channels: [channel.site_id], - dateStart: date.format('YYYY-MM-DDT00:00:00-00:00'), - dateEnd: date.add(1, 'd').format('YYYY-MM-DDT00:00:00-00:00'), - accountID: '' - } + 'accept': '*/*', + 'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,pt;q=0.6,cs;q=0.5', + 'cache-control': 'no-cache', + 'origin': 'https://www.meo.pt', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.meo.pt/', + 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', + 'sec-ch-ua-mobile': '?1', + 'sec-ch-ua-platform': '"Android"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36' } }, - async parser({ content }) { - const axios = require('axios') + async parser({ content, channel }) { let programs = [] const items = parseItems(content) if (!items.length) return programs - // simple per-run in-memory cache - const detailsCache = new Map() - for (const item of items) { - const start = parseStart(item) - let stop = parseStop(item) - if (stop < start) { - stop = stop.plus({ days: 1 }) - } - - let description = '' - let image = '' - - const programID = item.uniqueId || null - if (programID) { - let details = detailsCache.get(programID) - if (!details) { - details = await fetchProgramDetails(programID, axios).catch(() => null) - if (details) detailsCache.set(programID, details) - } - if (details) { - description = details.description || description - image = details.image || image - } - } + const start = DateTime.fromISO(item.StartDate, { zone: 'Europe/Lisbon' }).toUTC() + const stop = DateTime.fromISO(item.EndDate, { zone: 'Europe/Lisbon' }).toUTC() const prog = { - title: item.name || 'Sem título', + title: item.Title || 'Sem título', start, stop } - if (description) prog.description = description - if (image) { + + if (item.Synopsis) { + prog.description = item.Synopsis + } + + // Construct image URL using the same logic as before if possible + if (item.Title && channel.site_id) { + const encodedTitle = encodeURIComponent(item.Title) + const image = `https://proxycache.online.meo.pt/eemstb/ImageHandler.ashx?evTitle=${encodedTitle}&chCallLetter=${channel.site_id}&profile=16_9&width=600` prog.icon = { src: image } prog.image = image } + programs.push(prog) } @@ -70,84 +60,45 @@ module.exports = { async channels() { const axios = require('axios') const data = await axios - .post('https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getGridAnon', null, { + .get('https://meogouser.apps.meo.pt/Services/GridTv/GridTv.svc/GetContentsForChannels?userAgent=IPTV_OFR_GTV', { headers: { - Origin: 'https://www.meo.pt', - 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; en-US Trident/4.0)' + 'accept': '*/*', + 'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,pt;q=0.6,cs;q=0.5', + 'cache-control': 'no-cache', + 'origin': 'https://www.meo.pt', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.meo.pt/', + 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', + 'sec-ch-ua-mobile': '?1', + 'sec-ch-ua-platform': '"Android"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36' } }) .then(r => r.data) .catch(console.log) - // channel logo at data.d.channels.logo - - return data.d.channels + return data.Result .map(item => { return { lang: 'pt', - site_id: item.sigla, - name: item.name + site_id: item.CallLetter, + name: item.Title } }) .filter(channel => channel.site_id) } } -function parseStart(item) { - return DateTime.fromFormat(`${item.date} ${item.timeIni}`, 'd-M-yyyy HH:mm', { - zone: 'Europe/Lisbon' - }).toUTC() -} - -function parseStop(item) { - return DateTime.fromFormat(`${item.date} ${item.timeEnd}`, 'd-M-yyyy HH:mm', { - zone: 'Europe/Lisbon' - }).toUTC() -} - function parseItems(content) { if (!content) return [] - const data = JSON.parse(content) - const programs = data?.d?.channels?.[0]?.programs - - return Array.isArray(programs) ? programs : [] -} - -async function fetchProgramDetails(programID, axiosInstance) { try { - const response = await axiosInstance.post( - 'https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getProgramDetails', - { - service: 'programdetail', - programID: String(programID), - accountID: '' - }, - { - headers: { - Origin: 'https://www.meo.pt', - 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; en-US Trident/4.0)' - }, - timeout: 10000 - } - ) - - const data = response.data - // Response structure has program data directly in data.d - const program = data?.d - if (!program || typeof program !== 'object') return null - - // Build image URL using MEO's image handler - let image = null - if (program.progName && program.channelSigla) { - const encodedTitle = encodeURIComponent(program.progName) - image = `https://proxycache.online.meo.pt/eemstb/ImageHandler.ashx?evTitle=${encodedTitle}&chCallLetter=${program.channelSigla}&profile=16_9&width=600` - } - - const description = program.description || null - - return { description, image } + const data = typeof content === 'string' ? JSON.parse(content) : content + return Array.isArray(data.Result) ? data.Result : [] } catch { - // Silent fail returning null so parser continues - return null + return [] } } diff --git a/sites/meo.pt/meo.pt.test.js b/sites/meo.pt/meo.pt.test.js index d86e9d2d9..26b5ce0f5 100644 --- a/sites/meo.pt/meo.pt.test.js +++ b/sites/meo.pt/meo.pt.test.js @@ -18,37 +18,28 @@ const channel = { } it('can generate valid url', () => { - expect(url).toBe( - 'https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getProgramsFromChannels' + expect(url({ channel, date })).toBe( + 'https://meogouser.apps.meo.pt/Services/GridTv/GridTv.svc/GetLiveChannelProgramsByDate?callLetter=RTPM&date=2022-12-02&userAgent=IPTV_OFR_GTV' ) }) it('can generate valid request method', () => { - expect(request.method).toBe('POST') + expect(request.method).toBe('GET') }) it('can generate valid request headers', () => { expect(request.headers).toMatchObject({ - Origin: 'https://www.meo.pt' - }) -}) - -it('can generate valid request method', () => { - expect(request.data({ channel, date })).toMatchObject({ - service: 'channelsguide', - channels: ['RTPM'], - dateStart: '2022-12-02T00:00:00-00:00', - dateEnd: '2022-12-03T00:00:00-00:00', - accountID: '' + 'origin': 'https://www.meo.pt', + 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36' }) }) it('can parse response', async () => { - const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json')) + const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'), 'utf-8') - axios.post.mockResolvedValue({ data: {} }) + axios.get.mockResolvedValue({ data: {} }) - let results = await parser({ content }) + let results = await parser({ content, channel }) results = results.map(p => { p.start = p.start.toJSON() p.stop = p.stop.toJSON() @@ -56,9 +47,13 @@ it('can parse response', async () => { }) expect(results[0]).toMatchObject({ - start: '2022-12-01T23:35:00.000Z', - stop: '2022-12-02T00:17:00.000Z', - title: 'Walker, O Ranger Do Texas T6 - Ep. 14' + start: '2026-01-22T23:40:00.000Z', + stop: '2026-01-23T00:04:00.000Z', + title: 'Barman - Ep. 4', + description: "'Barman' é uma série de comédia dramática sobre um jovem comediante que começa a trabalhar como Barman porque precisa de arranjar dinheiro depressa, pelo caminho é obrigado a lidar com a vida noturna e conciliar duas realidades diferentes.", + icon: { + src: 'https://proxycache.online.meo.pt/eemstb/ImageHandler.ashx?evTitle=Barman%20-%20Ep.%204&chCallLetter=RTPM&profile=16_9&width=600' + } }) }) From 4434f6f5a370927d913b0ba704b28e8f418acc76 Mon Sep 17 00:00:00 2001 From: CyberPoison <60718477+CyberPoison@users.noreply.github.com> Date: Sat, 24 Jan 2026 03:31:40 +0100 Subject: [PATCH 05/31] Update Init --- sites/nostv.pt/__data__/data.json | 68 ++++++++++++++++++++++++++++++- sites/nostv.pt/nostv.pt.config.js | 37 ++++++++++------- sites/nostv.pt/nostv.pt.test.js | 19 ++++----- 3 files changed, 98 insertions(+), 26 deletions(-) diff --git a/sites/nostv.pt/__data__/data.json b/sites/nostv.pt/__data__/data.json index 205e57974..6725777c5 100644 --- a/sites/nostv.pt/__data__/data.json +++ b/sites/nostv.pt/__data__/data.json @@ -1 +1,67 @@ -[{"CoreId":"2023121151009543","AssetId":"EPGE2023121151009543","ContentId":"epg@2023121151009543","ProgramId":"3011502","AggregatorId":"2967456","DateFullEventId":"2023121151009543","GridItemsLink":"/v2/browse/epg@2023121151009543/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009543/PlayListTray/items","UtcDateTimeStart":"2023-12-11T16:30:00Z","UtcDateTimeEnd":"2023-12-11T17:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Village Vets","SubTitle":"","RatingDisplay":"NC","GenreDisplay":"Reality TV","SeriesId":"142241","Description":"A história de dois melhores amigos veterinários e o seu extraordinário trabalho na Austrália.","ReleaseYear":"2014","Rating":0,"Season":1,"Episode":12,"Duration":30,"ProgramId":3011502,"AggregatorId":2967456,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"8329ed1aec5d4c0faa2056972256ff9f","Url":"http://vip.pam.local.internal/PAM.Images/Store/8329ed1aec5d4c0faa2056972256ff9f","Type":1}]},{"CoreId":"2023121151009544","AssetId":"EPGE2023121151009544","ContentId":"epg@2023121151009544","ProgramId":"3161537","AggregatorId":"2165665","DateFullEventId":"2023121151009544","GridItemsLink":"/v2/browse/epg@2023121151009544/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009544/PlayListTray/items","UtcDateTimeStart":"2023-12-11T17:00:00Z","UtcDateTimeEnd":"2023-12-11T18:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Histórias Clínicas","SubTitle":"Associações","RatingDisplay":"M12","GenreDisplay":"Saúde","SeriesId":"102905","Description":"Processo de Decisão Clínica.","ReleaseYear":"2018","Rating":80,"Season":7,"Episode":13,"Duration":60,"ProgramId":3161537,"AggregatorId":2165665,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"818dba4817a7464f9e8433620270b01d","Url":"http://vip.pam.local.internal/PAM.Images/Store/818dba4817a7464f9e8433620270b01d","Type":1}]},{"CoreId":"2023121151009545","AssetId":"EPGE2023121151009545","ContentId":"epg@2023121151009545","ProgramId":"3357379","AggregatorId":"2182966","DateFullEventId":"2023121151009545","GridItemsLink":"/v2/browse/epg@2023121151009545/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009545/PlayListTray/items","UtcDateTimeStart":"2023-12-11T18:00:00Z","UtcDateTimeEnd":"2023-12-11T19:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Corpo Clínico","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Saúde","SeriesId":"103390","Description":"Farmacovigilância.","ReleaseYear":"2018","Rating":1,"Season":12,"Episode":5,"Duration":60,"ProgramId":3357379,"AggregatorId":2182966,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"a060ca5930444d3a864ad20615e7df33","Url":"http://vip.pam.local.internal/PAM.Images/Store/a060ca5930444d3a864ad20615e7df33","Type":1}]},{"CoreId":"2023121151009546","AssetId":"EPGE2023121151009546","ContentId":"epg@2023121151009546","ProgramId":"3364579","AggregatorId":"3161534","DateFullEventId":"2023121151009546","GridItemsLink":"/v2/browse/epg@2023121151009546/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009546/PlayListTray/items","UtcDateTimeStart":"2023-12-11T19:00:00Z","UtcDateTimeEnd":"2023-12-11T20:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Caixa de Pandora","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Talk-Show","SeriesId":"152921","Description":"Programa de 45 minutos, em estúdio, que reúne 4 mulheres de diversas idades e backgrounds que conversam todas as semanas sobre temas ligados à saúde e bem-estar, mas também à sexualidade, vida em família, ao trabalho, etc. É uma tertúlia no feminino.","ReleaseYear":"2023","Rating":80,"Season":4,"Episode":13,"Duration":60,"ProgramId":3364579,"AggregatorId":3161534,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"0ba7dccc8d1d459083c90666a2250776","Url":"http://vip.pam.local.internal/PAM.Images/Store/0ba7dccc8d1d459083c90666a2250776","Type":1}]},{"CoreId":"2023121151009547","AssetId":"EPGE2023121151009547","ContentId":"epg@2023121151009547","ProgramId":"3161541","AggregatorId":"2166905","DateFullEventId":"2023121151009547","GridItemsLink":"/v2/browse/epg@2023121151009547/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009547/PlayListTray/items","UtcDateTimeStart":"2023-12-11T20:00:00Z","UtcDateTimeEnd":"2023-12-11T21:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Anatomia De Vénus","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Entrevista","SeriesId":"102934","Description":"Sexualidade e Deficiência.","ReleaseYear":"2018","Rating":80,"Season":7,"Episode":13,"Duration":60,"ProgramId":3161541,"AggregatorId":2166905,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"5a9c92a158084235901d63e0cda418df","Url":"http://vip.pam.local.internal/PAM.Images/Store/5a9c92a158084235901d63e0cda418df","Type":1}]},{"CoreId":"2023121151009548","AssetId":"EPGE2023121151009548","ContentId":"epg@2023121151009548","ProgramId":"3072059","AggregatorId":"3066918","DateFullEventId":"2023121151009548","GridItemsLink":"/v2/browse/epg@2023121151009548/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009548/PlayListTray/items","UtcDateTimeStart":"2023-12-11T21:00:00Z","UtcDateTimeEnd":"2023-12-11T22:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Heart Transplant: A Chance To Live","SubTitle":"","RatingDisplay":"NC","GenreDisplay":"Saúde","SeriesId":"146850","Description":"Acompanhamos a vida de sete doentes criticos à espera para fazerem transplantes de coração.","ReleaseYear":"2018","Rating":0,"Season":1,"Episode":2,"Duration":60,"ProgramId":3072059,"AggregatorId":3066918,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"aba563a9ff3748de8a3551633f3bd1cb","Url":"http://vip.pam.local.internal/PAM.Images/Store/aba563a9ff3748de8a3551633f3bd1cb","Type":1}]},{"CoreId":"2023121151009549","AssetId":"EPGE2023121151009549","ContentId":"epg@2023121151009549","ProgramId":"3361332","AggregatorId":"3103070","DateFullEventId":"2023121151009549","GridItemsLink":"/v2/browse/epg@2023121151009549/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009549/PlayListTray/items","UtcDateTimeStart":"2023-12-11T22:00:00Z","UtcDateTimeEnd":"2023-12-11T22:30:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Entre Turnos","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Saúde","SeriesId":"149976","Description":"Vasco Lança (jogador de basquetebol e estudante de medicina).","ReleaseYear":"2022","Rating":80,"Season":1,"Episode":11,"Duration":30,"ProgramId":3361332,"AggregatorId":3103070,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"2e0fa1bc7d36404ab52dafcf450137d2","Url":"http://vip.pam.local.internal/PAM.Images/Store/2e0fa1bc7d36404ab52dafcf450137d2","Type":1}]},{"CoreId":"2023121151009550","AssetId":"EPGE2023121151009550","ContentId":"epg@2023121151009550","ProgramId":"3367957","AggregatorId":"3333429","DateFullEventId":"2023121151009550","GridItemsLink":"/v2/browse/epg@2023121151009550/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009550/PlayListTray/items","UtcDateTimeStart":"2023-12-11T22:30:00Z","UtcDateTimeEnd":"2023-12-11T23:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Fact Check","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entretenimento","SeriesId":"164520","Description":"Ouviu dizer que não deve misturar melancia e vinho na mesma refeição? Contaram-lhe que aquecer refeições no micro-ondas provoca cancro? No outro dia, viu nas redes sociais alguém afirmar que só vai ao psiquiatra quem tem doenças graves?","ReleaseYear":"2023","Rating":1,"Season":1,"Episode":11,"Duration":30,"ProgramId":3367957,"AggregatorId":3333429,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"6b08d78551e745899ff8db0fea2b8680","Url":"http://vip.pam.local.internal/PAM.Images/Store/6b08d78551e745899ff8db0fea2b8680","Type":1}]},{"CoreId":"2023121151009551","AssetId":"EPGE2023121151009551","ContentId":"epg@2023121151009551","ProgramId":"3365804","AggregatorId":"2165712","DateFullEventId":"2023121151009551","GridItemsLink":"/v2/browse/epg@2023121151009551/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121151009551/PlayListTray/items","UtcDateTimeStart":"2023-12-11T23:00:00Z","UtcDateTimeEnd":"2023-12-12T00:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Check Up","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Debate","SeriesId":"102906","Description":"Para debater o futuro da saúde em Portugal, todas as semanas abrimos antena a “Check up”. O programa promete reunir os principais protagonistas do setor para discutirem em conjunto os grandes temas que preocupam este universo.","ReleaseYear":"2018","Rating":1,"Season":10,"Episode":14,"Duration":60,"ProgramId":3365804,"AggregatorId":2165712,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"5bf507f275934d369ceb7a790251bd1e","Url":"http://vip.pam.local.internal/PAM.Images/Store/5bf507f275934d369ceb7a790251bd1e","Type":1}]},{"CoreId":"2023121251009807","AssetId":"EPGE2023121251009807","ContentId":"epg@2023121251009807","ProgramId":"3364404","AggregatorId":"2460399","DateFullEventId":"2023121251009807","GridItemsLink":"/v2/browse/epg@2023121251009807/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009807/PlayListTray/items","UtcDateTimeStart":"2023-12-12T00:00:00Z","UtcDateTimeEnd":"2023-12-12T00:30:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Doutor Ajuda","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Saúde","SeriesId":"112361","Description":"O que é a toxina botulínica e suas utilizações.","ReleaseYear":"2023","Rating":1,"Season":3,"Episode":9,"Duration":30,"ProgramId":3364404,"AggregatorId":2460399,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"dfc67678e6de4a2baf23cd16a039684b","Url":"http://vip.pam.local.internal/PAM.Images/Store/dfc67678e6de4a2baf23cd16a039684b","Type":1}]},{"CoreId":"2023121251009808","AssetId":"EPGE2023121251009808","ContentId":"epg@2023121251009808","ProgramId":"2207459","AggregatorId":"2165669","DateFullEventId":"2023121251009808","GridItemsLink":"/v2/browse/epg@2023121251009808/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009808/PlayListTray/items","UtcDateTimeStart":"2023-12-12T00:30:00Z","UtcDateTimeEnd":"2023-12-12T01:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Atendimento Permanente","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Reality TV","SeriesId":"102919","Description":"No Atendimento Permanente desta semana vamos conhecer o dia a dia de um fisiatra.","ReleaseYear":"2018","Rating":1,"Season":1,"Episode":6,"Duration":30,"ProgramId":2207459,"AggregatorId":2165669,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"7973715e80b449afaeea3a23aa830fa0","Url":"http://vip.pam.local.internal/PAM.Images/Store/7973715e80b449afaeea3a23aa830fa0","Type":1}]},{"CoreId":"2023121251009809","AssetId":"EPGE2023121251009809","ContentId":"epg@2023121251009809","ProgramId":"3161541","AggregatorId":"2166905","DateFullEventId":"2023121251009809","GridItemsLink":"/v2/browse/epg@2023121251009809/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009809/PlayListTray/items","UtcDateTimeStart":"2023-12-12T01:00:00Z","UtcDateTimeEnd":"2023-12-12T02:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Anatomia De Vénus","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Entrevista","SeriesId":"102934","Description":"Sexualidade e Deficiência.","ReleaseYear":"2018","Rating":80,"Season":7,"Episode":13,"Duration":60,"ProgramId":3161541,"AggregatorId":2166905,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"5a9c92a158084235901d63e0cda418df","Url":"http://vip.pam.local.internal/PAM.Images/Store/5a9c92a158084235901d63e0cda418df","Type":1}]},{"CoreId":"2023121251009810","AssetId":"EPGE2023121251009810","ContentId":"epg@2023121251009810","ProgramId":"3047405","AggregatorId":"140870","DateFullEventId":"2023121251009810","GridItemsLink":"/v2/browse/epg@2023121251009810/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009810/PlayListTray/items","UtcDateTimeStart":"2023-12-12T02:00:00Z","UtcDateTimeEnd":"2023-12-12T03:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Sete Vidas","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entrevista","SeriesId":"116562","Description":"Anorexia, perturbação bipolar, depressão, comportamentos aditivos, dor crónica ou comportamento obsessivo-compulsivo são patologias psicológicas que a conhecida psicóloga clínica Joana Amaral Dias vai retratar através de uma conversa com uma figura pública que tenha vivenciado e superado o problema.","ReleaseYear":"2022","Rating":1,"Season":3,"Episode":8,"Duration":60,"ProgramId":3047405,"AggregatorId":140870,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"245f7c92250d443dbfa923d4a7cdda30","Url":"http://vip.pam.local.internal/PAM.Images/Store/245f7c92250d443dbfa923d4a7cdda30","Type":1}]},{"CoreId":"2023121251009811","AssetId":"EPGE2023121251009811","ContentId":"epg@2023121251009811","ProgramId":"2602834","AggregatorId":"2597243","DateFullEventId":"2023121251009811","GridItemsLink":"/v2/browse/epg@2023121251009811/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009811/PlayListTray/items","UtcDateTimeStart":"2023-12-12T03:00:00Z","UtcDateTimeEnd":"2023-12-12T04:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Histórias Clínicas: Dra. Sofia Braga","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Talk-Show","SeriesId":"120596","Description":"Rastreio cancro prostata.","ReleaseYear":"2020","Rating":80,"Season":6,"Episode":5,"Duration":60,"ProgramId":2602834,"AggregatorId":2597243,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"818dba4817a7464f9e8433620270b01d","Url":"http://vip.pam.local.internal/PAM.Images/Store/818dba4817a7464f9e8433620270b01d","Type":1}]},{"CoreId":"2023121251009812","AssetId":"EPGE2023121251009812","ContentId":"epg@2023121251009812","ProgramId":"2554643","AggregatorId":"1059808","DateFullEventId":"2023121251009812","GridItemsLink":"/v2/browse/epg@2023121251009812/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009812/PlayListTray/items","UtcDateTimeStart":"2023-12-12T04:00:00Z","UtcDateTimeEnd":"2023-12-12T05:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Pura Vida","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entrevista","SeriesId":"102883","Description":"João Paulo Freitas.","ReleaseYear":"2018","Rating":1,"Season":5,"Episode":9,"Duration":60,"ProgramId":2554643,"AggregatorId":1059808,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"c59c07b60101435a846e546633137b54","Url":"http://vip.pam.local.internal/PAM.Images/Store/c59c07b60101435a846e546633137b54","Type":1}]},{"CoreId":"2023121251009813","AssetId":"EPGE2023121251009813","ContentId":"epg@2023121251009813","ProgramId":"2581668","AggregatorId":"2527677","DateFullEventId":"2023121251009813","GridItemsLink":"/v2/browse/epg@2023121251009813/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009813/PlayListTray/items","UtcDateTimeStart":"2023-12-12T05:00:00Z","UtcDateTimeEnd":"2023-12-12T05:30:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Casos Singulares","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entrevista","SeriesId":"116606","Description":"No mundo foram reconhecidas entre 5 a 8 mil doenças raras que afetam o próprio e quem está ao redor. O peso social do problema, o acesso às terapêuticas quando existem, a forma de lidar com o problema, são aspetos a abordar no programa, que apresenta patologias e histórias de vida diferentes.","ReleaseYear":"2019","Rating":1,"Season":1,"Episode":13,"Duration":30,"ProgramId":2581668,"AggregatorId":2527677,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"42a228cd013742ffa58e302d4706b401","Url":"http://vip.pam.local.internal/PAM.Images/Store/42a228cd013742ffa58e302d4706b401","Type":1}]},{"CoreId":"2023121251009814","AssetId":"EPGE2023121251009814","ContentId":"epg@2023121251009814","ProgramId":"2312607","AggregatorId":"2176405","DateFullEventId":"2023121251009814","GridItemsLink":"/v2/browse/epg@2023121251009814/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009814/PlayListTray/items","UtcDateTimeStart":"2023-12-12T05:30:00Z","UtcDateTimeEnd":"2023-12-12T06:30:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Histórias Clínicas: Dra. Rita Gama","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Talk-Show","SeriesId":"103212","Description":"Prematuridade e doenças pulmonares crónicas obstrutivas.","ReleaseYear":"2018","Rating":80,"Season":2,"Episode":3,"Duration":60,"ProgramId":2312607,"AggregatorId":2176405,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"818dba4817a7464f9e8433620270b01d","Url":"http://vip.pam.local.internal/PAM.Images/Store/818dba4817a7464f9e8433620270b01d","Type":1}]},{"CoreId":"2023121251009815","AssetId":"EPGE2023121251009815","ContentId":"epg@2023121251009815","ProgramId":"2944028","AggregatorId":"2165663","DateFullEventId":"2023121251009815","GridItemsLink":"/v2/browse/epg@2023121251009815/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009815/PlayListTray/items","UtcDateTimeStart":"2023-12-12T06:30:00Z","UtcDateTimeEnd":"2023-12-12T07:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Ajudar Quem Ajuda","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entrevista","SeriesId":"102898","Description":"Hoje apresentamos a Associação Careca Power.","ReleaseYear":"2018","Rating":1,"Season":7,"Episode":11,"Duration":30,"ProgramId":2944028,"AggregatorId":2165663,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"a655dbeb67b745418e40096827581a69","Url":"http://vip.pam.local.internal/PAM.Images/Store/a655dbeb67b745418e40096827581a69","Type":1}]},{"CoreId":"2023121251009816","AssetId":"EPGE2023121251009816","ContentId":"epg@2023121251009816","ProgramId":"2554639","AggregatorId":"2165680","DateFullEventId":"2023121251009816","GridItemsLink":"/v2/browse/epg@2023121251009816/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009816/PlayListTray/items","UtcDateTimeStart":"2023-12-12T07:00:00Z","UtcDateTimeEnd":"2023-12-12T08:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Tenho um bebé. E agora?","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Magazine","SeriesId":"102886","Description":"Obesidade Infantil - Estratégias de combate em casa e na escola.","ReleaseYear":"2018","Rating":1,"Season":5,"Episode":9,"Duration":60,"ProgramId":2554639,"AggregatorId":2165680,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"293d91056a424619b904d93cd60e8db5","Url":"http://vip.pam.local.internal/PAM.Images/Store/293d91056a424619b904d93cd60e8db5","Type":1}]},{"CoreId":"2023121251009817","AssetId":"EPGE2023121251009817","ContentId":"epg@2023121251009817","ProgramId":"2383511","AggregatorId":"2303539","DateFullEventId":"2023121251009817","GridItemsLink":"/v2/browse/epg@2023121251009817/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009817/PlayListTray/items","UtcDateTimeStart":"2023-12-12T08:00:00Z","UtcDateTimeEnd":"2023-12-12T09:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Histórias Clínicas: Dr. Luis Sousa","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Talk-Show","SeriesId":"106734","Description":"Medicina Dentária em Portugal.","ReleaseYear":"2018","Rating":80,"Season":3,"Episode":1,"Duration":60,"ProgramId":2383511,"AggregatorId":2303539,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"818dba4817a7464f9e8433620270b01d","Url":"http://vip.pam.local.internal/PAM.Images/Store/818dba4817a7464f9e8433620270b01d","Type":1}]},{"CoreId":"2023121251009818","AssetId":"EPGE2023121251009818","ContentId":"epg@2023121251009818","ProgramId":"3364579","AggregatorId":"3161534","DateFullEventId":"2023121251009818","GridItemsLink":"/v2/browse/epg@2023121251009818/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009818/PlayListTray/items","UtcDateTimeStart":"2023-12-12T09:00:00Z","UtcDateTimeEnd":"2023-12-12T10:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Caixa de Pandora","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Talk-Show","SeriesId":"152921","Description":"Programa de 45 minutos, em estúdio, que reúne 4 mulheres de diversas idades e backgrounds que conversam todas as semanas sobre temas ligados à saúde e bem-estar, mas também à sexualidade, vida em família, ao trabalho, etc. É uma tertúlia no feminino.","ReleaseYear":"2023","Rating":80,"Season":4,"Episode":13,"Duration":60,"ProgramId":3364579,"AggregatorId":3161534,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"0ba7dccc8d1d459083c90666a2250776","Url":"http://vip.pam.local.internal/PAM.Images/Store/0ba7dccc8d1d459083c90666a2250776","Type":1}]},{"CoreId":"2023121251009819","AssetId":"EPGE2023121251009819","ContentId":"epg@2023121251009819","ProgramId":"3357379","AggregatorId":"2182966","DateFullEventId":"2023121251009819","GridItemsLink":"/v2/browse/epg@2023121251009819/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009819/PlayListTray/items","UtcDateTimeStart":"2023-12-12T10:00:00Z","UtcDateTimeEnd":"2023-12-12T11:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Corpo Clínico","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Saúde","SeriesId":"103390","Description":"Farmacovigilância.","ReleaseYear":"2018","Rating":1,"Season":12,"Episode":5,"Duration":60,"ProgramId":3357379,"AggregatorId":2182966,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"a060ca5930444d3a864ad20615e7df33","Url":"http://vip.pam.local.internal/PAM.Images/Store/a060ca5930444d3a864ad20615e7df33","Type":1}]},{"CoreId":"2023121251009820","AssetId":"EPGE2023121251009820","ContentId":"epg@2023121251009820","ProgramId":"3365186","AggregatorId":"3120338","DateFullEventId":"2023121251009820","GridItemsLink":"/v2/browse/epg@2023121251009820/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009820/PlayListTray/items","UtcDateTimeStart":"2023-12-12T11:00:00Z","UtcDateTimeEnd":"2023-12-12T12:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Tenho Um Adolescente. E Agora?","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Saúde","SeriesId":"150432","Description":"Como lidar com a rejeição.","ReleaseYear":"2022","Rating":80,"Season":2,"Episode":3,"Duration":60,"ProgramId":3365186,"AggregatorId":3120338,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"d0b53e8f6f644939a11be96ac28aae07","Url":"http://vip.pam.local.internal/PAM.Images/Store/d0b53e8f6f644939a11be96ac28aae07","Type":1}]},{"CoreId":"2023121251009821","AssetId":"EPGE2023121251009821","ContentId":"epg@2023121251009821","ProgramId":"3031742","AggregatorId":"2967454","DateFullEventId":"2023121251009821","GridItemsLink":"/v2/browse/epg@2023121251009821/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009821/PlayListTray/items","UtcDateTimeStart":"2023-12-12T12:00:00Z","UtcDateTimeEnd":"2023-12-12T13:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"One Born Every Minute","SubTitle":"","RatingDisplay":"NC","GenreDisplay":"Saúde","SeriesId":"142171","Description":"Saiba quais os segredos de uma boa relação.","ReleaseYear":"2018","Rating":0,"Season":9,"Episode":5,"Duration":60,"ProgramId":3031742,"AggregatorId":2967454,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"746a4552819c485aba07aed59fcca49d","Url":"http://vip.pam.local.internal/PAM.Images/Store/746a4552819c485aba07aed59fcca49d","Type":1}]},{"CoreId":"2023121251009822","AssetId":"EPGE2023121251009822","ContentId":"epg@2023121251009822","ProgramId":"3361332","AggregatorId":"3103070","DateFullEventId":"2023121251009822","GridItemsLink":"/v2/browse/epg@2023121251009822/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009822/PlayListTray/items","UtcDateTimeStart":"2023-12-12T13:00:00Z","UtcDateTimeEnd":"2023-12-12T13:30:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Entre Turnos","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Saúde","SeriesId":"149976","Description":"Vasco Lança (jogador de basquetebol e estudante de medicina).","ReleaseYear":"2022","Rating":80,"Season":1,"Episode":11,"Duration":30,"ProgramId":3361332,"AggregatorId":3103070,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"2e0fa1bc7d36404ab52dafcf450137d2","Url":"http://vip.pam.local.internal/PAM.Images/Store/2e0fa1bc7d36404ab52dafcf450137d2","Type":1}]},{"CoreId":"2023121251009823","AssetId":"EPGE2023121251009823","ContentId":"epg@2023121251009823","ProgramId":"3367957","AggregatorId":"3333429","DateFullEventId":"2023121251009823","GridItemsLink":"/v2/browse/epg@2023121251009823/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009823/PlayListTray/items","UtcDateTimeStart":"2023-12-12T13:30:00Z","UtcDateTimeEnd":"2023-12-12T14:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Fact Check","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Entretenimento","SeriesId":"164520","Description":"Ouviu dizer que não deve misturar melancia e vinho na mesma refeição? Contaram-lhe que aquecer refeições no micro-ondas provoca cancro? No outro dia, viu nas redes sociais alguém afirmar que só vai ao psiquiatra quem tem doenças graves?","ReleaseYear":"2023","Rating":1,"Season":1,"Episode":11,"Duration":30,"ProgramId":3367957,"AggregatorId":3333429,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"6b08d78551e745899ff8db0fea2b8680","Url":"http://vip.pam.local.internal/PAM.Images/Store/6b08d78551e745899ff8db0fea2b8680","Type":1}]},{"CoreId":"2023121251009824","AssetId":"EPGE2023121251009824","ContentId":"epg@2023121251009824","ProgramId":"3206760","AggregatorId":"3161538","DateFullEventId":"2023121251009824","GridItemsLink":"/v2/browse/epg@2023121251009824/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009824/PlayListTray/items","UtcDateTimeStart":"2023-12-12T14:00:00Z","UtcDateTimeEnd":"2023-12-12T15:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Guia da Vida Saudável","SubTitle":"","RatingDisplay":"M12","GenreDisplay":"Magazine","SeriesId":"152938","Description":"Programa de estúdio de 45 minutos, onde vamos mostrar exemplos e práticas que podem determinar uma vida mais saudável. Queremos condensar toda a informação disponível. O objetivo do programa é “prevenir primeiro, para não ter que remediar depois”.","ReleaseYear":"2023","Rating":80,"Season":1,"Episode":12,"Duration":60,"ProgramId":3206760,"AggregatorId":3161538,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"0082754b26bb4bc4978b9e324cccd8f6","Url":"http://vip.pam.local.internal/PAM.Images/Store/0082754b26bb4bc4978b9e324cccd8f6","Type":1}]},{"CoreId":"2023121251009825","AssetId":"EPGE2023121251009825","ContentId":"epg@2023121251009825","ProgramId":"3365804","AggregatorId":"2165712","DateFullEventId":"2023121251009825","GridItemsLink":"/v2/browse/epg@2023121251009825/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009825/PlayListTray/items","UtcDateTimeStart":"2023-12-12T15:00:00Z","UtcDateTimeEnd":"2023-12-12T16:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Check Up","SubTitle":"","RatingDisplay":"Todos","GenreDisplay":"Debate","SeriesId":"102906","Description":"Para debater o futuro da saúde em Portugal, todas as semanas abrimos antena a “Check up”. O programa promete reunir os principais protagonistas do setor para discutirem em conjunto os grandes temas que preocupam este universo.","ReleaseYear":"2018","Rating":1,"Season":10,"Episode":14,"Duration":60,"ProgramId":3365804,"AggregatorId":2165712,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"5bf507f275934d369ceb7a790251bd1e","Url":"http://vip.pam.local.internal/PAM.Images/Store/5bf507f275934d369ceb7a790251bd1e","Type":1}]},{"CoreId":"2023121251009826","AssetId":"EPGE2023121251009826","ContentId":"epg@2023121251009826","ProgramId":"3161537","AggregatorId":"2165665","DateFullEventId":"2023121251009826","GridItemsLink":"/v2/browse/epg@2023121251009826/grid/items","PlayListTrayItemLink":"/v1/contents/epg@2023121251009826/PlayListTray/items","UtcDateTimeStart":"2023-12-12T16:00:00Z","UtcDateTimeEnd":"2023-12-12T17:00:00Z","Type":4,"IsAdult":false,"AiringChannel":{"IsOnline":true,"IsTimeWarpable":true,"IsRestartable":true,"ServiceId":"510","ChannelId":"510","AssetId":"EPGC510","Name":"S+ HD","RatingDisplay":"M3","DvbLocator":"dvb://36.4C.835","Rating":20,"Position":129,"QualityVersion":2,"Images":[{"ImageId":"SAUDEMAIS.png","Url":"http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/SAUDEMAIS.png","Type":16}]},"Metadata":{"Title":"Histórias Clínicas","SubTitle":"Associações","RatingDisplay":"M12","GenreDisplay":"Saúde","SeriesId":"102905","Description":"Processo de Decisão Clínica.","ReleaseYear":"2018","Rating":80,"Season":7,"Episode":13,"Duration":60,"ProgramId":3161537,"AggregatorId":2165665,"IsNPVR":true,"IsStartOver":true},"Images":[{"ImageId":"818dba4817a7464f9e8433620270b01d","Url":"http://vip.pam.local.internal/PAM.Images/Store/818dba4817a7464f9e8433620270b01d","Type":1}]}] \ No newline at end of file +[ + { + "CoreId": "2026012313905035", + "AssetId": "EPGE2026012313905035", + "ContentId": "epg@2026012313905035", + "ProgramId": "3805166", + "AggregatorId": "2649043", + "DateFullEventId": "2026012313905035", + "GridItemsLink": "/v2/browse/epg@2026012313905035/grid/items", + "PlayListTrayItemLink": "/v1/contents/epg@2026012313905035/PlayListTray/items", + "DetailNodeItemNavLink": "/nodeitems/epg@2026012313905035/detail?context=schedule", + "UtcDateTimeStart": "2026-01-23T22:39:00Z", + "UtcDateTimeEnd": "2026-01-24T00:23:00Z", + "Type": 4, + "IsAdult": false, + "AiringChannel": { + "IsOnline": true, + "IsTimeWarpable": true, + "IsRestartable": true, + "ServiceId": "139", + "ChannelId": "5", + "AssetId": "EPGC139", + "Name": "RTP 1 HD", + "RatingDisplay": "M3", + "DvbLocator": "dvb://36.4E.1E79", + "Rating": 20, + "Position": 1, + "QualityVersion": 2, + "Images": [ + { + "ImageId": "RTPHD.png", + "Type": 16, + "Url": "http://vip.repositories.local.internal/Repositories.EPG/OttChannelIcons/RTPHD.png" + } + ] + }, + "Metadata": { + "Title": "Em Casa d'Amália", + "SubTitle": "", + "RatingDisplay": "M6", + "GenreDisplay": "Talk-Show", + "SeriesId": "124075", + "Description": "Que mais poderíamos pedir para o regresso deste programa, do que receber um dos poetas de Amália? Manuel Alegre, autor do icónico \"Trova do Vento que Passa\", estará connosco. A este raro momento, juntam-se também ilustres convidados: Paulo de Carvalho e o seu filho Agir, Rita Guerra e André Amaro...", + "ReleaseYear": "2025", + "Rating": 60, + "Season": 9, + "Episode": 15, + "Duration": 104, + "ProgramId": 3805166, + "AggregatorId": 2649043, + "IsNPVR": true, + "IsStartOver": true + }, + "Images": [ + { + "ImageId": "901d96a8f1534749b076212c296d821e", + "Type": 1, + "Url": "http://vip.pam.local.internal/PAM.Images/Store/901d96a8f1534749b076212c296d821e" + }, + { + "ImageId": "4de2fbd7177c4e7c8cc9faf703b119b5", + "Type": 38, + "Url": "http://vip.pam.local.internal/PAM.Images/Store/4de2fbd7177c4e7c8cc9faf703b119b5" + } + ] + } +] \ No newline at end of file diff --git a/sites/nostv.pt/nostv.pt.config.js b/sites/nostv.pt/nostv.pt.config.js index ffeb7a6eb..88db91de0 100644 --- a/sites/nostv.pt/nostv.pt.config.js +++ b/sites/nostv.pt/nostv.pt.config.js @@ -5,24 +5,33 @@ const utc = require('dayjs/plugin/utc') dayjs.extend(utc) const headers = { - 'X-Apikey': 'xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI', - 'X-Core-Appversion': '2.20.0.3', - 'X-Core-Contentratinglimit': '0', - 'X-Core-Deviceid': '', - 'X-Core-Devicetype': 'web', - Origin: 'https://nostv.pt', - 'User-Agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,pt;q=0.6,cs;q=0.5', + 'cache-control': 'no-cache', + 'origin': 'https://nostv.pt', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://nostv.pt/', + 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', + 'sec-ch-ua-mobile': '?1', + 'sec-ch-ua-platform': '"Android"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36', + 'x-apikey': 'xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI', + 'x-core-appversion': '2.20.2.2', + 'x-core-contentratinglimit': '0', + 'x-core-deviceid': '', + 'x-core-devicetype': 'web', + 'x-core-timezoneoffset': '3600000' } module.exports = { site: 'nostv.pt', days: 2, url({ channel, date }) { - return `https://api.clg.nos.pt/nostv/ott/schedule/range/contents/guest?channels=${channel.site_id - }&minDate=${date.format('YYYY-MM-DD')}T00:00:00Z&maxDate=${date.format( - 'YYYY-MM-DD' - )}T23:59:59Z&isDateInclusive=true&client_id=${headers['X-Apikey']}` + return `https://api.clg.nos.pt/nostv/ott/schedule/range/contents/guest?channels=${channel.site_id}&minDate=${date.format('YYYY-MM-DD')}T00:00:00Z&maxDate=${date.format('YYYY-MM-DD')}T23:59:59Z&isDateInclusive=true&client_id=${headers['x-apikey']}` }, request: { headers }, parser({ content }) { @@ -31,7 +40,7 @@ module.exports = { const items = Array.isArray(content) ? content : JSON.parse(content) items.forEach(item => { const image = item.Images - ? `https://mage.stream.nos.pt/mage/v1/Images?sourceUri=${item.Images[0].Url}&profile=ott_1_452x340&client_id=${headers['X-Apikey']}` + ? `https://mage.stream.nos.pt/mage/v1/Images?sourceUri=${item.Images[0].Url}&profile=ott_1_452x340&client_id=${headers['x-apikey']}` : null programs.push({ title: item.Metadata?.Title, @@ -54,7 +63,7 @@ module.exports = { async channels() { const result = await axios .get( - `https://api.clg.nos.pt/nostv/ott/channels/guest?client_id=${headers['X-Apikey']}`, + `https://api.clg.nos.pt/nostv/ott/channels/guest?client_id=${headers['x-apikey']}`, { headers } ) .then(r => r.data) diff --git a/sites/nostv.pt/nostv.pt.test.js b/sites/nostv.pt/nostv.pt.test.js index 939b8aadc..e20132c20 100644 --- a/sites/nostv.pt/nostv.pt.test.js +++ b/sites/nostv.pt/nostv.pt.test.js @@ -28,20 +28,17 @@ it('can parse response', () => { return p }) - const image = 'https://mage.stream.nos.pt/mage/v1/Images?sourceUri=http://vip.pam.local.internal/PAM.Images/Store/8329ed1aec5d4c0faa2056972256ff9f&profile=ott_1_452x340&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI' - expect(results[0]).toMatchObject({ - start: '2023-12-11T16:30:00.000Z', - stop: '2023-12-11T17:00:00.000Z', - title: 'Village Vets', - description: - 'A história de dois melhores amigos veterinários e o seu extraordinário trabalho na Austrália.', - season: 1, - episode: 12, + start: '2026-01-23T22:39:00.000Z', + stop: '2026-01-24T00:23:00.000Z', + title: 'Em Casa d\'Amália', + description: 'Que mais poderíamos pedir para o regresso deste programa, do que receber um dos poetas de Amália? Manuel Alegre, autor do icónico "Trova do Vento que Passa", estará connosco. A este raro momento, juntam-se também ilustres convidados: Paulo de Carvalho e o seu filho Agir, Rita Guerra e André Amaro...', + season: 9, + episode: 15, icon: { - src: image + src: 'https://mage.stream.nos.pt/mage/v1/Images?sourceUri=http://vip.pam.local.internal/PAM.Images/Store/901d96a8f1534749b076212c296d821e&profile=ott_1_452x340&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI' }, - image + image: 'https://mage.stream.nos.pt/mage/v1/Images?sourceUri=http://vip.pam.local.internal/PAM.Images/Store/901d96a8f1534749b076212c296d821e&profile=ott_1_452x340&client_id=xe1dgrShwdR1DVOKGmsj8Ut4QLlGyOFI' }) }) From 0e61dff190c4b968c4eab39a11a6dedc5b7db884 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:50:19 +0300 Subject: [PATCH 06/31] Update pm2.config.js --- pm2.config.js | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/pm2.config.js b/pm2.config.js index f1f901166..d06556d3b 100644 --- a/pm2.config.js +++ b/pm2.config.js @@ -1,35 +1,35 @@ -const grab = process.env.SITE - ? `npm run grab -- --site=${process.env.SITE} ${process.env.CLANG ? `--lang=${process.env.CLANG}` : '' - } --output=public/guide.xml` - : 'npm run grab -- --channels=channels.xml --output=public/guide.xml' - - -const apps = [ - { - name: 'serve', - script: 'npx serve -- public', - instances: 1, - watch: false, - autorestart: true - }, - { - name: 'grab', - script: `npx chronos -e "${grab}" -p "${process.env.CRON_SCHEDULE}" -l`, - instances: 1, - watch: false, - autorestart: true - } -]; - -if (process.env.RUN_AT_STARTUP === 'true') { - apps.push({ - name: 'grab-at-startup', - script: grab, - instances: 1, - autorestart: false, - watch: false, - max_restarts: 1 - }); -} - -module.exports = { apps }; \ No newline at end of file +const grab = process.env.SITE + ? `npm run grab -- --site=${process.env.SITE} ${ + process.env.CLANG ? `--lang=${process.env.CLANG}` : '' + } --output=public/guide.xml` + : 'npm run grab -- --channels=public/channels.xml --output=public/guide.xml' + +const apps = [ + { + name: 'serve', + script: 'npx serve -- public', + instances: 1, + watch: false, + autorestart: true + }, + { + name: 'grab', + script: `npx chronos -e "${grab}" -p "${process.env.CRON_SCHEDULE}" -l`, + instances: 1, + watch: false, + autorestart: true + } +] + +if (process.env.RUN_AT_STARTUP === 'true') { + apps.push({ + name: 'grab-at-startup', + script: grab, + instances: 1, + autorestart: false, + watch: false, + max_restarts: 1 + }) +} + +module.exports = { apps } From fdd25839b5d3807e93bedf67b94ca8e361858c6a Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:50:31 +0300 Subject: [PATCH 07/31] Update package-lock.json --- package-lock.json | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc7fa85f4..f12b02df7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "@typescript-eslint/parser": "^8.38.0", "axios": "^1.11.0", "axios-cookiejar-support": "^6.0.4", + "axios-mock-adapter": "^2.1.0", "chalk": "^5.4.1", "cheerio": "^1.1.2", "cli-progress": "^3.12.0", @@ -52,7 +53,7 @@ "cwait": "^1.1.2", "dayjs": "^1.11.13", "epg-grabber": "^0.46.1", - "epg-parser": "^0.3.1", + "epg-parser": "^0.5.0", "eslint": "^9.32.0", "eslint-config-prettier": "^10.1.8", "form-data": "^4.0.4", @@ -5238,9 +5239,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", - "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==" }, "node_modules/debug": { "version": "4.3.4", @@ -5538,12 +5539,12 @@ } }, "node_modules/epg-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz", - "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.5.0.tgz", + "integrity": "sha512-NK9vSev/KkCVcKilJd35PmB9tP4+tN45dhcsSxHagVoUTINh8KLZ1yvgtoPDVYr0IaSPJXIIIZWcu1JPjS5HMw==", "dependencies": { - "dayjs": "^1.11.6", - "lodash": "^4.17.21", + "dayjs": "^1.11.19", + "lodash.groupby": "^4.6.0", "xml-js": "^1.6.11" } }, @@ -8694,6 +8695,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -14838,9 +14844,9 @@ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" }, "dayjs": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", - "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==" }, "debug": { "version": "4.3.4", @@ -15056,12 +15062,12 @@ } }, "epg-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.3.1.tgz", - "integrity": "sha512-y131hXfDthUdSeKbN0Ru1wiFF5er4t/TLT+IaAnHF2CYB0cnygHTJteQMDYIlHWHDsGj+z9ejm1cU3saFNF3nQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.5.0.tgz", + "integrity": "sha512-NK9vSev/KkCVcKilJd35PmB9tP4+tN45dhcsSxHagVoUTINh8KLZ1yvgtoPDVYr0IaSPJXIIIZWcu1JPjS5HMw==", "requires": { - "dayjs": "^1.11.6", - "lodash": "^4.17.21", + "dayjs": "^1.11.19", + "lodash.groupby": "^4.6.0", "xml-js": "^1.6.11" } }, @@ -17283,6 +17289,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", From 6490952f4e1d401afb2cd54ee94f1e4aff7ac305 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:50:36 +0300 Subject: [PATCH 08/31] Update package.json --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c6d8aa59..4f2be8a44 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "channels:validate": "tsx scripts/commands/channels/validate.ts", "sites:init": "tsx scripts/commands/sites/init.ts", "sites:update": "tsx scripts/commands/sites/update.ts", + "guides:update": "tsx scripts/commands/guides/update.ts", "grab": "tsx scripts/commands/epg/grab.ts", "lint": "npx eslint \"{scripts,tests,sites}/**/*.{ts,mts,js}\"", "test": "cross-env TZ=Pacific/Nauru npx jest --runInBand", @@ -71,6 +72,7 @@ "@typescript-eslint/parser": "^8.38.0", "axios": "^1.11.0", "axios-cookiejar-support": "^6.0.4", + "axios-mock-adapter": "^2.1.0", "chalk": "^5.4.1", "cheerio": "^1.1.2", "cli-progress": "^3.12.0", @@ -82,7 +84,7 @@ "cwait": "^1.1.2", "dayjs": "^1.11.13", "epg-grabber": "^0.46.1", - "epg-parser": "^0.3.1", + "epg-parser": "^0.5.0", "eslint": "^9.32.0", "eslint-config-prettier": "^10.1.8", "form-data": "^4.0.4", From dd18056047b4bf4ba76492036002f992276e42d8 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:51:11 +0300 Subject: [PATCH 09/31] Update tests/__data__ --- .../__data__/expected/guides_update/GUIDES.md | 13 ++++++++ .../__data__/input/guides_update/channels.xml | 4 +++ tests/__data__/input/guides_update/guide.xml | 30 +++++++++++++++++++ .../__data__/input/guides_update/worker.json | 4 +++ .../__data__/input/guides_update/workers.txt | 2 ++ 5 files changed, 53 insertions(+) create mode 100644 tests/__data__/expected/guides_update/GUIDES.md create mode 100644 tests/__data__/input/guides_update/channels.xml create mode 100644 tests/__data__/input/guides_update/guide.xml create mode 100644 tests/__data__/input/guides_update/worker.json create mode 100644 tests/__data__/input/guides_update/workers.txt diff --git a/tests/__data__/expected/guides_update/GUIDES.md b/tests/__data__/expected/guides_update/GUIDES.md new file mode 100644 index 000000000..f6e86cfc8 --- /dev/null +++ b/tests/__data__/expected/guides_update/GUIDES.md @@ -0,0 +1,13 @@ +# Guides + + + + + + + + + +
HostStatusChannelsLast UpdatedLinks
example.com🔴0-
worker-9dd4.onrender.com🟢1a day agochannels.xml
guide.xml
+ +[How can I add my server to the list?](CONTRIBUTING.md#how-to-add-my-server-to-the-guides-md) diff --git a/tests/__data__/input/guides_update/channels.xml b/tests/__data__/input/guides_update/channels.xml new file mode 100644 index 000000000..46c1b2e93 --- /dev/null +++ b/tests/__data__/input/guides_update/channels.xml @@ -0,0 +1,4 @@ + + + ANT1 Europe + \ No newline at end of file diff --git a/tests/__data__/input/guides_update/guide.xml b/tests/__data__/input/guides_update/guide.xml new file mode 100644 index 000000000..ed17438ed --- /dev/null +++ b/tests/__data__/input/guides_update/guide.xml @@ -0,0 +1,30 @@ + +ANT1 Europehttps://antennaeurope.gr +ΚΑΛΗΜΕΡΑ ΕΛΛΑΔΑ +ΤΟ ΠΡΩΙΝΟ +ANT1 NEWS +ΑΠΟΚΑΛΥΨΕΙΣ +ΡΟΥΚ ΖΟΥΚ +5 X 5 +ANT1 NEWS +ΠΟΙΟΣ ΘΕΛΕΙ ΝΑ ΓΙΝΕΙ ΕΚΑΤΟΜΜΥΡΙΟΥΧΟΣ +GRAND HOTEL +ΓΙΑΤΙ ΡΕ ΠΑΤΕΡΑ ; +THE ROADSHOW - BEST OF +ΕΝΩΠΙΟΣ ΕΝΩΠΙΩ +5 X 5 +ΤΟ ΠΡΩΙΝΟ +ΚΑΛΗΜΕΡΑ ΕΛΛΑΔΑ +ΤΟ ΠΡΩΙΝΟ +ANT1 NEWS +ΑΠΟΚΑΛΥΨΕΙΣ +ΡΟΥΚ ΖΟΥΚ +5 X 5 +ANT1 NEWS +ΠΟΙΟΣ ΘΕΛΕΙ ΝΑ ΓΙΝΕΙ ΕΚΑΤΟΜΜΥΡΙΟΥΧΟΣ +DON'T FORGET THE LYRICS +VIΠ +ΠΕΦΤΕΙ Η ΝΥΧΤΑ ΜΕ... ΡΥΘΜΟ +5 X 5 +ΤΟ ΠΡΩΙΝΟ + \ No newline at end of file diff --git a/tests/__data__/input/guides_update/worker.json b/tests/__data__/input/guides_update/worker.json new file mode 100644 index 000000000..371feec07 --- /dev/null +++ b/tests/__data__/input/guides_update/worker.json @@ -0,0 +1,4 @@ +{ + "channels": "channels.xml", + "guide": "guide.xml" +} \ No newline at end of file diff --git a/tests/__data__/input/guides_update/workers.txt b/tests/__data__/input/guides_update/workers.txt new file mode 100644 index 000000000..02ca158a1 --- /dev/null +++ b/tests/__data__/input/guides_update/workers.txt @@ -0,0 +1,2 @@ +example.com +worker-9dd4.onrender.com \ No newline at end of file From 2ac41ec8cd48e5da2b3098413b917da691ca8392 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:51:24 +0300 Subject: [PATCH 10/31] Create update.test.ts --- tests/commands/guides/update.test.ts | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/commands/guides/update.test.ts diff --git a/tests/commands/guides/update.test.ts b/tests/commands/guides/update.test.ts new file mode 100644 index 000000000..4f3d0f6ef --- /dev/null +++ b/tests/commands/guides/update.test.ts @@ -0,0 +1,29 @@ +import { execSync } from 'child_process' +import { pathToFileURL } from 'node:url' +import fs from 'fs-extra' + +const ENV_VAR = 'cross-env ROOT_DIR=tests/__data__/output' + +beforeEach(() => { + fs.emptyDirSync('tests/__data__/output') + fs.copySync('tests/__data__/input/guides_update/workers.txt', 'tests/__data__/output/workers.txt') +}) + +it('can update GUIDES.md', () => { + const cmd = `${ENV_VAR} npm run guides:update` + + const stdout = execSync(cmd, { encoding: 'utf8' }) + if (process.env.DEBUG === 'true') console.log(cmd, stdout) + + expect(content('tests/__data__/output/GUIDES.md')).toEqual( + content('tests/__data__/expected/guides_update/GUIDES.md') + ) +}) + +function content(filepath: string) { + const data = fs.readFileSync(pathToFileURL(filepath), { + encoding: 'utf8' + }) + + return JSON.stringify(data) +} From d7916ceca2c2c73cc6cc7adcd003d719b2e7b2c6 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:52:15 +0300 Subject: [PATCH 11/31] Update scripts --- scripts/commands/guides/update.ts | 144 ++++++++++++++++++++++++++++++ scripts/models/index.ts | 1 + scripts/models/worker.ts | 68 ++++++++++++++ scripts/templates/_guides.md | 5 ++ 4 files changed, 218 insertions(+) create mode 100644 scripts/commands/guides/update.ts create mode 100644 scripts/models/worker.ts create mode 100644 scripts/templates/_guides.md diff --git a/scripts/commands/guides/update.ts b/scripts/commands/guides/update.ts new file mode 100644 index 000000000..f43b96b6c --- /dev/null +++ b/scripts/commands/guides/update.ts @@ -0,0 +1,144 @@ +import { HTMLTableRow, HTMLTableDataItem, HTMLTableColumn } from '../../types/htmlTable' +import epgGrabber, { EPGGrabber } from 'epg-grabber' +import AxiosMockAdapter from 'axios-mock-adapter' +import { Storage } from '@freearhey/storage-js' +import { Channel, Worker } from '../../models' +import { Collection } from '@freearhey/core' +import { ROOT_DIR } from '../../constants' +import { Logger } from '@freearhey/core' +import { HTMLTable } from '../../core' +import epgParser from 'epg-parser' +import axios from 'axios' + +async function main() { + const logger = new Logger({ level: process.env.NODE_ENV === 'test' ? -999 : 3 }) + const rootStorage = new Storage(ROOT_DIR) + const workers = new Map() + + logger.info('loading workers.txt...') + const workersTxt = await rootStorage.load('workers.txt') + + workersTxt.split('\r\n').forEach((host: string) => { + if (!host) return + + const worker = new Worker({ host }) + + workers.set(host, worker) + }) + + for (const worker of workers.values()) { + logger.info(`processing "${worker.host}"...`) + + const client = axios.create({ + baseURL: worker.getBaseUrl(), + timeout: 60000 + }) + + if (process.env.NODE_ENV === 'test') { + const mock = new AxiosMockAdapter(client) + if (worker.host === 'example.com') { + mock.onGet('worker.json').reply(404) + } else { + const testStorage = new Storage('tests/__data__/input/guides_update') + mock.onGet('worker.json').reply(200, await testStorage.load('worker.json')) + mock.onGet('channels.xml').reply(200, await testStorage.load('channels.xml')) + mock.onGet('guide.xml').reply(200, await testStorage.load('guide.xml')) + } + } + + const workerJson = await client + .get('worker.json') + .then(res => res.data) + .catch(err => { + worker.status = err.status + logger.error(err.message) + }) + + if (!workerJson) { + worker.status = 'MISSING_WORKER_CONFIG' + logger.error('Unable to load "workers.json"') + continue + } + + worker.channelsPath = workerJson.channels + worker.guidePath = workerJson.guide + + if (!worker.channelsPath) { + worker.status = 'MISSING_CHANNELS_PATH' + logger.error('The "channels" property is missing from the workers config') + continue + } + + if (!worker.guidePath) { + worker.status = 'MISSING_GUIDE_PATH' + logger.error('The "guide" property is missing from the workers config') + continue + } + + const channelsXml = await client + .get(worker.channelsPath) + .then(res => res.data) + .catch(err => { + worker.status = err.status + logger.error(err.message) + }) + + if (!channelsXml) continue + + const parsedChannels = EPGGrabber.parseChannelsXML(channelsXml) + worker.channels = new Collection(parsedChannels).map( + (channel: epgGrabber.Channel) => new Channel(channel.toObject()) + ) + + const guideXml = await client + .get(worker.guidePath) + .then(res => res.data) + .catch(err => { + worker.status = err.status + logger.error(err.message) + }) + + if (!guideXml) continue + + const parsedGuide = epgParser.parse(guideXml) + worker.lastUpdated = parsedGuide.date + + worker.status = 'OK' + } + + logger.info('creating guides table...') + const rows = new Collection() + workers.forEach((worker: Worker) => { + rows.add( + new Collection([ + { value: worker.host }, + { value: worker.getStatusEmoji(), align: 'center' }, + { value: worker.getChannelsCount().toString(), align: 'right' }, + { value: worker.getLastUpdated(), align: 'left' }, + { + value: + worker.status === 'OK' + ? `${worker.channelsPath}
${worker.guidePath}` + : '' + } + ]) + ) + }) + + logger.info('updating guides.md...') + const table = new HTMLTable( + rows, + new Collection([ + { name: 'Host', align: 'left' }, + { name: 'Status', align: 'left' }, + { name: 'Channels', align: 'left' }, + { name: 'Last Updated', align: 'left' }, + { name: 'Links', align: 'left' } + ]) + ) + const guidesTemplate = await new Storage().load('scripts/templates/_guides.md') + const guidesContent = guidesTemplate.replace('_TABLE_', table.toString()) + await rootStorage.save('GUIDES.md', guidesContent) +} + +main() diff --git a/scripts/models/index.ts b/scripts/models/index.ts index a05f13a89..c891f01bf 100644 --- a/scripts/models/index.ts +++ b/scripts/models/index.ts @@ -3,3 +3,4 @@ export * from './issue' export * from './site' export * from './channel' export * from './program' +export * from './worker' diff --git a/scripts/models/worker.ts b/scripts/models/worker.ts new file mode 100644 index 000000000..8b625ffa9 --- /dev/null +++ b/scripts/models/worker.ts @@ -0,0 +1,68 @@ +import relativeTime from 'dayjs/plugin/relativeTime' +import { Collection } from '@freearhey/core' +import { Channel } from './channel' +import dayjs from 'dayjs' + +dayjs.extend(relativeTime) + +export interface WorkerData { + host: string +} + +export class Worker { + host: string + channelsPath?: string + guidePath?: string + channels?: Collection + status?: string + lastUpdated?: string + + constructor(data: WorkerData) { + this.host = data.host + } + + getBaseUrl(): string { + return `https://${this.host}` + } + + getConfigUrl(): string { + const url = new URL('worker.json', this.getBaseUrl()) + + return url.href + } + + getChannelsUrl(): string { + if (!this.channelsPath) return '' + + const url = new URL(this.channelsPath, this.getBaseUrl()) + + return url.href + } + + getGuideUrl(): string { + if (!this.guidePath) return '' + + const url = new URL(this.guidePath, this.getBaseUrl()) + + return url.href + } + + getStatusEmoji(): string { + if (!this.status) return '⚪' + if (this.status === 'OK') return '🟢' + + return '🔴' + } + + getChannelsCount(): number { + if (!this.channels) return 0 + + return this.channels.count() + } + + getLastUpdated(): string { + if (!this.lastUpdated) return '-' + + return dayjs().to(dayjs(this.lastUpdated)) + } +} diff --git a/scripts/templates/_guides.md b/scripts/templates/_guides.md new file mode 100644 index 000000000..d643a4637 --- /dev/null +++ b/scripts/templates/_guides.md @@ -0,0 +1,5 @@ +# Guides + +_TABLE_ + +[How can I add my server to the list?](CONTRIBUTING.md#how-to-add-my-server-to-the-guides-md) From 8f43348a2fb23e3031131a37d1cfb77c93159512 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:52:23 +0300 Subject: [PATCH 12/31] Create workers.txt --- workers.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 workers.txt diff --git a/workers.txt b/workers.txt new file mode 100644 index 000000000..d43ab81c3 --- /dev/null +++ b/workers.txt @@ -0,0 +1 @@ +worker-9dd4.onrender.com \ No newline at end of file From 2374fac9b4a602747768cac528b88b993bc66250 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:53:20 +0300 Subject: [PATCH 13/31] Update update.yml --- .github/workflows/update.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 26255c8bd..cf94890a5 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -32,17 +32,28 @@ jobs: run: npm run channels:lint - name: update sites.md run: npm run sites:update - env: - GH_TOKEN: ${{ steps.create-app-token.outputs.token }} - run: git status - name: commit changes to sites.md if: ${{ !env.ACT && github.ref == 'refs/heads/master' }} run: | - SITE=SITES.md - CHANGED=$(git diff ${SITE}) + FILE=SITES.md + CHANGED=$(git diff ${FILE}) if [ -n "${CHANGED}" ]; then - git add ${SITE} - git commit -m "[Bot] Update ${SITE}" -m "Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/${{ github.run_id }}) workflow." --no-verify + git add ${FILE} + git commit -m "[Bot] Update ${FILE}" -m "Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/${{ github.run_id }}) workflow." --no-verify + git push + fi + - name: update guides.md + run: npm run guides:update + - run: git status + - name: commit changes to guides.md + if: ${{ !env.ACT && github.ref == 'refs/heads/master' }} + run: | + FILE=GUIDES.md + CHANGED=$(git diff ${FILE}) + if [ -n "${CHANGED}" ]; then + git add ${FILE} + git commit -m "[Bot] Update ${FILE}" -m "Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/${{ github.run_id }}) workflow." --no-verify git push fi - name: generate .api/guides.json From 3028757db322063297dfa609591847faaa9b5642 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:54:25 +0300 Subject: [PATCH 14/31] Update README.md --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 06a8bf352..d6aeecd9a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Tools for downloading the EPG (Electronic Program Guide) for thousands of TV cha - 🚀 [Usage](#usage) - 💫 [Update](#update) - 🐋 [Docker](#docker) -- 📺 [Playlists](#playlists) +- 📅 [Guides](#guides) - 🗄 [Database](#database) - 👨‍💻 [API](#api) - 📚 [Resources](#resources) @@ -155,7 +155,7 @@ docker pull ghcr.io/iptv-org/epg:master ### Create and run container ```sh -docker run -p 3000:3000 -v /path/to/channels.xml:/epg/channels.xml ghcr.io/iptv-org/epg:master +docker run -p 3000:3000 -v /path/to/channels.xml:/epg/public/channels.xml ghcr.io/iptv-org/epg:master ``` By default, the guide will be downloaded every day at 00:00 UTC and saved to the `/epg/public/guide.xml` file inside the container. @@ -179,7 +179,7 @@ To fine-tune the execution, you can pass environment variables to the container ```sh docker run \ -p 5000:3000 \ --v /path/to/channels.xml:/epg/channels.xml \ +-v /path/to/channels.xml:/epg/public/channels.xml \ -e CRON_SCHEDULE="0 0,12 * * *" \ -e MAX_CONNECTIONS=10 \ -e GZIP=true \ @@ -203,6 +203,10 @@ ghcr.io/iptv-org/epg:master | DELAY | Delay between request in milliseconds (default: 0) | | RUN_AT_STARTUP | Run grab on container startup (default: true) | +## Guides + +Any user can share the guides they have created with the rest of the community. A complete list of these guides and their current status can be found in the [GUIDES.md](GUIDES.md) file. + ## Database All channel data is taken from the [iptv-org/database](https://github.com/iptv-org/database) repository. If you find any errors please open a new [issue](https://github.com/iptv-org/database/issues) there. @@ -236,4 +240,3 @@ And thank you to everyone who has already contributed! ## License [![CC0](http://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)](LICENSE) - From 8d23c384a37befc8cf1512be325de52b2187cbdd Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:54:27 +0300 Subject: [PATCH 15/31] Update CONTRIBUTING.md --- CONTRIBUTING.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e7089e053..5aae9de3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -407,6 +407,27 @@ This way, you can map channels by simply selecting the proper ID from the list: Once complete, [commit](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits) all changes and send a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). +### How to add my server to the GUIDES.md? + +To do this, you just need to place the `worker.json` file in a public directory on your server. + +
+worker.json +
+ +```json +{ + "channels": "path/to/channels.xml", + "guide": "path/to/guide.xml" +} +``` + +
+ +And then add server domain or IP address to the [workers.txt](workers.txt) file. + +Once your request is approved, it will automatically be added to the [GUIDES.md](GUIDES.md). + ## Project Structure - `.github/` @@ -417,8 +438,10 @@ Once complete, [commit](https://docs.github.com/en/pull-requests/committing-chan - `sites/`: contains configurations, channel lists and tests for all sites. - `tests/`: contains tests to check the scripts. - `CONTRIBUTING.md`: file you are currently reading. +- `GUIDES.md`: list of all available guides and their current status. - `README.md`: project description displayed on the home page. - `SITES.md`: list of all supported sites and their current status. +- `workers.txt`: list of all available community workers. ## Scripts @@ -439,6 +462,7 @@ To run scripts use the `npm run ` command. - `channels:validate`: checks the description of channels for errors. - `sites:init`: creates a new site config from the template. - `sites:update`: updates the list of sites and their status in [SITES.md](SITES.md). +- `guides:update`: updates the list of guides and their status in [GUIDES.md](GUIDES.md). - `grab`: downloads a program from a specified source. - `serve`: starts the [web server](https://github.com/vercel/serve). - `lint`: сhecks the scripts for syntax errors. From b8655d926b0d2a4a058856207f8bb7eeb289b311 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:54:32 +0300 Subject: [PATCH 16/31] Create GUIDES.md --- GUIDES.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 GUIDES.md diff --git a/GUIDES.md b/GUIDES.md new file mode 100644 index 000000000..46c58a37d --- /dev/null +++ b/GUIDES.md @@ -0,0 +1,12 @@ +# Guides + + + + + + + + +
HostStatusChannelsLast UpdatedLinks
worker-9dd4.onrender.com🟢1a day agochannels.xml
guide.xml
+ +[How can I add my server to the list?](CONTRIBUTING.md#how-to-add-my-server-to-the-guides-md) From 122be1964495e9c7d85a959dc3cc7634d8687dca Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:00:34 +0300 Subject: [PATCH 17/31] Update dependecies --- package-lock.json | 488 ++++++++++++++++++++++++++-------------------- 1 file changed, 272 insertions(+), 216 deletions(-) diff --git a/package-lock.json b/package-lock.json index f12b02df7..352f9b8b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1092,9 +1092,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -1611,27 +1611,6 @@ "node": ">=16.0.0" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2229,9 +2208,10 @@ } }, "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -2846,6 +2826,17 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" }, + "node_modules/@pm2/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-ZcNHqQjMuNRcQ7Z1zJbFIQZO/BDKV3KbiTckWdfbUaYhj7uNmUwb+FbdDWSCkvxNr9dBJQwvV17o6QBkAvgO0g==", + "bin": { + "blessed": "bin/tput.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/@pm2/io": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz", @@ -4207,23 +4198,25 @@ } }, "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "node_modules/axios-cache-interceptor": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.3.tgz", - "integrity": "sha512-ifuSBoCEkVaiugg1UTjVuTdK+SjSOJ35pdv2OrzhRT3wDMr52QiayQxUqs7jd7GDsfPOjMcw3T3ek0TysbyZZw==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.11.4.tgz", + "integrity": "sha512-xZ4OZUxdpcFUpZjrqfYlGK0VglpPRKKSoE3vMHrstxolixQNs/MrbMezOAO5uS454hIEcWpnk75RZK26WkPW/g==", "dependencies": { - "cache-parser": "1.2.5", - "fast-defer": "1.1.8", - "object-code": "1.3.3" + "cache-parser": "^1.2.6", + "fast-defer": "^1.1.9", + "http-vary": "^1.0.3", + "object-code": "^2.0.0", + "try": "^1.0.3" }, "engines": { "node": ">=12" @@ -4399,17 +4392,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", - "bin": { - "blessed": "bin/tput.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -4615,9 +4597,9 @@ } }, "node_modules/cache-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.5.tgz", - "integrity": "sha512-Md/4VhAHByQ9frQ15WD6LrMNiVw9AEl/J7vWIXw+sxT6fSOpbtt6LHTp76vy8+bOESPBO94117Hm2bIjlI7XjA==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.6.tgz", + "integrity": "sha512-SjjnKlWgrhDrAWKUxAvmZLRGDa6JExMfjSu59/pvpNoI6mEHYSLcLKUw2RtECEOINvf6dxJo35fY+T/scA0SUA==" }, "node_modules/call-bind": { "version": "1.0.8", @@ -6023,9 +6005,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-defer": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz", - "integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.9.tgz", + "integrity": "sha512-JP7Xm9HuePSeTT1DI78NeE9eAQvgNb9qNP2jlyQrcx4jiWM189omV6oyd0xaUPWHPlKmvDzz6H1FfPWIDU+xfg==" }, "node_modules/fast-glob": { "version": "3.3.3", @@ -6153,9 +6135,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -6215,9 +6197,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6378,14 +6360,14 @@ "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" }, "node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "license": "ISC", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", + "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -6411,13 +6393,34 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "license": "ISC", + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "jackspeak": "^4.2.3" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "dependencies": { + "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" @@ -6591,6 +6594,11 @@ "node": ">= 14" } }, + "node_modules/http-vary": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http-vary/-/http-vary-1.0.3.tgz", + "integrity": "sha512-sx7Y8YTqF3o0mFJJvF66n8dbaE8v3liV1RgCz46XP5xK7dnzyZHvwMWRA115q5kjbCPBV65/nOMlgW54WLyiag==" + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -7060,12 +7068,11 @@ } }, "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "license": "BlueOak-1.0.0", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" }, "engines": { "node": "20 || >=22" @@ -7074,6 +7081,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/jackspeak/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "engines": { + "node": ">=18" + } + }, "node_modules/jest": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/jest/-/jest-30.0.5.tgz", @@ -7361,9 +7376,10 @@ } }, "node_modules/jest-config/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -8047,9 +8063,10 @@ } }, "node_modules/jest-runtime/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -8691,9 +8708,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" }, "node_modules/lodash.groupby": { "version": "4.6.0", @@ -9094,9 +9111,9 @@ } }, "node_modules/object-code": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.3.tgz", - "integrity": "sha512-/Ds4Xd5xzrtUOJ+xJQ57iAy0BZsZltOHssnDgcZ8DOhgh41q1YJCnTPnWdWSLkNGNnxYzhYChjc5dgC9mEERCA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-2.0.0.tgz", + "integrity": "sha512-qOwMF43O/VAD51nJAB7MKsf1yWksql6O1i0DHRo1yaOQM6xJQH0NAE9UKJzYB7lyKw1jnpeb2BmB8qakjxiYZA==" }, "node_modules/object-treeify": { "version": "2.1.1", @@ -9539,36 +9556,36 @@ } }, "node_modules/pm2": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.10.tgz", - "integrity": "sha512-sbk4HsnhtJMx1wJlhFQhYfDRzHtVK+cvdrIezbjM9WjSyc7kLtQ4nZ5K7JLOdLe3AevytmRcTiOa3VvAQrve2A==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.14.tgz", + "integrity": "sha512-wX1FiFkzuT2H/UUEA8QNXDAA9MMHDsK/3UHj6Dkd5U7kxyigKDA5gyDw78ycTQZAuGCLWyUX5FiXEuVQWafukA==", "dependencies": { "@pm2/agent": "~2.1.1", + "@pm2/blessed": "0.1.81", "@pm2/io": "~6.1.0", "@pm2/js-api": "~0.8.0", - "@pm2/pm2-version-check": "latest", + "@pm2/pm2-version-check": "^1.0.4", "ansis": "4.0.0-node10", - "async": "~3.2.6", - "blessed": "0.1.81", - "chokidar": "^3.5.3", - "cli-tableau": "^2.0.0", + "async": "3.2.6", + "chokidar": "3.6.0", + "cli-tableau": "2.0.1", "commander": "2.15.1", - "croner": "~4.1.92", - "dayjs": "~1.11.13", - "debug": "^4.3.7", + "croner": "4.1.97", + "dayjs": "1.11.15", + "debug": "4.4.3", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", - "js-yaml": "~4.1.0", + "js-yaml": "4.1.1", "mkdirp": "1.0.4", "needle": "2.4.0", - "pidusage": "~3.0", + "pidusage": "3.0.2", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", "pm2-multimeter": "^0.1.2", - "promptly": "^2", - "semver": "^7.6.2", + "promptly": "2.2.0", + "semver": "7.7.2", "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1" @@ -9680,11 +9697,15 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, + "node_modules/pm2/node_modules/dayjs": { + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.15.tgz", + "integrity": "sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ==" + }, "node_modules/pm2/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dependencies": { "ms": "^2.1.3" }, @@ -9698,9 +9719,9 @@ } }, "node_modules/pm2/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dependencies": { "argparse": "^2.0.1" }, @@ -10649,9 +10670,9 @@ } }, "node_modules/systeminformation": { - "version": "5.25.11", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.25.11.tgz", - "integrity": "sha512-jI01fn/t47rrLTQB0FTlMCC+5dYx8o0RRF+R4BPiUNsvg5OdY0s9DKMFmJGrx5SwMZQ4cag0Gl6v8oycso9b/g==", + "version": "5.30.7", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.30.7.tgz", + "integrity": "sha512-33B/cftpaWdpvH+Ho9U1b08ss8GQuLxrWHelbJT1yw4M48Taj8W3ezcPuaLoIHZz5V6tVHuQPr5BprEfnBLBMw==", "optional": true, "os": [ "darwin", @@ -10806,6 +10827,14 @@ "node": ">= 14.0.0" } }, + "node_modules/try": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/try/-/try-1.0.3.tgz", + "integrity": "sha512-AHA8khVCII6zKyRkyPo6pRwoR9v5jb7QFw6e5avtaVSkxVfaEucYIo06xnwB+pJaEarfYNbs7W3Vq+LZLZiWyA==", + "funding": { + "url": "https://github.com/arthurfiorette/try?sponsor=1" + } + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -10902,9 +10931,9 @@ } }, "node_modules/undici": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.12.0.tgz", - "integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.21.0.tgz", + "integrity": "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==", "engines": { "node": ">=20.18.1" } @@ -12007,9 +12036,9 @@ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==" }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "requires": { "argparse": "^2.0.1" } @@ -12316,19 +12345,6 @@ } } }, - "@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==" - }, - "@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "requires": { - "@isaacs/balanced-match": "^4.0.1" - } - }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -12766,9 +12782,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "requires": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -13232,6 +13248,11 @@ } } }, + "@pm2/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/@pm2/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-ZcNHqQjMuNRcQ7Z1zJbFIQZO/BDKV3KbiTckWdfbUaYhj7uNmUwb+FbdDWSCkvxNr9dBJQwvV17o6QBkAvgO0g==" + }, "@pm2/io": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.1.0.tgz", @@ -14136,23 +14157,25 @@ } }, "axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "axios-cache-interceptor": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.8.3.tgz", - "integrity": "sha512-ifuSBoCEkVaiugg1UTjVuTdK+SjSOJ35pdv2OrzhRT3wDMr52QiayQxUqs7jd7GDsfPOjMcw3T3ek0TysbyZZw==", + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.11.4.tgz", + "integrity": "sha512-xZ4OZUxdpcFUpZjrqfYlGK0VglpPRKKSoE3vMHrstxolixQNs/MrbMezOAO5uS454hIEcWpnk75RZK26WkPW/g==", "requires": { - "cache-parser": "1.2.5", - "fast-defer": "1.1.8", - "object-code": "1.3.3" + "cache-parser": "^1.2.6", + "fast-defer": "^1.1.9", + "http-vary": "^1.0.3", + "object-code": "^2.0.0", + "try": "^1.0.3" } }, "axios-cookiejar-support": { @@ -14270,11 +14293,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" }, - "blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -14407,9 +14425,9 @@ "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, "cache-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.5.tgz", - "integrity": "sha512-Md/4VhAHByQ9frQ15WD6LrMNiVw9AEl/J7vWIXw+sxT6fSOpbtt6LHTp76vy8+bOESPBO94117Hm2bIjlI7XjA==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.6.tgz", + "integrity": "sha512-SjjnKlWgrhDrAWKUxAvmZLRGDa6JExMfjSu59/pvpNoI6mEHYSLcLKUw2RtECEOINvf6dxJo35fY+T/scA0SUA==" }, "call-bind": { "version": "1.0.8", @@ -15375,9 +15393,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-defer": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz", - "integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.9.tgz", + "integrity": "sha512-JP7Xm9HuePSeTT1DI78NeE9eAQvgNb9qNP2jlyQrcx4jiWM189omV6oyd0xaUPWHPlKmvDzz6H1FfPWIDU+xfg==" }, "fast-glob": { "version": "3.3.3", @@ -15487,9 +15505,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" }, "for-each": { "version": "0.3.5", @@ -15516,9 +15534,9 @@ } }, "form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -15628,24 +15646,40 @@ "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" }, "glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "requires": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", + "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "dependencies": { - "minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "requires": { - "@isaacs/brace-expansion": "^5.0.0" + "jackspeak": "^4.2.3" + } + }, + "brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "requires": { + "balanced-match": "^4.0.2" + } + }, + "minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "requires": { + "brace-expansion": "^5.0.2" } } } @@ -15752,6 +15786,11 @@ "debug": "^4.3.4" } }, + "http-vary": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http-vary/-/http-vary-1.0.3.tgz", + "integrity": "sha512-sx7Y8YTqF3o0mFJJvF66n8dbaE8v3liV1RgCz46XP5xK7dnzyZHvwMWRA115q5kjbCPBV65/nOMlgW54WLyiag==" + }, "https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -16048,11 +16087,18 @@ } }, "jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "requires": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" + }, + "dependencies": { + "@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==" + } } }, "jest": { @@ -16290,9 +16336,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "requires": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -16816,9 +16862,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "requires": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -17285,9 +17331,9 @@ } }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" }, "lodash.groupby": { "version": "4.6.0", @@ -17584,9 +17630,9 @@ "integrity": "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==" }, "object-code": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.3.tgz", - "integrity": "sha512-/Ds4Xd5xzrtUOJ+xJQ57iAy0BZsZltOHssnDgcZ8DOhgh41q1YJCnTPnWdWSLkNGNnxYzhYChjc5dgC9mEERCA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-2.0.0.tgz", + "integrity": "sha512-qOwMF43O/VAD51nJAB7MKsf1yWksql6O1i0DHRo1yaOQM6xJQH0NAE9UKJzYB7lyKw1jnpeb2BmB8qakjxiYZA==" }, "object-treeify": { "version": "2.1.1", @@ -17907,37 +17953,37 @@ } }, "pm2": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.10.tgz", - "integrity": "sha512-sbk4HsnhtJMx1wJlhFQhYfDRzHtVK+cvdrIezbjM9WjSyc7kLtQ4nZ5K7JLOdLe3AevytmRcTiOa3VvAQrve2A==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-6.0.14.tgz", + "integrity": "sha512-wX1FiFkzuT2H/UUEA8QNXDAA9MMHDsK/3UHj6Dkd5U7kxyigKDA5gyDw78ycTQZAuGCLWyUX5FiXEuVQWafukA==", "requires": { "@pm2/agent": "~2.1.1", + "@pm2/blessed": "0.1.81", "@pm2/io": "~6.1.0", "@pm2/js-api": "~0.8.0", - "@pm2/pm2-version-check": "latest", + "@pm2/pm2-version-check": "^1.0.4", "ansis": "4.0.0-node10", - "async": "~3.2.6", - "blessed": "0.1.81", - "chokidar": "^3.5.3", - "cli-tableau": "^2.0.0", + "async": "3.2.6", + "chokidar": "3.6.0", + "cli-tableau": "2.0.1", "commander": "2.15.1", - "croner": "~4.1.92", - "dayjs": "~1.11.13", - "debug": "^4.3.7", + "croner": "4.1.97", + "dayjs": "1.11.15", + "debug": "4.4.3", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", - "js-yaml": "~4.1.0", + "js-yaml": "4.1.1", "mkdirp": "1.0.4", "needle": "2.4.0", - "pidusage": "~3.0", + "pidusage": "3.0.2", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", "pm2-multimeter": "^0.1.2", "pm2-sysmonit": "^1.2.8", - "promptly": "^2", - "semver": "^7.6.2", + "promptly": "2.2.0", + "semver": "7.7.2", "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1" @@ -17953,18 +17999,23 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, + "dayjs": { + "version": "1.11.15", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.15.tgz", + "integrity": "sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ==" + }, "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "requires": { "ms": "^2.1.3" } }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "requires": { "argparse": "^2.0.1" } @@ -18675,9 +18726,9 @@ } }, "systeminformation": { - "version": "5.25.11", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.25.11.tgz", - "integrity": "sha512-jI01fn/t47rrLTQB0FTlMCC+5dYx8o0RRF+R4BPiUNsvg5OdY0s9DKMFmJGrx5SwMZQ4cag0Gl6v8oycso9b/g==", + "version": "5.30.7", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.30.7.tgz", + "integrity": "sha512-33B/cftpaWdpvH+Ho9U1b08ss8GQuLxrWHelbJT1yw4M48Taj8W3ezcPuaLoIHZz5V6tVHuQPr5BprEfnBLBMw==", "optional": true }, "table2array": { @@ -18778,6 +18829,11 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" }, + "try": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/try/-/try-1.0.3.tgz", + "integrity": "sha512-AHA8khVCII6zKyRkyPo6pRwoR9v5jb7QFw6e5avtaVSkxVfaEucYIo06xnwB+pJaEarfYNbs7W3Vq+LZLZiWyA==" + }, "ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -18837,9 +18893,9 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==" }, "undici": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.12.0.tgz", - "integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==" + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.21.0.tgz", + "integrity": "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==" }, "undici-types": { "version": "7.8.0", From 14d8819d249796a3c5ff93f11dbcc297ef77183f Mon Sep 17 00:00:00 2001 From: PopeyeTheSai10r <107763146+PopeyeTheSai10r@users.noreply.github.com> Date: Sat, 14 Feb 2026 05:40:24 -0800 Subject: [PATCH 18/31] osn channels --- sites/osn.com/osn.com_ar.channels.xml | 86 +++++++++++++++------------ sites/osn.com/osn.com_en.channels.xml | 86 +++++++++++++++------------ 2 files changed, 94 insertions(+), 78 deletions(-) diff --git a/sites/osn.com/osn.com_ar.channels.xml b/sites/osn.com/osn.com_ar.channels.xml index 98df113fc..30aeeee39 100644 --- a/sites/osn.com/osn.com_ar.channels.xml +++ b/sites/osn.com/osn.com_ar.channels.xml @@ -1,62 +1,70 @@ - OSN TV Movies Action - Kapatid TV5 - ANC Animal Planet + Blippi and Friends + Bloomberg Originals HD + OSN TV Documentary + DWRR 101.9 + eClutch LIVE 2 + eClutch Access​ + eClutch LIVE 1 + eClutch Arabic​ + Esport 24 + Gametoon​ + Ginx​ + MCM Top + Motorvision + OSNtv Crime + OSNtv Movies Horror + OSNtv Movies Family + OSNtv Now + OSNtv Movies Comedy + OSNtv Showcase Classics + OSNtv One + Padeltime​ + OSNtv Pop up Love story + RFM TV + Kapatid TV5 + Alfa Series Channel + Alfa Series +2 + Al Safwa + Alfa Al Yawm + ANC Bloomberg - Crime & Investigation Network - Cine Mo + Cartoon Network Alfa Cinema 1 Alfa Cinema 2 - CNBC - CNN Cinema One Global - Discovery ID + Cine Mo + CNN + Crime & Investigation Network Discovery HD - DWRR 101.9 - DZMM Teleradyo - E! Entertainment Alfa Fann Fatafeat - GMA Pinoy TV GMA Life TV GMA News TV + GMA Pinoy TV H2 HD History HD - OSN TV Kidzone + Discovery ID Moonbug Kids - MTV Live HD + Music Now Myx Nickelodeon HD Nick Jr NickToons HD - Music Now - OSN TV Crime - OSNtv Movies Horror - OSN TV Comedy - OSN TV Showcase - OSN TV Movies Family - OSN TV Now - OSN TV Movies Premiere - OSN TV Movies Comedy - OSN TV Kids - OSN TV Mezze - OSN TV News - OSN TV Movies Hollywood - OSN TV Showcase Classics - OSN TV One - OSN TV Yahala Bil Arabi - OSN TV Yahala Aflam - OSN TV Yahala + OSNtv Comedy + OSNtv Kids + OSNtv Mezze + OSNtv Movies Action + OSNtv Movies Hollywood + OSNtv Movies Premiere + OSNtv Showcase + OSNtv Yahala + OSNtv Yahala Aflam + OSNtv Yahala Bil Arabi PBA Rush - Al Safwa - Alfa Series +2 - Alfa Series Channel - Sky News HD - Cartoon Network + DZMM Teleradyo TFC TLC HD - MTV 00s - Alfa Al Yawm diff --git a/sites/osn.com/osn.com_en.channels.xml b/sites/osn.com/osn.com_en.channels.xml index 462de041b..1a008dce2 100644 --- a/sites/osn.com/osn.com_en.channels.xml +++ b/sites/osn.com/osn.com_en.channels.xml @@ -1,62 +1,70 @@ - OSN TV Movies Action - Kapatid TV5 - ANC Animal Planet + Blippi and Friends + Bloomberg Originals HD + OSN TV Documentary + DWRR 101.9 + eClutch LIVE 2 + eClutch Access​ + eClutch LIVE 1 + eClutch Arabic​ + Esport 24 + Gametoon​ + Ginx​ + MCM Top + Motorvision + OSNtv Crime + OSNtv Movies Horror + OSNtv Movies Family + OSNtv Now + OSNtv Movies Comedy + OSNtv Showcase Classics + OSNtv One + Padeltime​ + OSNtv Pop up Love story + RFM TV + Kapatid TV5 + Alfa Series Channel + Alfa Series +2 + Al Safwa + Alfa Al Yawm + ANC Bloomberg - Crime & Investigation Network - Cine Mo + Cartoon Network Alfa Cinema 1 Alfa Cinema 2 - CNBC - CNN Cinema One Global - Discovery ID + Cine Mo + CNN + Crime & Investigation Network Discovery HD - DWRR 101.9 - DZMM Teleradyo - E! Entertainment Alfa Fann Fatafeat - GMA Pinoy TV GMA Life TV GMA News TV + GMA Pinoy TV H2 HD History HD - OSN TV Kidzone + Discovery ID Moonbug Kids - MTV Live HD + Music Now Myx Nickelodeon HD Nick Jr NickToons HD - Music Now - OSN TV Crime - OSNtv Movies Horror - OSN TV Comedy - OSN TV Showcase - OSN TV Movies Family - OSN TV Now - OSN TV Movies Premiere - OSN TV Movies Comedy - OSN TV Kids - OSN TV Mezze - OSN TV News - OSN TV Movies Hollywood - OSN TV Showcase Classics - OSN TV One - OSN TV Yahala Bil Arabi - OSN TV Yahala Aflam - OSN TV Yahala + OSNtv Comedy + OSNtv Kids + OSNtv Mezze + OSNtv Movies Action + OSNtv Movies Hollywood + OSNtv Movies Premiere + OSNtv Showcase + OSNtv Yahala + OSNtv Yahala Aflam + OSNtv Yahala Bil Arabi PBA Rush - Al Safwa - Alfa Series +2 - Alfa Series Channel - Sky News HD - Cartoon Network + DZMM Teleradyo TFC TLC HD - MTV 00s - Alfa Al Yawm From 1b2eb977a08c55fc2711dba5b077d1c176fc4ad4 Mon Sep 17 00:00:00 2001 From: PopeyeTheSai10r <107763146+PopeyeTheSai10r@users.noreply.github.com> Date: Sat, 14 Feb 2026 05:46:37 -0800 Subject: [PATCH 19/31] tv.movistar.com.pe channels --- .../tv.movistar.com.pe.channels.xml | 172 ++++++++---------- 1 file changed, 76 insertions(+), 96 deletions(-) diff --git a/sites/tv.movistar.com.pe/tv.movistar.com.pe.channels.xml b/sites/tv.movistar.com.pe/tv.movistar.com.pe.channels.xml index 889c09310..d2491aa59 100644 --- a/sites/tv.movistar.com.pe/tv.movistar.com.pe.channels.xml +++ b/sites/tv.movistar.com.pe/tv.movistar.com.pe.channels.xml @@ -1,43 +1,27 @@ - CANAL N ESPN INTERNACIONAL ESPN 3 Cartoon Network HD - TNT HD OTT + TNT HD LATINA HD AMERICA TELEVISION HD PANAMERICANA TELEVISION HD TV PERU HD ATV HD - LATINA - AMERICA TELEVISION - PANAMERICANA TELEVISION - TV PERU - ATV - RPP TV - TV PERU 7.3 GLOBAL LA TELE PERU - WILLAX - ATV+ TNT TNT SERIES TNT SERIES HD - SONY WARNER CHANNEL STAR CHANNEL - AXN - UNIVERSAL CHANNEL FX INVESTIGATION DISCOVERY TRU TV TCM SPACE - PARAMOUNT - I-SAT STUDIO UNIVERSAL - EUROCHANNEL CINECANAL CINEMAX HBO @@ -48,14 +32,12 @@ HBO PLUS ESTE HBO XTREME DISCOVERY CHANNEL - HISTORY CHANNEL NAT GEO HISTORY 2 DISCOVERY SCIENCE DISCOVERY TURBO TLC HOME & HEALTH - GLITZ CARTOON NETWORK DISCOVERY KIDS CARTOONITO @@ -63,58 +45,46 @@ ANIMAL PLANET DISNEY JUNIOR FOX SPORTS PREMIUM - FOX SPORTS 2 - FOX SPORTS 3 + ESPN 7 + ESPN 6 ESPN 2 - GOL TV GOLF CHANNEL - JCP - TOROS TV + JOCKEY CLUB WOBI CNN ESPAÑOL CNN INTERNACIONAL FOX NEWS - PODER JUDICIAL CAPITAL TV ENLACE TBN - ORBE 21 MTV - MTV HITS HTV CANAL N HD - GOLPERU HD STAR CHANNEL HD WARNER CHANNEL HD FX HD - ID HD - INVESTIGATION DISCOVERY HD + INV.DISCOVERY HD COMEDY CENTRAL HD SPACE HD - PARAMOUNT HD CINECANAL HD CINEMAX HD - ESPN 4 - FOX SPORTS 2 HD - FOX SPORTS 3 HD - GOL TV HD + ESPN 5 HD + ESPN 7 HD + ESPN 6 HD DISCOVERY THEATER HD DISCOVERY HD NAT GEO HD - TRU TV HD + LATINA FASHION ONE HD - ATRES SERIES HD DISCOVERY WORLD HD HOME & HEALTH HD DISCOVERY KIDS HD DISNEY CHANNEL HD NICK HD MTV HD - MTV 00S GLOBO TV TELEFE EL TRECE - TV CHILE TELESUR - NUESTRA TELE TVE ANTENA3 DEUTSCHE WELLE @@ -122,34 +92,23 @@ TV5 NHK CCTV - ARTV VOA PLAYBOY - VENUS - SEXTREME PLAYBOY HD CONGRESO - A&E - GOLPERU - ESPN 2 HD RPP HD HBO HD - QUALITY CHANNEL BABY TV - EL GOURMET HD BBC WORLD NEWS ESPN HD ESPN 3 HD - SPACE REGIONAL DTH LIVE - GOL PERU - ESPN EXTRA HD + SPACE HD + ESPN 4 HD ANIMAL PLANET HD TNT HD - M PLUS HD + PLUS LIFE M DEPORTES HD M DEPORTES - M PLUS - NICK JR OTT CABLE NOTICIAS HBO PLUS ESTE HD HBO SIGNATURE HD @@ -158,30 +117,23 @@ NAT GEO HD TEST01 TEST02 - CANAL J - ESPN 2 - KANAL D DRAMA - ZEE MUNDO + Juntos TV + ESPN 2 HD DISCOVERY HOME & GARDEN FOOD NETWORK - USMP TV - MOVISTAR EVENTOS 2 MOVISTAR EVENTOS Food Network HD Exitosa TV Exitosa TV INFO STAR PREMIUM - AZ CORAZON VE PLUS TV HGTV - AZ MUNDO NICKELODEON DISNEY PX SPORTS FRANCE24 JUSTICIA TV EWTN - PAXTV MOVISTAR EVENTOS HD TV PERÚ 7.3 HD WILLAX TV HD @@ -189,51 +141,24 @@ HGTV HD CARTOONITO HD CANAL J HD - RUSIA TODAY HD TVN CHILE - RUSIA TODAY CLOVER UCL TOONCAST - LOLLY KIDS - QUIALITY CHANNEL + KIDS STARS CLOVER CLOVER DISNEY JUNIOR - TOONCAST - LOLLY KIDS - Alianza Lima TV - Alianza Lima TV - Universitario TV - Universitario TV UCL - UCL - EL TIEMPO - Alianza TV + Movistar Te Informa U TV TV PERU HD - CANAL J - AMC HD Star TVE HD - Pasiones HD - Film & Arts HD - Love Nature HD Via X Esports HD - Mas Chic HD - Europa Europa HD EWTN - EUROCHANNEL - RAI ITALIA - ANTENA 3 - PX SPORTS TVE - K-DRAMA - I-SAT - GLITZ HTV TV5 - WOBI - NUESTRA TELE FRANCE24 TV GLOBO TVN CHILE @@ -241,9 +166,6 @@ Telefe Internacional ATV+ BABY TV - GLOBAL TV - CONGRESO - EXITOSA TV JUSTICIA TV ADULT SWIM ENLACE TBN @@ -251,9 +173,7 @@ IPe VIVA TV La Tele - JCP-JNE SOL TV - QUALITY TV JN19 TELEJUAN NUEVO TIEMPO PAXTV @@ -282,4 +202,64 @@ YouTube Youtube Kids Star+ + ATRES SERIES HD + CLAN HD + TVLIBERTAD + DAYSTAR HD + MOVISTAR EVENTOS 2 + AMERICA TELEVISION AREQUIPA + AMERICA TELEVISION CUSCO + AMERICA TELEVISION TRUJILLO + AMERICA TELEVISION CHICLAYO + AMERICA TELEVISION PIURA + PANAMERICANA TELEVISION AREQUIPA + PANAMERICANA TELEVISION CUSCO + PANAMERICANA TELEVISION TRUJILLO + PANAMERICANA TELEVISION CHICLAYO + PANAMERICANA TELEVISION PIURA + ALACOCINA TV + TOP LATINO + LATINA NOTICIAS + PBO + BBC WORLD NEWS + PLIM PLIM + TRIVU + OVACION + JNE TV + CRISTOVISION + NICK JR + L1MAX + L1 + AMERICA TELEVISION + ANTENA 3 + ATV + ATV+ + CANAL J + CANAL N + CONGRESO + EL TIEMPO + EXITOSA TV + GLOBAL TV + PODER JUDICIAL + KANAL D DRAMA + K-DRAMA + LATINA + LOLLY KIDS + Love Nature HD + M PLUS + PANAMERICANA TELEVISION + Pasiones HD + PAXTV + PX SPORTS + RPP TV + TOONCAST + TV CHILE + TV PERU + TV PERU 7.3 + UCL + USMP TV + VENUS + WILLAX + ZEE MUNDO + RAI ITALIA From c511e3ddc56ae7920f3cc5bdd076446848fcad83 Mon Sep 17 00:00:00 2001 From: PopeyeTheSai10r <107763146+PopeyeTheSai10r@users.noreply.github.com> Date: Sat, 14 Feb 2026 05:50:29 -0800 Subject: [PATCH 20/31] mujtvprogram.cz channels Fixes #2877 --- .../mujtvprogram.cz.channels.xml | 393 +++++++++--------- 1 file changed, 195 insertions(+), 198 deletions(-) diff --git a/sites/mujtvprogram.cz/mujtvprogram.cz.channels.xml b/sites/mujtvprogram.cz/mujtvprogram.cz.channels.xml index 0c8143117..ad0cf9a3e 100644 --- a/sites/mujtvprogram.cz/mujtvprogram.cz.channels.xml +++ b/sites/mujtvprogram.cz/mujtvprogram.cz.channels.xml @@ -1,219 +1,216 @@ - ČT1 - ČT2 - Nova - Prima - HBO - HBO2 - Cinemax AXN - Spektrum - Animal Planet - Discovery - Viasat Explorer - Viasat History - CS Film - Eurosport 1 - Nova Sport 1 - ČT sport - ÓČKO - MTV Europe - National Geographic - CNN - ČT24 - Eurosport 2 - TV Paprika - Spektrum Home - Disney Channel - Minimax - TVP 1 - TVP 2 - Polsat - ORF1 - ORF2 - ARD - 3SAT - ARTE - RTL - RTL2 - SAT1 - VOX - Kabel1 - Sport 1 - Film+ - FilmBox - FilmBox Plus - MTV 00s - Mezzo - Hustler - Cartoonito - Private TV - TV Noe - JimJam - Nova Cinema - National Geographic Wild - Extreme Sports Channel - TV Barrandov - Prima COOL - Sport 2 - BBC World News - Fishing & Hunting - Playboy - Travel Channel - MTV 80s - Baby TV - Ducktv - Stingray CMusic - Cinemax 2 - Euronews - Fashion TV - FilmBox Extra HD - France 24 (FR) - History Channel - LEO TV - Club MTV - Music Box - RT - Sky News - TV5 Monde - Blue Hustler MTV Europe CZ - DMAX - CNBC Europe - MTV 90s - MTV Hits - Deutsche Welle - PRO7 - Dvojka - Jednotka - Doma - Markíza - PLUS - JOJ - Spectrum - TA3 - Retro - Viasat Nature National Geographic HD - ZDF NEO - Al Jazeera English - Golf Channel - Prima Love - MTV Live HD - Stingray Classica - Stingray iConcerts - Deluxe Music - Duna (SK) - RTL - TV 8 - FilmBox Family - Film Europe - TLC - Bloomberg + Auto Motor Sport HD + CANAL+ Sport + Canal+ Action + Story 4 + Canal+ Sport 2 + Nova Sport 5 + Nova Sport 6 + Warner TV + Viasat True Crime + DVTV Extra + 3SAT Canal 24 Horas A11 - Erox HD - FightBox HD - SUPER RTL - TV Lux - M1 - Dajto - RELAX - DocuBox - CBS Reality - Cartoon Network - EroXXX HD - Prima ZOOM - FashionBox HD - Arena Sport 1 - WAU - ÓČKO STAR - KiKA - Disney Junior - M2 - ČT :D - ČT art - Duna (H) - RTL - Senzi - Rebel - Cool TV - 360TuneBox - Crime & Investigation + AMC + Animal Planet + ARTE AXN Black AXN White - ÓČKO EXPRES - Ginx eSports TV - Brazzers TV Europe - Arena Sport 2 - Mezzo Live HD - Investigation Discovery - ZDF - AMC - France 24 (EN) - FilmBox Premium - Jojko - HTV1 - HTV2 - Fast&FunBox HD - English Club TV - SAT.1 Gold - E! Entertainment - Mňam TV - Auto Motor Sport HD - Kino Barrandov Barrandov Krimi - JOJ Cinema - Nova Sport 2 - Food Network - Prima MAX - Paramount Network - Nova International - Markíza International - HBO3 - Premier Sport - JOJ Family - Dorcel TV - Prima PLUS - Nova Action - Nova Gold - Nova Fun - Mňau TV - Travelxp HD - Epic Drama - Televize Seznam - Prim KRIMI - Nick Jr. Czech - Nickelodeon - Power TV - Skylink 7 - Óčko Black HD - LALA TV + Cartoon Network + Cinemax 2 + Cinemax + CNBC Europe + CNN Prim NEWS + Crime & Investigation + CS Film CS History CS Horror CS Mystery - Nicktoons - Dorcel XXX - Love Nature HD + ČT1 + ČT2 + ČT24 + ČT art + ČT :D + ČT sport + ARD + Discovery + Disney Channel + Duna (SK) + E! Entertainment + Epic Drama + Eurosport 1 + Eurosport 2 + FashionBox HD + FilmBox + FilmBox Extra HD + FilmBox Family + FilmBox Premium + FilmBox Plus + Film Europe Film Europe + HD - CNN Prima News - Šlágr Premium - Vixen - Prima STAR - Premier Sport 2 + Film+ + Food Network + Golf Channel + HBO2 + HBO3 + HBO + History Channel + HTV1 + HTV2 + Investigation Discovery + JimJam + Kabel1 + Kino Barrandov + LALA TV + LEO TV + M1 + M2 + Minimax + Mňam TV + Mňau TV + MTV Europe + National Geographic + National Geographic Wild + Nickelodeon + Nick Jr. Czech + Nicktoons + Nova Action + Nova Cinema + Nova Fun + Nova Krimi + Nova International + Nova Lady + Nova Sport 1 + Nova Sport 2 Nova Sport 3 Nova Sport 4 - Nova Lady - Prima Show - JOJ Šport - RTVS Šport - RTVS 24 + ÓČKO + Óčko Black HD + ÓČKO EXPRES + ÓČKO STAR + ORF1 + ORF2 + Polsat + Power TV + Premier Sport 2 + Prima + Prima COOL + Prim KRIMI + Prim LOVE + Prima MAX + Prim SHOW + Prima STAR + Prima ZOOM + PRO7 + Rebel + Retro + RTL + RTL + RTL2 + SAT1 + SAT.1 Gold + Šlágr Premium + Spektrum + Spektrum Home + Sport 1 + Sport 2 + Televize Seznam + Fishing & Hunting + TLC + Travel Channel + Travelxp HD + TV Barrandov + TV Noe + Nova + TVP 1 + TVP 2 + TV Paprika + Viasat Explorer + Viasat History + Viasat Nature + VOX + ZDF + SUPER RTL + DMAX + KiKA + ZDF NEO + Music Box + 360TuneBox + Al Jazeera English + Baby TV + BBC World News + Bloomberg + Blue Hustler + Brazzers TV Europe + Cartoonito + CNN + Deluxe Music + Disney Junior + DocuBox + Dorcel TV + Dorcel XXX + Deutsche Welle + English Club TV + Erox HD + EroXXX HD + Euronews + Extreme Sports Channel + Fashion TV + Fast&FunBox HD + FightBox HD + France 24 (EN) + Ginx eSports TV + Hustler + Love Nature HD + Playboy + Private TV + RT + Sky News + Stingray Classica + Stingray CMusic + Stingray iConcerts + Vixen + France 24 (FR) + Mezzo + Mezzo Live HD + TV5 Monde + Cool TV + Duna (H) + RTL + Spectrum + ST24 Markíza Krimi - CANAL+ Sport JOJ 24 - Canal+ Action - Story 4 TV Spark JOJ Svet + JOJ Šport + Markíza KLASIK + JOJ Šport 2 + Arena Sport 1 + Arena Sport 2 + ducktv + ST2 + ST1 + JOJ Cinema + JOJ Family + Jojko + PLUS + WAU + Markíza + Dajto + Doma + Markíza International + Prima SK + Senzi + RTVS Šport + TA3 + TV 8 + JOJ + TV Lux From 035c3f0a9a3d56680c5ed76b29198bb47655dc1f Mon Sep 17 00:00:00 2001 From: "iptv-bot[bot]" <84861620+iptv-bot[bot]@users.noreply.github.com> Date: Sun, 15 Feb 2026 01:42:44 +0000 Subject: [PATCH 21/31] [Bot] Update SITES.md Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/22027696230) workflow. --- SITES.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SITES.md b/SITES.md index c3a569249..ae1aa5d7e 100644 --- a/SITES.md +++ b/SITES.md @@ -59,7 +59,7 @@ foxsports.com.au77🟢 foxtel.com.au9960🟢 freetv.tv77🟢 - freeview.co.uk16798🟢 + freeview.co.uk166104🟢 frikanalen.no11🟢 galamtv.kz2722🟢 gatotv.com475360🟢 @@ -91,7 +91,7 @@ mediaklikk.hu88🟢 mediasetinfinity.mediaset.it1313🟢 melita.com127110🟢 - meo.pt217189🟢 + meo.pt211185🟢 meuguia.tv10296🟢 mewatch.sg2524🟢 mi.tv2084614🟢 @@ -110,7 +110,7 @@ neo.io337230🟢 nhkworldpremium.com22🟢 nhl.com11🟢 - nostv.pt169152🟢 + nostv.pt167151🟢 novacyprus.com2924🟢 novasports.gr1616🟢 nowplayer.now.com288227🟢 @@ -222,7 +222,7 @@ virgintvgo.virginmedia.com238181🟢 visionplus.id250224🟢 vivoplay.com.br3970🟢 - vodafone.pt147135🟢 + vodafone.pt146135🟢 vtm.be76🟢 walesi.com.fj98🟢 watch.sportsnet.ca88🟢 From 16e7dd0eab7715428a66d481efd00216025648e4 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 08:23:23 +0300 Subject: [PATCH 22/31] Update worker.ts --- scripts/models/worker.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/models/worker.ts b/scripts/models/worker.ts index 8b625ffa9..94b94dfcb 100644 --- a/scripts/models/worker.ts +++ b/scripts/models/worker.ts @@ -1,9 +1,11 @@ import relativeTime from 'dayjs/plugin/relativeTime' import { Collection } from '@freearhey/core' import { Channel } from './channel' +import utc from 'dayjs/plugin/utc' import dayjs from 'dayjs' dayjs.extend(relativeTime) +dayjs.extend(utc) export interface WorkerData { host: string @@ -63,6 +65,9 @@ export class Worker { getLastUpdated(): string { if (!this.lastUpdated) return '-' - return dayjs().to(dayjs(this.lastUpdated)) + let now = dayjs() + if (process.env.NODE_ENV === 'test') now = dayjs.utc('2026-02-13') + + return dayjs.utc(this.lastUpdated).from(now) } } From dfb039cf210548cbf0c51fcd74daafadb8a92329 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:16:45 +0300 Subject: [PATCH 23/31] Create content.json --- sites/webtv.sk/__data__/content.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 sites/webtv.sk/__data__/content.json diff --git a/sites/webtv.sk/__data__/content.json b/sites/webtv.sk/__data__/content.json new file mode 100644 index 000000000..817661fd5 --- /dev/null +++ b/sites/webtv.sk/__data__/content.json @@ -0,0 +1 @@ +{"id":"golf_channel","content":[{"ChannelTitle":"Golf Channel","Start":"2026-02-17T00:00:00+01:00","Stop":"2026-02-17T05:00:00+01:00","Title":"Qatar Masters","Subtitle":"","Description":"Fin\u00e1lov\u00e9 kolo turnaje DP World Tour. Doha, Qatar., (\u0161port)","Icon":"","SeriesID":"dc1ad829a6c42cde31b0f84657eb90bb","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T05:00:00+01:00","Stop":"2026-02-17T07:00:00+01:00","Title":"The Bay vs Los Angeles","Subtitle":"","Description":"Tomorrow's Golf League. SoFi Center, Palm Beach State College, USA., (\u0161port)","Icon":"","SeriesID":"39eb4a8d024da076ce509b24c17e1a75","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T07:00:00+01:00","Stop":"2026-02-17T12:00:00+01:00","Title":"LIV Golf Adelaide","Subtitle":"","Description":"Fin\u00e1lov\u00e9 kolo turnaje LIV Golf. The Grange Golf Club, Australia., (\u0161port)","Icon":"","SeriesID":"735549e083f0cb5495881ee0f2530f16","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T12:00:00+01:00","Stop":"2026-02-17T12:25:00+01:00","Title":"The Golf Fix","Subtitle":"","Description":"Jak kontrolovat d\u00e9lku ran wedgemi. Kontrola vzd\u00e1lenosti je p\u0159edev\u0161\u00edm u ran wedgemi naprosto kl\u00ed\u010dov\u00fd p\u0159edpoklad golfov\u00e9ho \u00fasp\u011bchu. Zn\u00e1m\u00fd tren\u00e9r Devan Bonebrake v\u00e1m v dal\u0161\u00edm d\u00edlu po\u0159adu Golf Fix nab\u00eddne skv\u011bl\u00e9 tipy a cvi\u010den\u00ed pro zlep\u0161en\u00ed v t\u00e9to oblasti.., (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T12:00:00+01:00\/icon\/8793bfb65b85be90d64adfdb7163c022","SeriesID":"8793bfb65b85be90d64adfdb7163c022","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T12:25:00+01:00","Stop":"2026-02-17T12:30:00+01:00","Title":"Cestov\u00e1n\u00ed za golfem 2025","Subtitle":"","Description":"Profesion\u00e1ln\u00ed turnaje. B\u011bhem deseti d\u00edl\u016f s\u00e9rie Cestov\u00e1n\u00ed za golfem se spole\u010dn\u011b pod\u00edv\u00e1me jak na m\u00edsta, kam golfist\u00e9 v roce 2025 cestuj\u00ed nej\u010dast\u011bji, tak zav\u00edt\u00e1me do destinac\u00ed, kter\u00e1 si o sv\u00e9 slovo teprve \u0159\u00edkaj\u00ed.., (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T12:25:00+01:00\/icon\/724f5af276123ee230befad2a27fa7fd","SeriesID":"724f5af276123ee230befad2a27fa7fd","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T12:30:00+01:00","Stop":"2026-02-17T14:30:00+01:00","Title":"The Bay vs Los Angeles","Subtitle":"","Description":"(\u0161port)","Icon":"","SeriesID":"39eb4a8d024da076ce509b24c17e1a75","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T14:30:00+01:00","Stop":"2026-02-17T15:00:00+01:00","Title":"The Golf Fix","Subtitle":"","Description":"Um\u011bn\u00ed kr\u00e1tk\u00e9 hry. Nikdo nem\u00e1 r\u00e1d tr\u00e1pen\u00ed okolo greenu. P\u0159itom dobr\u00e1 kr\u00e1tk\u00e1 hra m\u016f\u017ee v\u00fdrazn\u011b pomoci sn\u00ed\u017eit sk\u00f3re. Pokud m\u00e1te probl\u00e9my s kr\u00e1tkou hrou, \u0159e\u0161en\u00ed nab\u00edz\u00ed v dal\u0161\u00edm d\u00edlu Golf Fix pr\u016fvodce Devan Bonebrake.., (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T14:30:00+01:00\/icon\/8793bfb65b85be90d64adfdb7163c022","SeriesID":"8793bfb65b85be90d64adfdb7163c022","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T15:00:00+01:00","Stop":"2026-02-17T20:00:00+01:00","Title":"LIV Golf Adelaide","Subtitle":"","Description":"Fin\u00e1lov\u00e9 kolo turnaje LIV Golf. The Grange Golf Club, Australia., (\u0161port)","Icon":"","SeriesID":"735549e083f0cb5495881ee0f2530f16","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T20:00:00+01:00","Stop":"2026-02-17T21:00:00+01:00","Title":"Sn\u011bhul\u00e1k","Subtitle":"","Description":"Romana Pavelkov\u00e1, (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T20:00:00+01:00\/icon\/782cd01f689e432d695a5c482dcbeee0","SeriesID":"782cd01f689e432d695a5c482dcbeee0","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T21:00:00+01:00","Stop":"2026-02-17T21:30:00+01:00","Title":"The Golf Fix","Subtitle":"","Description":"Jak potopit v\u00edc putt\u016f. M\u00edjet kr\u00e1tk\u00e9 putty m\u016f\u017ee znamenat pro celkov\u00e9 sk\u00f3re pohromu. Devan Bonebrake v\u00e1s v dal\u0161\u00edm pokra\u010dov\u00e1n\u00ed po\u0159adu Golf Fix provede v\u0161emi z\u00e1ludnostmi spojen\u00fdmi s puttov\u00e1n\u00edm.., (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T21:00:00+01:00\/icon\/8793bfb65b85be90d64adfdb7163c022","SeriesID":"8793bfb65b85be90d64adfdb7163c022","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T21:30:00+01:00","Stop":"2026-02-17T23:30:00+01:00","Title":"The Bay vs Los Angeles","Subtitle":"","Description":"(\u0161port)","Icon":"","SeriesID":"39eb4a8d024da076ce509b24c17e1a75","Genres":["\u0161port"],"Score":0},{"ChannelTitle":"Golf Channel","Start":"2026-02-17T23:30:00+01:00","Stop":"2026-02-18T00:00:00+01:00","Title":"The Golf Fix","Subtitle":"","Description":"Jak v golfu pracovat se spinem. Spin neboli zp\u011btn\u00e1 rotace m\u00ed\u010dku je jedn\u00edm z nejd\u016fle\u017eit\u011bj\u0161\u00edch faktor\u016f v golfu. Jak s n\u00edm pracovat a jak ho m\u00edt pod kontrolou v\u00e1s v dal\u0161\u00edm pokra\u010dov\u00e1n\u00ed po\u0159adu Golf Fix nau\u010d\u00ed Devan Bonebrake.., (\u0161port)","Icon":"\/channel\/golf_channel\/programme\/2026-02-17T23:30:00+01:00\/icon\/8793bfb65b85be90d64adfdb7163c022","SeriesID":"8793bfb65b85be90d64adfdb7163c022","Genres":["\u0161port"],"Score":0}]} \ No newline at end of file From f6d5f4da3fcfd250dd9b3cd97b6e2dd9a9f90d66 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:16:47 +0300 Subject: [PATCH 24/31] Create webtv.sk.test.js --- sites/webtv.sk/webtv.sk.test.js | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 sites/webtv.sk/webtv.sk.test.js diff --git a/sites/webtv.sk/webtv.sk.test.js b/sites/webtv.sk/webtv.sk.test.js new file mode 100644 index 000000000..b3b42d56a --- /dev/null +++ b/sites/webtv.sk/webtv.sk.test.js @@ -0,0 +1,68 @@ +const { parser, url, request } = require('./webtv.sk.config.js') +const fs = require('fs') +const path = require('path') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const customParseFormat = require('dayjs/plugin/customParseFormat') +dayjs.extend(customParseFormat) +dayjs.extend(utc) + +const date = dayjs.utc('2026-02-17', 'YYYY-MM-DD').startOf('d') +const channel = { site_id: 'golf_channel' } + +it('can generate valid url', () => { + expect(url).toBe('https://api.webtv.sk/epg/channel') +}) + +it('can generate valid request method', () => { + expect(request.method).toBe('POST') +}) + +it('can generate valid request headers', () => { + expect(request.headers).toMatchObject({ + 'content-type': 'application/json' + }) +}) + +it('can generate valid request data', () => { + expect(request.data({ channel, date })).toMatchObject({ + channel_id: 'golf_channel', + date: '2026-02-17T00:00:00.000Z' + }) +}) + +it('can parse response', () => { + const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json')) + + const results = parser({ content }).map(p => { + p.start = p.start.toJSON() + p.stop = p.stop.toJSON() + + return p + }) + + expect(results.length).toBe(12) + expect(results[0]).toMatchObject({ + title: 'Qatar Masters', + subtitle: '', + description: 'Finálové kolo turnaje DP World Tour. Doha, Qatar., (šport)', + categories: ['šport'], + start: '2026-02-16T23:00:00.000Z', + stop: '2026-02-17T04:00:00.000Z' + }) + expect(results[11]).toMatchObject({ + title: 'The Golf Fix', + subtitle: '', + description: + 'Jak v golfu pracovat se spinem. Spin neboli zpětná rotace míčku je jedním z nejdůležitějších faktorů v golfu. Jak s ním pracovat a jak ho mít pod kontrolou vás v dalším pokračování pořadu Golf Fix naučí Devan Bonebrake.., (šport)', + categories: ['šport'], + start: '2026-02-17T22:30:00.000Z', + stop: '2026-02-17T23:00:00.000Z' + }) +}) + +it('can handle empty guide', () => { + const results = parser({ content: '' }) + + expect(results).toMatchObject([]) +}) From 58da7b1165d4f3cc1211670beeb49b67c87335eb Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:16:56 +0300 Subject: [PATCH 25/31] Create webtv.sk.config.js --- sites/webtv.sk/webtv.sk.config.js | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 sites/webtv.sk/webtv.sk.config.js diff --git a/sites/webtv.sk/webtv.sk.config.js b/sites/webtv.sk/webtv.sk.config.js new file mode 100644 index 000000000..dc7045a28 --- /dev/null +++ b/sites/webtv.sk/webtv.sk.config.js @@ -0,0 +1,74 @@ +const axios = require('axios') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') + +dayjs.extend(utc) + +module.exports = { + site: 'webtv.sk', + days: 2, + delay: 1000, + url: 'https://api.webtv.sk/epg/channel', + request: { + method: 'POST', + headers: { + 'content-type': 'application/json' + }, + data({ channel, date }) { + return { + channel_id: channel.site_id, + date: dayjs.utc(date).toJSON() + } + } + }, + parser({ content }) { + return parseItems(content).map(item => { + return { + title: item.Title, + subtitle: item.Subtitle, + description: item.Description, + categories: item.Genres, + start: dayjs(item.Start), + stop: dayjs(item.Stop) + } + }) + }, + async channels() { + const data = await axios + .post( + 'https://api.webtv.sk/channels', + { type: 'TV', channels_content: null }, + { + headers: { + 'content-type': 'application/json' + } + } + ) + .then(r => r.data) + .catch(console.error) + + let channels = [] + for (const site_id in data.data) { + const channel = data.data[site_id] + + channels.push({ + site_id, + name: channel.name, + lang: 'sk' + }) + } + + return channels + } +} + +function parseItems(content) { + try { + const data = JSON.parse(content) + if (!data || !Array.isArray(data.content)) return [] + + return data.content + } catch { + return [] + } +} From d9334485c1fc394cecd0edb25d3310f8d5ad1637 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:17:03 +0300 Subject: [PATCH 26/31] Create webtv.sk.channels.xml --- sites/webtv.sk/webtv.sk.channels.xml | 189 +++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 sites/webtv.sk/webtv.sk.channels.xml diff --git a/sites/webtv.sk/webtv.sk.channels.xml b/sites/webtv.sk/webtv.sk.channels.xml new file mode 100644 index 000000000..058822546 --- /dev/null +++ b/sites/webtv.sk/webtv.sk.channels.xml @@ -0,0 +1,189 @@ + + + 360 TuneBox + Al Jazeera + Al Jazeera English + AMC + Animal Planet + Arena Sport 1 + Arena Sport 2 + Arirang TV + Armenia 1 TV + ATV Žiar + Auto Motor und Sport + AXN + AXN Black + AXN White + Barrandov + Barrandov Krimi + BTV + CETV + CGTN + CGTN Documentary + Cinemax + Cinemax 2 + HaHa TV + Crime & Investigation + ČSRTV + ČT1 + ČT2 + ČT24 + ČT :D - ČT art + Current Time + DajTo + Discovery + Disney Channel + Disney Junior + DocuBox + Doktor TV + Doma + Duck TV + Duck TV Plus + eClutch 1 + eClutch 2 + English Club TV + Espreso TV + Euronews + Eurosport 1 + Eurosport 2 + Fashion TV Czech & Slovak + FashionBox + Fast and Funbox + FightBox + Film + + FilmBox + Filmbox Arthouse + FilmBox Extra + FilmBox Family + FilmBox Stars + FilmBox Premium + Fishing&Hunting + Folklorika + Food Network + France 24 + France 24 English + Golf Channel + GTTV + HBO + HBO 2 + HBO 3 + HGTV + History 2 + History Channel + HN TV + Antik Info TV + ID + JimJam + JOJ + JOJ 24 + JOJ Cinema + JOJ Cinema +1 + JOJ Plus + JOJ +1 + JOJ Šport + JOJ Šport 2 + JOJ Svet + Kino Barrandov + Kitchen TV + LALA TV + LangLab + Life TV + Lingo Toons + TV LocAll + Love Nature + TV LUX + Markíza + Markíza Klasik + Markíza Krimi + Markíza +1 + Mestská Televízia Trnava + Mestská Tv Košice + Mestská Televízia Partizánske + Miestna TV Trebišov + Minimax + TV Mistral + Moldava TV + National Geographic Channel + National Geographic Wild + NHK World Japan + Nick Jr + Nickelodeon + Nicktoons + NOE + Nova International + Nova Sport 1 + Nova Sport 2 + tv NRSR + Óčko + Óčko Black + Óčko Expres + Óčko Star + Padel Time + PARK TV + Rebel + Relax + Polar TV + Prima Cool SK + Prima Krimi SK + Prima Love SK + CNN Prima News + Prima SK + Rai Tre + Rai Uno + Régió TV + A11 + Retro Music Television + RiK TV + Jojko + RVTV + Senzi + Seznam.cz TV + Skvelé TV + Sky News + PREMIUM + Šláger Muzika + Šláger Originál + Spektrum + Spektrum Home + Sport 1 + Sport 2 + STINGRAY iConcerts + Jednotka + Dvojka + :24 + :Šport + SuperYacht TV + TA3 + Tanečné súťaže + TLC + Travel Channel + TRT World + Turbo TV + TV7 + TV 9 + TV8 + TV Bratislava + TV Nitrička + TV Nové Zámky + TV Panoráma + TV Paprika + TV Piánko + TV Poprad + TV Považie + TV RAJ + TV Reduta + TV Romana + TV Ružinov + TV SEN + TV Kežmarok + Tv Vega + Godzone TV + TV Zemplín + TVP Info + TVP Polonia + TVP World + UA TV + Kanal1 + WAU + Televízia Slovensko + From 8ba0af82c7c4992d32ae16a7627c307a9f26e400 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:17:14 +0300 Subject: [PATCH 27/31] Create readme.md --- sites/webtv.sk/readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sites/webtv.sk/readme.md diff --git a/sites/webtv.sk/readme.md b/sites/webtv.sk/readme.md new file mode 100644 index 000000000..70cd24252 --- /dev/null +++ b/sites/webtv.sk/readme.md @@ -0,0 +1,21 @@ +# webtv.sk + +https://webtv.sk/archive + +### Download the guide + +```sh +npm run grab --- --site=webtv.sk +``` + +### Update channel list + +```sh +npm run channels:parse --- --config=./sites/webtv.sk/webtv.sk.config.js --output=./sites/webtv.sk/webtv.sk.channels.xml +``` + +### Test + +```sh +npm test --- webtv.sk +``` From f95b142a321ff53f37b3aaf7b6d8728d22e0119b Mon Sep 17 00:00:00 2001 From: "iptv-bot[bot]" <84861620+iptv-bot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 01:26:44 +0000 Subject: [PATCH 28/31] [Bot] Update SITES.md Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/22047035165) workflow. --- SITES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SITES.md b/SITES.md index ae1aa5d7e..b96ce3c4f 100644 --- a/SITES.md +++ b/SITES.md @@ -102,7 +102,7 @@ movistarplus.es1780🔴https://github.com/iptv-org/epg/issues/2865 mtel.ba5010🟢 mts.rs4570🟢 - mujtvprogram.cz216202🟢 + mujtvprogram.cz213190🟢 musor.tv181142🟢 mysky.com.ph11543🟢 mytelly.co.uk488387🟢https://github.com/iptv-org/epg/issues/2985 @@ -119,7 +119,7 @@ ontvtonight.com5177528🟢 opto.sic.pt44🟢 orangetv.orange.es273151🟢 - osn.com11898🟢 + osn.com13486🟢 passie.nl11🟢 pbsguam.org11🟢 pickx.be404375🟢 @@ -185,7 +185,7 @@ tv.lv13749🟢 tv.magenta.at307219🟢 tv.mail.ru664632🟢 - tv.movistar.com.pe28239🟢 + tv.movistar.com.pe26231🟢 tv.nu199180🟢 tv.post.lu332241🟢 tv.sfr.fr489438🟢https://github.com/iptv-org/epg/issues/2998 From ea43daf61c18778ea35a4bb4080db7f68dba3a94 Mon Sep 17 00:00:00 2001 From: PopeyeTheSai10r <107763146+PopeyeTheSai10r@users.noreply.github.com> Date: Mon, 16 Feb 2026 19:45:20 -0800 Subject: [PATCH 29/31] Update artonline.tv.config.js Fixes #2954 --- sites/artonline.tv/artonline.tv.config.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sites/artonline.tv/artonline.tv.config.js b/sites/artonline.tv/artonline.tv.config.js index 2b9fe78c4..b5abb1346 100644 --- a/sites/artonline.tv/artonline.tv.config.js +++ b/sites/artonline.tv/artonline.tv.config.js @@ -34,6 +34,7 @@ module.exports = { const programs = [] if (!content) return programs const items = JSON.parse(content) + if (!Array.isArray(items)) return programs items.forEach(item => { const image = parseImage(item) const start = parseStart(item) @@ -60,9 +61,9 @@ function parseStart(item) { } function parseDuration(item) { - const [, HH, mm, ss] = item.duration.match(/(\d+):(\d+):(\d+)/) + const [, HH, mm, ss] = item.duration.match(/(\d+):(\d+)(?::(\d+))?/) - return parseInt(HH) * 3600 + parseInt(mm) * 60 + parseInt(ss) + return parseInt(HH) * 3600 + parseInt(mm) * 60 + parseInt(ss || 0) } function parseImage(item) { From a1168b74f5d51a26fdf51129c9af7a296f04b9f6 Mon Sep 17 00:00:00 2001 From: "iptv-bot[bot]" <84861620+iptv-bot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:28:40 +0000 Subject: [PATCH 30/31] [Bot] Update SITES.md Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/22122778901) workflow. --- SITES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SITES.md b/SITES.md index b96ce3c4f..f5b04da77 100644 --- a/SITES.md +++ b/SITES.md @@ -99,7 +99,7 @@ moji.id11🟢 mojmaxtv.hrvatskitelekom.hr2430🟢 mon-programme-tv.be11194🟢 - movistarplus.es1780🔴https://github.com/iptv-org/epg/issues/2865 + movistarplus.es1780🟢 mtel.ba5010🟢 mts.rs4570🟢 mujtvprogram.cz213190🟢 From 2fccdd42a820e820436dba721fd58edc58eb2cf2 Mon Sep 17 00:00:00 2001 From: "iptv-bot[bot]" <84861620+iptv-bot[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:28:29 +0000 Subject: [PATCH 31/31] [Bot] Update SITES.md Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/22164807042) workflow. --- SITES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SITES.md b/SITES.md index f5b04da77..c2da69e56 100644 --- a/SITES.md +++ b/SITES.md @@ -116,7 +116,7 @@ nowplayer.now.com288227🟢 nuevosiglo.com.uy17346🟢 nzxmltv.com532118🟢 - ontvtonight.com5177528🟢 + ontvtonight.com5177528🟢https://github.com/iptv-org/epg/issues/3014 opto.sic.pt44🟢 orangetv.orange.es273151🟢 osn.com13486🟢