Merge pull request #2821 from whitesnakeftw/master

Fix tvprofil.com + tvguide.com + tvarenasport.com + guidatv.sky.it
This commit is contained in:
PopeyeTheSai10r
2025-08-15 05:00:35 -07:00
committed by GitHub
24 changed files with 38908 additions and 22132 deletions

View File

@@ -549,8 +549,8 @@
<channel site="directv.com" lang="en" xmltv_id="GolfChannel.us" site_id="218#5605">Golf Channel HD</channel>
<channel site="directv.com" lang="en" xmltv_id="GolfChannel.us" site_id="218#605">Golf Channel</channel>
<channel site="directv.com" lang="en" xmltv_id="GolTVUSA.us" site_id="468#3641">GolTV</channel>
<channel site="directv.com" lang="en" xmltv_id="GreatAmericanCountry.us" site_id="326#326">Great American Family</channel>
<channel site="directv.com" lang="en" xmltv_id="GreatAmericanCountry.us" site_id="326#573">Great American Family HD</channel>
<channel site="directv.com" lang="en" xmltv_id="GreatAmericanFamily.us" site_id="326#326">Great American Family</channel>
<channel site="directv.com" lang="en" xmltv_id="GreatAmericanFamily.us" site_id="326#573">Great American Family HD</channel>
<channel site="directv.com" lang="en" xmltv_id="Grit.us" site_id="81#6172">GRIT</channel>
<channel site="directv.com" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="312#312">Hallmark</channel>
<channel site="directv.com" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="312#3771">Hallmark Channel HD</channel>

View File

@@ -1 +1 @@
{"events": [ { "channel": { "id": 10458, "logo": "/logo/545820mediasethd_Light_Fit.png", "logoPadding": "/logo/545820mediasethd_Light_Padding.png", "logoDark": "/logo/545820mediasethd_Dark_Fit.png", "logoDarkPadding": "/logo/545820mediasethd_Dark_Padding.png", "logoLight": "/logo/545820mediasethd_Light_Padding.png", "name": "20Mediaset HD", "number": 151, "category": { "id": 3, "name": "Intrattenimento" } }, "content": { "uuid": "77c630aa-4744-44cb-a88e-3e871c6b73d9", "contentTitle": "Distretto di Polizia", "episodeNumber": 26, "seasonNumber": 6, "url": "/serie-tv/distretto-di-polizia/stagione-6/episodio-26/77c630aa-4744-44cb-a88e-3e871c6b73d9", "genre": { "id": 1, "name": "Intrattenimento" }, "subgenre": { "id": 9, "name": "Fiction" }, "imagesMap": [ { "key": "background", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/background?md5ChecksumParam=88d3f48ce855316f4be25ab9bb846d32" } }, { "key": "cover", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/cover?md5ChecksumParam=61135b999a63e3d3f4a933b9edeb0c1b" } }, { "key": "scene", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/16-9?md5ChecksumParam=f41bfe414bec32505abdab19d00b8b43" } } ] }, "eventId": "139585132", "starttime": "2022-05-06T00:35:40Z", "endtime": "2022-05-06T01:15:40Z", "eventTitle": "Distretto di Polizia", "eventSynopsis": "S6 Ep26 La resa dei conti - Fino all'ultimo la sfida tra Ardenzi e Carrano, nemici di vecchia data, riserva clamorosi colpi di scena. E si scopre che non e' tutto come sembrava.", "epgEventTitle": "S6 Ep26 - Distretto di Polizia", "primeVision": false, "resolutions": [ { "resolutionType": "resolution4k", "value": false } ] }]}
{"events": [ { "channel": { "id": 10458, "logo": "/logo/545820mediasethd_Light_Fit.png", "logoPadding": "/logo/545820mediasethd_Light_Padding.png", "logoDark": "/logo/545820mediasethd_Dark_Fit.png", "logoDarkPadding": "/logo/545820mediasethd_Dark_Padding.png", "logoLight": "/logo/545820mediasethd_Light_Padding.png", "name": "20Mediaset HD", "number": 151, "category": { "id": 3, "name": "Intrattenimento" } }, "content": { "uuid": "77c630aa-4744-44cb-a88e-3e871c6b73d9", "contentTitle": "Distretto di Polizia", "episodeNumber": 26, "seasonNumber": 6, "url": "/serie-tv/distretto-di-polizia/stagione-6/episodio-26/77c630aa-4744-44cb-a88e-3e871c6b73d9", "genre": { "id": 1, "name": "Intrattenimento" }, "subgenre": { "id": 9, "name": "Fiction" }, "imagesMap": [ { "key": "background", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/background?md5ChecksumParam=88d3f48ce855316f4be25ab9bb846d32" } }, { "key": "cover", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/cover?md5ChecksumParam=61135b999a63e3d3f4a933b9edeb0c1b" } }, { "key": "scene", "img": { "url": "/uuid/77c630aa-4744-44cb-a88e-3e871c6b73d9/16-9?md5ChecksumParam=f41bfe414bec32505abdab19d00b8b43" } } ] }, "eventId": "139585132", "starttime": "2022-05-06T00:35:40Z", "endtime": "2022-05-06T01:15:40Z", "eventTitle": "Distretto di Polizia", "eventSynopsis": "S6 Ep26 La resa dei conti - Fino all'ultimo la sfida tra Ardenzi e Carrano, nemici di vecchia data, riserva clamorosi colpi di scena. E si scopre che non e' tutto come sembrava.", "epgEventTitle": "S6 Ep26 - Distretto di Polizia", "primeVision": false, "resolutions": [ { "resolutionType": "resolution4k", "value": false } ] }]}

File diff suppressed because it is too large Load Diff

View File

@@ -1,98 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#10713">CNBC HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11216">Sky Crime</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11247">Sky Serie +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11490">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11491">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11492">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11494">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11496">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#11497">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#445">Sky News</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#617">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#6862">NHK World TV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#8336">Sky Crime</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#8453">Sky Atlantic +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="" site_id="DTH#9047">Heroes Collection</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="20.it@HD" site_id="DTH#10458">20Mediaset HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ACISportTV.it" site_id="DTH#7587">ACI Sport Tv</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="AlJazeera.qa@EnglishHD" site_id="DTH#5113">Al Jazeera Intl. HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="BBCNews.uk@Europe" site_id="DTH#891">BBC World News</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="BikeChannel.it" site_id="DTH#11278">BIKE</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="BloombergTV.us@Europe" site_id="DTH#349">Bloomberg</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boing.it" site_id="DTH#6628">Boing</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boomerang.it" site_id="DTH#472">Boomerang</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boomerang.it@Plus1" site_id="DTH#479">Boomerang +1</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="CNNInternational.us@MENA" site_id="DTH#312">CNN Intl.</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CacciaePesca.it" site_id="DTH#520">CACCIA e Pesca</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Canale5.it@HD" site_id="DTH#10354">Canale 5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CartoonNetwork.it@HD" site_id="DTH#9693">Cartoon Network HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CartoonNetwork.it@Plus1" site_id="DTH#476">Cartoon +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cartoonito.it" site_id="DTH#8132">CARTOONITO DTT</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cielo.it" site_id="DTH#8133">cielo</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cine34.it@HD" site_id="DTH#10893">Cine34 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ClassCNBC.it" site_id="DTH#308">Class CNBC</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Classica.it@HD" site_id="DTH#11437">Classica HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ComedyCentral.it" site_id="DTH#318">Comedy Central</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ComedyCentral.it@Plus1" site_id="DTH#8353">Comedy +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DMAX.it@HD" site_id="DTH#8933">DMAX HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAJunior.it" site_id="DTH#7427">DeAJunior</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAKids.it" site_id="DTH#460">DeAKids</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAKids.it@Plus1" site_id="DTH#364">DeAKids +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeejayTV.it" site_id="DTH#462">Deejay TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DiscoveryChannel.it@HD" site_id="DTH#9059">Discovery HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DiscoveryChannel.it@Plus1" site_id="DTH#331">Discovery +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="EQUtv.it" site_id="DTH#8293">EQUtv</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="EmiliaRomagna24.it" site_id="DTH#10615">Emilia Romagna 24</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="EuronewsEnglish.fr" site_id="DTH#801">Euronews</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Eurosport1.fr@Italy" site_id="DTH#9057">Eurosport HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Eurosport2.fr@Italy" site_id="DTH#9060">Eurosport 2 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ExplorerHDChannel.it" site_id="DTH#11262">Explorer HD Channel</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="FashionTVEurope.fr" site_id="DTH#810">Fashion TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Focus.it@HD" site_id="DTH#10470">Focus HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="FoodNetwork.it@HD" site_id="DTH#10534">Food Network HD</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="FoxBusinessNetwork.us" site_id="DTH#6741">Fox Business</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="FoxNewsChannel.us" site_id="DTH#446">Fox News</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="France24.fr@EnglishHD" site_id="DTH#7968">France 24 English HD</channel>
<channel site="guidatv.sky.it" lang="fr" xmltv_id="France24.fr@FrenchHD" site_id="DTH#5119">France 24 Francais HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Frisbee.it" site_id="DTH#6610">-frisbee-</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="20.it@HD" site_id="DTH#10458">20Mediaset HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ACISportTV.it" site_id="DTH#7587">ACI Sport TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="BBCNews.uk@Europe" site_id="DTH#891">BBC World News</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="BikeChannel.it" site_id="DTH#11278">BIKE</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boing.it" site_id="DTH#6628">Boing</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boomerang.it" site_id="DTH#472">Boomerang</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Boomerang.it@Plus1" site_id="DTH#479">Boomerang +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CacciaePesca.it" site_id="DTH#520">CACCIA e Pesca</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Canale5.it@HD" site_id="DTH#10354">Canale 5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cartoonito.it" site_id="DTH#8132">CARTOONITO DTT</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CartoonNetwork.it@HD" site_id="DTH#9693">Cartoon Network</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CartoonNetwork.it@Plus1" site_id="DTH#476">Cartoon Network +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cielo.it" site_id="DTH#8133">cielo</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Cine34.it@HD" site_id="DTH#10893">Cine34 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ClassCNBC.it" site_id="DTH#308">Class CNBC</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Classica.it@HD" site_id="DTH#11437">Sky Classica</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="CNBCEurope.uk" site_id="DTH#10713">CNBC HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ComedyCentral.it" site_id="DTH#318">Comedy Central</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ComedyCentral.it@Plus1" site_id="DTH#8353">Comedy +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAJunior.it" site_id="DTH#7427">DeAJunior</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAKids.it" site_id="DTH#460">DeAKids</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeAKids.it@Plus1" site_id="DTH#364">DeAKids +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="DeejayTV.it" site_id="DTH#462">Deejay TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="EQUtv.it" site_id="DTH#8293">EQUtv</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="FashionTVEurope.fr" site_id="DTH#810">Fashion TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Focus.it@HD" site_id="DTH#10470">Focus HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="GamberoRossoChannel.it@HD" site_id="DTH#9099">Gambero Rosso HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="GamberoRossoChannel.it@HD" site_id="DTH#11055">Gambero Rosso HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Giallo.it@HD" site_id="DTH#8131">GIALLO HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="HGTV.it@HD" site_id="DTH#11154">HGTV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="History.it@HD" site_id="DTH#9101">History HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="History.it@HD" site_id="DTH#9101">History</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="History.it@Plus1" site_id="DTH#123">History +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="HorseTVHD.it" site_id="DTH#6611">Horse TV HD</channel>
<channel site="guidatv.sky.it" lang="en" xmltv_id="i24NEWSEnglishWorld.il" site_id="DTH#8273">i24news</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="HorseTV.it" site_id="DTH#6611">Horse TV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="InterTV.it" site_id="DTH#9893">Inter TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Iris.it@HD" site_id="DTH#10467">Iris HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Italia1.it@HD" site_id="DTH#10454">Italia 1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Italia2.it@HD" site_id="DTH#10469">Mediaset Italia2 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="K2.it" site_id="DTH#6240">K2</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="La5.it@HD" site_id="DTH#10466">La 5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="LA7d.it" site_id="DTH#6624">LA7D</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="LA7d.it@HD" site_id="DTH#319">LA7 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="La5.it@HD" site_id="DTH#10466">La 5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="LazioStyleChannel.it@HD" site_id="DTH#7527">Lazio Style HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MediasetExtra.it@HD" site_id="DTH#10465">Mediaset Extra HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MilanTV.it" site_id="DTH#9513">Milan TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MTV.it@HD" site_id="DTH#9195">MTV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MTVMusic.it" site_id="DTH#528">MTV Music</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MTVMusic.it" site_id="DTH#11054">MTV Music</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MediasetExtra.it@HD" site_id="DTH#10465">Mediaset Extra HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MilanTV.it" site_id="DTH#9513">Milan TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="MotorTrend.it@HD" site_id="DTH#8130">Motor Trend HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="NickJr.it" site_id="DTH#461">Nick Jr</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="NickJr.it@Plus1" site_id="DTH#6701">Nick Jr +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="NHKWorldJapan.jp" site_id="DTH#6862">NHK World TV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Nickelodeon.it" site_id="DTH#320">Nickelodeon</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Nickelodeon.it@Plus1" site_id="DTH#6140">Nickelodeon +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Nove.it@HD" site_id="DTH#9753">NOVE HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="NickJr.it" site_id="DTH#461">Nick Jr</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="NickJr.it@Plus1" site_id="DTH#6701">Nick Jr. +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="PescaeCaccia.it" site_id="DTH#6220">Caccia e PESCA</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="QVC.it" site_id="DTH#6626">QVC</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RTL1025TV.it@HD" site_id="DTH#6885">RTL 102.5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Radiofreccia.it@HD" site_id="DTH#10616">RADIOFRECCIA HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RadioItaliaTrendTV.it" site_id="DTH#10033">Radio Italia Trend Tv HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RadioItaliaTV.it@HD" site_id="DTH#9833">Radio Italia TV HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RadioItaliaTrendTVHD.it" site_id="DTH#10033">Radio Italia Trend Tv HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RadioMonteCarloTV.it" site_id="DTH#10993">Radio Monte Carlo</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RadioNorbaTV.it" site_id="DTH#8213">RADIONORBA TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Radiofreccia.it@HD" site_id="DTH#10616">RADIOFRECCIA HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Rai1.it@HD" site_id="DTH#899">Rai 1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Rai2.it@HD" site_id="DTH#898">Rai 2 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Rai3.it@HD" site_id="DTH#897">Rai 3 HD</channel>
@@ -105,67 +75,83 @@
<channel site="guidatv.sky.it" lang="it" xmltv_id="RaiSport.it" site_id="DTH#807">RAI Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RaiStoria.it" site_id="DTH#6630">Rai Storia</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RaiYoyo.it" site_id="DTH#6609">Rai Yoyo</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RealTime.it@HD" site_id="DTH#8173">Real Time HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Rete4.it@HD" site_id="DTH#10464">Rete 4 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="RTL1025TV.it@HD" site_id="DTH#6885">RTL 102.5 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SanMarinoRTV.sm" site_id="DTH#6861">San Marino RTV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArteHD.it" site_id="DTH#7767">Sky Arte</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArteHD.it" site_id="DTH#8473">Sky Arte</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArtePlus1HD.it" site_id="DTH#11276">Sky Arte +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArtePlus1HD.it" site_id="DTH#11277">Sky Arte +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyAdventure.it" site_id="DTH#11889">Sky Adventure</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyAdventure.it" site_id="DTH#11890">Sky Adventure</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArte.it" site_id="DTH#7767">Sky Arte</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyArte.it" site_id="DTH#8473">Sky Arte</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyAtlantic.it" site_id="DTH#9095">Sky Atlantic</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyAtlantic.it@Plus1" site_id="DTH#8453">Sky Atlantic HD +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCalcio10.it" site_id="DTH#615">Sky Calcio 10</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCalcio11.it" site_id="DTH#617">Sky Calcio 11</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaAction.it" site_id="DTH#9050">Sky Cinema Action</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaCollection.it" site_id="DTH#9047">Sky Cinema Collection</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaComedy.it" site_id="DTH#9039">Sky Cinema Comedy</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaDrama.it" site_id="DTH#10518">Sky Cinema Drama</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaDue.it" site_id="DTH#9034">Sky Cinema Due</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaDuePlus24.it" site_id="DTH#10517">Sky Cinema Due +24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaDue.it@Plus24" site_id="DTH#10517">Sky Cinema Due +24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaFamily.it" site_id="DTH#9042">Sky Cinema Family</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaRomance.it" site_id="DTH#9055">Sky Cinema Romance</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaSuspense.it" site_id="DTH#10515">Sky Cinema Suspense</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaUno.it" site_id="DTH#9044">Sky Cinema Uno</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCinemaUno.it@Plus24" site_id="DTH#9037">Sky Cinema Uno +24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCrime.it" site_id="DTH#8336">Sky Crime</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyCrime.it" site_id="DTH#11216">Sky Crime</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it" site_id="DTH#11239">Sky Documentaries</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it" site_id="DTH#11241">Sky Documentaries</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it@Plus1" site_id="DTH#11240">Sky Documentaries +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it@Plus1" site_id="DTH#11243">Sky Documentaries +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it@Plus1" site_id="DTH#11240">Sky Documentaries +1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyDocumentaries.it@Plus1" site_id="DTH#11243">Sky Documentaries +1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyInvestigation.it" site_id="DTH#11246">Sky Investigation</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyInvestigation.it@Plus1" site_id="DTH#11238">Sky Investigation +1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyMeteo24.it" site_id="DTH#321">Sky Meteo24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyNature.it" site_id="DTH#11242">Sky Nature</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyNature.it" site_id="DTH#11245">Sky Nature</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyNews.uk" site_id="DTH#445">Sky News</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySerie.it" site_id="DTH#11244">Sky Serie</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySerie.it@Plus1" site_id="DTH#11247">Sky Serie +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport4K.it" site_id="DTH#10013">Sky Sport 4K</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport8.it" site_id="DTH#11386">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport9.it" site_id="DTH#9046">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport10.it" site_id="DTH#8613">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport11.it" site_id="DTH#615">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport24.it" site_id="DTH#929">Sky Sport24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport24.it" site_id="DTH#9094">Sky Sport24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport251.it" site_id="DTH#11497">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport252.it" site_id="DTH#11496">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport253.it" site_id="DTH#11494">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport254.it" site_id="DTH#11490">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport255.it" site_id="DTH#11491">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport256.it" site_id="DTH#11492">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport257.it" site_id="DTH#11386">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport258.it" site_id="DTH#9046">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySport259.it" site_id="DTH#8613">Sky Sport</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportArena.it" site_id="DTH#7507">Sky Sport Arena</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportArena.it" site_id="DTH#9093">Sky Sport Arena</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportBasket.it" site_id="DTH#9116">Sky Sport Basket</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportCalcio.it" site_id="DTH#9113">Sky Sport Calcio</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportF1.it" site_id="DTH#9096">Sky Sport F1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportGolf.it" site_id="DTH#10254">Sky Sport Golf</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportLegend.it" site_id="DTH#11910">Sky Sport Legend</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportMax.it" site_id="DTH#9103">Sky Sport Max</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportMotoGP.it" site_id="DTH#8434">Sky Sport MotoGP</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportNBA.it" site_id="DTH#8753">Sky Sport NBA</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportMix.it" site_id="DTH#11909">Sky Sport Mix</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportMotoGP.it" site_id="DTH#9102">Sky Sport MotoGP</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportBasket.it" site_id="DTH#8753">Sky Sport Basket</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportTennis.it" site_id="DTH#11237">Sky Sport Tennis</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportUno.it" site_id="DTH#8714">Sky Sport Uno</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyTG24PrimoPiano.it" site_id="DTH#6510">TG24PrimoPiano</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkySportUno.it" site_id="DTH#11346">Sky Sport Uno</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyTG24.it" site_id="DTH#9117">Sky TG24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyTG24PrimoPiano.it" site_id="DTH#6510">TG24PrimoPiano</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyUno.it" site_id="DTH#9115">Sky Uno</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SkyUno.it@Plus1" site_id="DTH#9114">Sky Uno +1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Super.it" site_id="DTH#6460">Super!</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="SuperTennis.it@HD" site_id="DTH#6000">SuperTennis HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TGNorba24.it" site_id="DTH#6481">TG NORBA 24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TGCom24.it@HD" site_id="DTH#10473">TgCom24 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TGNorba24.it" site_id="DTH#6481">TG NORBA 24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TopCrime.it@HD" site_id="DTH#10468">TOPcrime HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TRMh24.it" site_id="DTH#9013">TRM h24</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TV8.it@HD" site_id="DTH#8195">TV8 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TV2000.it@HD" site_id="DTH#7588">TV2000 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="TopCrime.it@HD" site_id="DTH#10468">TOPcrime HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Twentyseven.it@HD" site_id="DTH#11342">27Twentyseven HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="VH1.it@HD" site_id="DTH#10918">VH1 HD</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="Value24TV.it" site_id="DTH#11712">VALUE 24 TV</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="VirginRadioTV.it" site_id="DTH#11344">Virgin Radio</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN2.it" site_id="DTH#11401">ZONA DAZN 2</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN3.it" site_id="DTH#11403">ZONA DAZN 3</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN4.it" site_id="DTH#11405">ZONA DAZN 4</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN5.it" site_id="DTH#11404">ZONA DAZN 5</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN.it" site_id="DTH#11402">ZONA DAZN</channel>
</channels>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN2.it" site_id="DTH#11401">DAZN 2</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN3.it" site_id="DTH#11849">DAZN3</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN4.it" site_id="DTH#11850">DAZN4</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN.it" site_id="DTH#11402">DAZN 1</channel>
</channels>

View File

@@ -1,4 +1,5 @@
const dayjs = require('dayjs')
const axios = require('axios')
module.exports = {
site: 'guidatv.sky.it',
@@ -31,29 +32,21 @@ module.exports = {
return programs
},
async channels() {
const axios = require('axios')
const cheerio = require('cheerio')
const res = await axios.get('https://apid.sky.it/gtv/v1/channels?env=DTH')
const list = res.data?.channels || []
const channels = list.map(ch => {
const num = (ch.number >= 251 && ch.number <= 259) ? ch.number : ''
const hd = /\bHD\b/i.test(ch.name)
const plus = ch.name.match(/\+(1|24)\b/)?.[1]
const feeds = (hd ? '@HD' : '') + (plus ? (plus === '1' ? '@Plus1' : '@Plus24') : '')
const data = await axios
.get('https://guidatv.sky.it/canali')
.then(r => r.data)
.catch(console.log)
const $ = cheerio.load(data)
let channels = []
$('.c-channelsCard__container').each((i, el) => {
const name = $(el).find('.c-channelsCard__title').text()
const url = $(el).find('.c-channelsCard__link').attr('href')
const [, channelId] = url.match(/\/(\d+)$/)
channels.push({
return {
lang: 'it',
site_id: `DTH#${channelId}`,
name
})
site_id: `DTH#${ch.id}`,
name: ch.name,
xmltv_id: ch.name.replace(/ |HD|\+1|\+24/g, '') + num + '.it' + feeds,
}
})
return channels
}
}

View File

@@ -1,6 +1,7 @@
const { parser, url } = require('./guidatv.sky.it.config.js')
const { parser, url, channels } = require('./guidatv.sky.it.config.js')
const fs = require('fs')
const path = require('path')
const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
@@ -50,3 +51,23 @@ it('can handle empty guide', () => {
})
expect(result).toMatchObject([])
})
it('can parse channel list', async () => {
const mockResponse = fs.readFileSync(path.join(__dirname, '__data__', 'data.json'), 'utf8')
axios.get = jest.fn().mockResolvedValue({ data: JSON.parse(mockResponse) })
const results = await channels()
expect(results.length).toBe(154)
expect(results[0]).toMatchObject({
site_id: 'DTH#9115',
name: 'Sky Uno',
lang: 'it',
xmltv_id: 'SkyUno.it',
})
expect(results[29]).toMatchObject({
site_id: 'DTH#9094',
name: 'Sky Sport24',
lang: 'it',
xmltv_id: 'SkySport24.it',
})
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1.rs" site_id="01">Arena Sport 1</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1Premium.rs" site_id="a1p">Arena 1 Premium</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1x2.rs" site_id="1x2">Arena Sport 1x2</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport2.rs" site_id="02">Arena Sport 2</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport2Premium.rs" site_id="a2p">Arena 2 Premium</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport3.rs" site_id="03">Arena Sport 3</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport3Premium.rs" site_id="a3p">Arena 3 Premium</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport4.rs" site_id="04">Arena Sport 4</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport5.rs" site_id="05">Arena Sport 5</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport6.rs" site_id="06">Arena Sport 6</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport7.rs" site_id="07">Arena Sport 7</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport8.rs" site_id="08">Arena Sport 8</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="" site_id="09">Arena Sport 9</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="" site_id="10">Arena Sport 10</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1Premium.rs" site_id="a1p" logo="https://www.tvarenasport.com/files/img/icons/chanel-a1p.png">Arena Sport 1 Premium Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport2Premium.rs" site_id="a2p" logo="https://www.tvarenasport.com/files/img/icons/chanel-a2p.png">Arena Sport 2 Premium Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport3Premium.rs" site_id="a3p" logo="https://www.tvarenasport.com/files/img/icons/chanel-a3p.png">Arena Sport 3 Premium Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport4Premium.rs" site_id="a4p" logo="https://www.tvarenasport.com/files/img/icons/chanel-a4p.png">Arena Sport 4 Premium Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport5Premium.rs" site_id="aa5p" logo="https://www.tvarenasport.com/files/img/icons/chanel-aa5p.png">Arena Sport 5 Premium Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1.rs" site_id="01" logo="https://www.tvarenasport.com/files/img/icons/chanel-01.png">Arena Sport 1 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport2.rs" site_id="02" logo="https://www.tvarenasport.com/files/img/icons/chanel-02.png">Arena Sport 2 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport3.rs" site_id="03" logo="https://www.tvarenasport.com/files/img/icons/chanel-03.png">Arena Sport 3 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport4.rs" site_id="04" logo="https://www.tvarenasport.com/files/img/icons/chanel-04.png">Arena Sport 4 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport5.rs" site_id="05" logo="https://www.tvarenasport.com/files/img/icons/chanel-05.png">Arena Sport 5 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport6.rs" site_id="06" logo="https://www.tvarenasport.com/files/img/icons/chanel-06.png">Arena Sport 6 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport7.rs" site_id="07" logo="https://www.tvarenasport.com/files/img/icons/chanel-07.png">Arena Sport 7 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport8.rs" site_id="08" logo="https://www.tvarenasport.com/files/img/icons/chanel-08.png">Arena Sport 8 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport9.rs" site_id="09" logo="https://www.tvarenasport.com/files/img/icons/chanel-09.png">Arena Sport 9 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport10.rs" site_id="10" logo="https://www.tvarenasport.com/files/img/icons/chanel-10.png">Arena Sport 10 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSport1x2.rs" site_id="1x2" logo="https://www.tvarenasport.com/files/img/icons/chanel-1x2.png">Arena Sport 1x2 Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSportAdrenalin.rs" site_id="a-adrenalin" logo="https://www.tvarenasport.com/files/img/icons/chanel-a-adrenalin.png">Arena Sport Adrenalin Serbia</channel>
<channel site="tvarenasport.com" lang="sr" xmltv_id="ArenaSportTenis.rs" site_id="a-tenis" logo="https://www.tvarenasport.com/files/img/icons/chanel-a-tenis.png">Arena Sport Tenis Serbia</channel>
</channels>

View File

@@ -9,9 +9,12 @@ dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
const CHANNEL_LOGO_REGEX = /chanel-([\w-]+?)\.png/
const TIMEZONE = 'Europe/Belgrade'
module.exports = {
site: 'tvarenasport.com',
tz: 'Europe/Belgrade',
tz: TIMEZONE,
lang: 'sr',
days: 2,
request: {
@@ -23,110 +26,77 @@ module.exports = {
parser({ content, channel, date }) {
const programs = []
const expectedDate = date.format('YYYY-MM-DD')
if (content) {
const dates = []
const $ = cheerio.load(content)
const parent = $(
`.tv-scheme-chanel-header img[src*="chanel-${channel.site_id}.png"]`
).parents('div')
parent
.siblings('.tv-scheme-days')
.find('a')
.toArray()
.forEach(el => {
const a = $(el)
const dt = a.find('span:nth-child(3)').text()
dates.push(dayjs(dt + date.year(), 'DD.MM.YYYY'))
})
parent
.siblings('.tv-scheme-new-slider-wrapper')
.find('.tv-scheme-new-slider-item')
.toArray()
.forEach((el, i) => {
programs.push(...parseSchedules($(el), dates[i], module.exports.tz))
})
programs.forEach((s, i) => {
if (i < programs.length - 2) {
s.stop = programs[i + 1].start
} else {
s.stop = s.start.startOf('d').add(1, 'd')
}
const $ = cheerio.load(content)
$('.tv-scheme-chanel').each((_, el) => {
const $ch = $(el)
const logo = $ch.find('.tv-scheme-chanel-header img').attr('src') || ''
const m = logo.match(CHANNEL_LOGO_REGEX)
if (!m || m[1] !== channel.site_id) return
const dates = $ch.find('.tv-scheme-days a').map((i, d) => {
const t = $(d).find('span:nth-child(3)').text().trim()
return dayjs(`${t}${date.year()}`, 'DD.MM.YYYY')
}).get()
const startIdx = dates.findIndex(d => d.format('YYYY-MM-DD') === expectedDate)
if (startIdx === -1) return
const sliders = $ch.find('.tv-scheme-new-slider-item')
const slider = sliders.eq(startIdx)
if (!slider.length) return
let entries = parseSchedules($, slider, dates[startIdx])
entries.forEach((e, i) => {
const nxt = entries[i + 1]
e.stop = nxt
? nxt.start
: dayjs.tz(`${expectedDate} 23:59`, 'YYYY-MM-DD HH:mm', TIMEZONE)
})
}
return programs.filter(
p =>
p.start.format('YYYY-MM-DD') === expectedDate ||
p.stop.format('YYYY-MM-DD') === expectedDate
)
},
async channels() {
const channels = []
const data = await axios
.get(this.url)
.then(r => r.data)
.catch(console.error)
if (data) {
// channel naming rule
const names = id => {
let match = id.match(/^\d+$/)
if (match) {
return `Arena Sport ${parseInt(id)}`
}
match = id.match(/^\d/)
if (match) {
return `Arena Sport ${id}`
}
match = id.match(/^a(\d+)(p)?/)
if (match) {
return `Arena ${parseInt(match[1])}${match[2] === 'p' ? ' Premium' : ''}`
}
return `Arena ${id}`
}
const $ = cheerio.load(data)
const items = $('.tv-scheme-chanel-header img').toArray()
for (const item of items) {
const [, id] = $(item)
.attr('src')
.match(/chanel-([a-z0-9]+)\.png/) || [null, null]
if (id) {
channels.push({
lang: this.lang,
site_id: id,
name: names(id)
})
}
}
}
return channels
}
}
function parseSchedules($s, date, tz) {
const schedules = []
const $ = $s._make
$s.find('.slider-content')
.toArray()
.forEach(el => {
schedules.push(parseSchedule($(el), date, tz))
programs.push(...entries)
})
return programs
},
return schedules
}
function parseSchedule($s, date, tz) {
const time = $s.find('.slider-content-top span').text()
const start = dayjs.tz(`${date.format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm', tz)
const category = $s.find('.slider-content-middle span').text()
const title = $s.find('.slider-content-bottom p').text()
const description = $s.find('.slider-content-bottom span:first').text()
return {
title: description ? description : title,
description: description ? title : description,
category,
start
async channels() {
const data = await axios.get(this.url).then(r => r.data).catch(console.error)
if (!data) return []
const $ = cheerio.load(data)
return $('.tv-scheme-chanel-header img')
.map((_, img) => {
const src = $(img).attr('src') || ''
const m = src.match(CHANNEL_LOGO_REGEX)
if (!m) return null
const id = m[1]
const displayName = getDisplayName(id)
const xmltvId = displayName.replaceAll(' ', '').replace(/Serbia$/, '.rs')
const logourl = `https://www.${this.site}${src}`
return { site_id: id, lang: this.lang, xmltv_id: xmltvId, name: displayName, logo: logourl }
})
.get()
}
}
function getDisplayName(id) {
const template = name => `Arena Sport ${name} Serbia`
let m
if ((m = /^0*(\d+)$/.exec(id))) return template(m[1])
if ((m = /^a+(\d+)p$/.exec(id))) return template(`${m[1]} Premium`)
const formattedId = id.replace(/^a-/, '').replace(/^./, c => c.toUpperCase())
return template(formattedId)
}
function parseSchedules($, $slider, date) {
return $slider
.find('.slider-content')
.map((_, el) => parseSchedule($(el), date))
.get()
}
function parseSchedule($s, date) {
const time = $s.find('.slider-content-top span').text().trim()
const start = dayjs.tz(`${date.format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm', TIMEZONE)
const sport = $s.find('.slider-content-middle span').text().trim()
const titleText = $s.find('.slider-content-bottom p').text().trim()
const league = $s.find('.slider-content-bottom span')
.not('.live-title, .blob-text, .blob-border, .blob').first().text().trim()
const isLive = $s.find('.blob-text').text().trim().toLowerCase() === 'uživo'
const title = (isLive ? '(Uživo) ' : '') + (league ? `${league}: ${titleText}` : titleText)
return { title, category: sport, start }
}

View File

@@ -8,7 +8,7 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
dayjs.extend(utc)
const date = dayjs.utc('2024-12-07', 'YYYY-MM-DD').startOf('d')
const date = dayjs.utc('2025-07-30', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: 'a1p',
xmltv_id: 'ArenaSport1Premium.rs'
@@ -20,24 +20,23 @@ it('can generate valid url', () => {
it('can parse response', () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content.html'))
const result = parser({ channel, date, content }).map(p => {
const result = parser({ content, channel, date }).map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})
expect(result.length).toBe(19)
expect(result.length).toBe(13)
expect(result[4]).toMatchObject({
start: '2024-12-07T03:30:00.000Z',
stop: '2024-12-07T05:00:00.000Z',
title: 'EVROPSKO PRVENSTVO Ž',
description: 'Francuska - Crna Gora',
category: 'Rukomet'
start: '2025-07-30T08:00:00.000Z',
stop: '2025-07-30T09:00:00.000Z',
title: 'UEFA LIGA ŠAMPIONA: Liga Šampiona: Pregled sezone',
category: 'Fudbal'
})
expect(result[8]).toMatchObject({
start: '2024-12-07T11:00:00.000Z',
stop: '2024-12-07T11:05:00.000Z',
title: 'Arena News'
expect(result[6]).toMatchObject({
start: '2025-07-30T11:00:00.000Z',
stop: '2025-07-30T13:00:00.000Z',
title: '(Uživo) PRIJATELJSKE UTAKMICE: K League - Newcastle Utd'
})
})

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
{"data":{"duration":"240","providerId":"9100001138","startTime":"1736640000","items":[{"channel":{"fullName":"CBS National Schedule","name":"CBS","number":null,"sourceId":9200018514,"legacySourceId":null,"networkName":"CBS","networkId":1,"logo":"/provider/8/4/8-9200018514.png"},"programSchedules":[{"airingAttrib":524304,"catId":5,"startTime":1736643600,"endTime":1736647200,"programId":9000351140,"title":"FBI: International","rating":null,"programDetails":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000351140/web"},{"airingAttrib":524304,"catId":5,"startTime":1736647200,"endTime":1736650800,"programId":9000317198,"title":"FBI: Most Wanted","rating":null,"programDetails":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000317198/web"},{"airingAttrib":524308,"catId":5,"startTime":1736650800,"endTime":1736654400,"programId":9000415495,"title":"48 Hours","rating":null,"programDetails":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000415495/web"}]}]},"links":{"self":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736640000&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"},"prev":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736625600&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"},"next":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736654400&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"}},"meta":{"componentName":null,"componentDisplayName":null,"componentType":null}}

View File

@@ -1 +0,0 @@
{"data":{"duration":"240","providerId":"9100001138","startTime":"1736654400","items":[{"channel":{"fullName":"CBS National Schedule","name":"CBS","number":null,"sourceId":9200018514,"legacySourceId":null,"networkName":"CBS","networkId":1,"logo":"/provider/8/4/8-9200018514.png"},"programSchedules":[{"airingAttrib":524288,"catId":5,"startTime":1736654400,"endTime":1736661600,"programId":9000000408,"title":"Local Programs","rating":null,"programDetails":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000000408/web"},{"airingAttrib":524288,"catId":5,"startTime":1736661600,"endTime":1736668800,"programId":9000000408,"title":"Local Programs","rating":null,"programDetails":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000000408/web"}]}]},"links":{"self":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736654400&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"},"prev":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736640000&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"},"next":{"href":"https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736668800&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc"}},"meta":{"componentName":null,"componentDisplayName":null,"componentType":null}}

View File

@@ -0,0 +1,78 @@
{
"data": {
"item": {
"id": 9000058285,
"name": "Secrets of the Zoo: North Carolina",
"isSportsEvent": false,
"tvRating": "TV-14",
"categoryId": 5,
"subCategoryId": 0,
"episodeNumber": 1,
"mcoId": 1000990897,
"title": "Secrets of the Zoo: North Carolina",
"type": "show",
"slug": "secrets-of-the-zoo-north-carolina",
"typeId": 1,
"images": [
{
"id": "2-e5b17322185dd95f066a2de47efd8a12",
"provider": "2",
"imageType": {
"typeId": 1,
"typeName": "showcard",
"providerTypeName": "showcard"
},
"bucketType": "catalog",
"bucketPath": "/provider/2/13/2-e5b17322185dd95f066a2de47efd8a12.jpg",
"filename": "",
"width": 3840,
"height": 2160
},
{
"id": "2-59b2fd193bc035d4f2d4d3f2a68629d3",
"provider": "2",
"imageType": {
"typeId": 2,
"typeName": "poster art",
"providerTypeName": "poster art"
},
"bucketType": "catalog",
"bucketPath": "/provider/2/2/2-59b2fd193bc035d4f2d4d3f2a68629d3.jpg",
"filename": "",
"width": 2000,
"height": 3000
}
],
"genres": [
{
"id": 14,
"name": "Reality",
"genres": [
"Reality-TV"
]
}
],
"metacriticSummary": null,
"video": null,
"parentId": 1000990897,
"description": "Chimps living at the North Carolina Zoo, a zoo located in the center of North Carolina that serves as the world's largest natural habitat zoo, as well as one of two state-supported zoos, are cared for",
"rating": null,
"episodeTitle": "Chimp Off the Old Block",
"releaseYear": 2020,
"seoUrl": null,
"episodeAirDate": "/Date(1604102400000)/",
"seasonNumber": 1,
"duration": null
}
},
"links": {
"self": {
"href": "https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000058285/web"
}
},
"meta": {
"componentName": null,
"componentDisplayName": null,
"componentType": null
}
}

View File

@@ -1 +0,0 @@
{"data":{"item":{"id":9000351140,"name":"FBI: International","isSportsEvent":false,"tvRating":"TV-14","categoryId":5,"subCategoryId":0,"episodeNumber":12,"mcoId":1060026058,"title":"FBI: International","type":"show","slug":"fbi-international","typeId":1,"images":[{"id":"2-da3822c4eec5e6100c9b6ff2ac667213","provider":"2","imageType":{"typeId":1,"typeName":"showcard","providerTypeName":"showcard"},"bucketType":"catalog","bucketPath":"/provider/2/13/2-da3822c4eec5e6100c9b6ff2ac667213.jpg","filename":"","width":3840,"height":2160},{"id":"2-d7bbccddf55702be0028e4c7b37d91d2","provider":"2","imageType":{"typeId":2,"typeName":"poster art","providerTypeName":"poster art"},"bucketType":"catalog","bucketPath":"/provider/2/2/2-d7bbccddf55702be0028e4c7b37d91d2.jpg","filename":"","width":1400,"height":2100}],"genres":[{"id":3,"name":"Action & Adventure","genres":["Action","Adventure"]},{"id":5,"name":"Suspense","genres":["Crime","Mystery","Thriller"]},{"id":1,"name":"Drama","genres":["Drama"]}],"metacriticSummary":null,"video":null,"parentId":1060026058,"description":"The owner of a prominent cyber security company is murdered in Copenhagen just before a massive data leak surfaces online, leading the NSA to ask the team for assistance in catching the killer and leaker before more data is revealed.","rating":"L","episodeTitle":"Gift","releaseYear":2024,"seoUrl":null,"episodeAirDate":"/Date(1715644800000)/","seasonNumber":3,"duration":null}},"links":{"self":{"href":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000351140/web"}},"meta":{"componentName":null,"componentDisplayName":null,"componentType":null}}

View File

@@ -1 +0,0 @@
{"data":{"item":{"id":9000000408,"name":"Local Programs","isSportsEvent":false,"tvRating":"TV-14","categoryId":5,"subCategoryId":0,"episodeNumber":null,"mcoId":null,"title":null,"type":null,"slug":null,"typeId":null,"images":[],"genres":[],"metacriticSummary":null,"video":null,"parentId":null,"description":"Local programming information.","rating":"L","episodeTitle":"Local Programs","releaseYear":null,"seoUrl":null,"episodeAirDate":null,"seasonNumber":null,"duration":null}},"links":{"self":{"href":"https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000000408/web"}},"meta":{"componentName":null,"componentDisplayName":null,"componentType":null}}

View File

@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="tvguide.com" lang="en" xmltv_id="" site_id="9200009636">Great American Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="" site_id="9233001847">MyNetworkTV National</channel>
<channel site="tvguide.com" lang="en" xmltv_id="" site_id="9233010939">Hallmark Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="5StarMax.us@East" site_id="9233011931">5StarMax</channel>
<channel site="tvguide.com" lang="en" xmltv_id="ABC.us@East" site_id="9233011874">ABC Network Feed</channel>
<channel site="tvguide.com" lang="en" xmltv_id="ACCNetwork.us" site_id="9200017734">ACC Network</channel>
@@ -45,11 +42,11 @@
<channel site="tvguide.com" lang="en" xmltv_id="FanDuelTV.us" site_id="9200012412">FanDuel TV</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Flix.us@East" site_id="9233000217">Flix</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoodNetwork.us@East" site_id="9233009448">Food Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxBusinessNetwork.us" site_id="9200009124">Fox Business Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Fox.us@East" site_id="9233002271">FOX</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxBusinessNetwork.us" site_id="9200009124">Fox Business Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxNewsChannel.us" site_id="9233000410">Fox News</channel>
<channel site="tvguide.com" lang="en" xmltv_id="" site_id="9233008440">FOX Sports 1</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxSports2LatinAmerica.us" site_id="9200009884">FOX Sports 2</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxSports1.us" site_id="9233008440">FOX Sports 1</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FoxSports2.us" site_id="9200009884">FOX Sports 2</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Freeform.us@East" site_id="9200006942">Freeform</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Fuse.us@East" site_id="9233011488">Fuse HD</channel>
<channel site="tvguide.com" lang="en" xmltv_id="FX.us@East" site_id="9200006932">FX</channel>
@@ -58,11 +55,13 @@
<channel site="tvguide.com" lang="en" xmltv_id="FYI.us@East" site_id="9200020460">FYI</channel>
<channel site="tvguide.com" lang="en" xmltv_id="GameShowNetwork.us@East" site_id="9200019858">Game Show Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="GolfChannel.us" site_id="9233005443">Golf</channel>
<channel site="tvguide.com" lang="en" xmltv_id="GreatAmericanFamily.us" site_id="9200009636">Great American Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="9200016034">Hallmark</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HallmarkFamily.us" site_id="9233010939">Hallmark Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HallmarkMoviesMysteries.us@East" site_id="9233013351">Hallmark Mystery</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBO2.us@East" site_id="9233003524">HBO 2</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBOComedy.us@East" site_id="9200006981">HBO Comedy</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBO.us@East" site_id="9200004886">HBO</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBOComedy.us@East" site_id="9200006981">HBO Comedy</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBOFamily.us@East" site_id="9200004595">HBO Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBOSignature.us@East" site_id="9233008160">HBO Signature</channel>
<channel site="tvguide.com" lang="en" xmltv_id="HBOZone.us@East" site_id="9233009866">HBO Zone</channel>
@@ -87,11 +86,12 @@
<channel site="tvguide.com" lang="en" xmltv_id="MSNBC.us" site_id="9233006803">MSNBC</channel>
<channel site="tvguide.com" lang="en" xmltv_id="MTV2.us@East" site_id="9200000872">MTV2</channel>
<channel site="tvguide.com" lang="en" xmltv_id="MTV.us@East" site_id="9200014754">MTV</channel>
<channel site="tvguide.com" lang="en" xmltv_id="MNT.us" site_id="9233001847">MyNetworkTV National</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NationalGeographic.us@East" site_id="9233002310">National Geographic</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NationalGeographicWild.us@East" site_id="9200004683">National Geographic Wild</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NBATV.us" site_id="9200000070">NBA TV</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NBC.us@East" site_id="9233009876">NBC National</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NewsNationEast.us" site_id="9233013251">NewsNation</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NewsNation.us" site_id="9233013251">NewsNation</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NFLNetwork.us" site_id="9200004330">NFL Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="NHLNetwork.us" site_id="9233009455">NHL Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Nickelodeon.us@East" site_id="9200006939">Nickelodeon</channel>
@@ -117,14 +117,14 @@
<channel site="tvguide.com" lang="en" xmltv_id="ShowtimeWomen.us@East" site_id="9200002975">SHOWTIME WOMEN</channel>
<channel site="tvguide.com" lang="en" xmltv_id="ShoxBet.us@East" site_id="9233017018">SHOxBET</channel>
<channel site="tvguide.com" lang="en" xmltv_id="SmithsonianChannel.us@East" site_id="9233002112">Smithsonian</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Starz.us@East" site_id="9233013809">STARZ</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzCinema.us@East" site_id="9233008357">STARZ Cinema</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzComedy.us@East" site_id="9233003558">STARZ Comedy</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Starz.us@East" site_id="9233013809">STARZ</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEdge.us@East" site_id="9233011247">STARZ Edge</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncore.us@East" site_id="9200009649">STARZ ENCORE</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreAction.us@East" site_id="9233005667">STARZ ENCORE Action</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreBlack.us@East" site_id="9200001097">STARZ ENCORE Black</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreClassic.us@East" site_id="9200003144">STARZ ENCORE Classic</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncore.us@East" site_id="9200009649">STARZ ENCORE</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreFamily.us@East" site_id="9200011867">STARZ ENCORE Family</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreSuspense.us@East" site_id="9200011866">STARZ ENCORE Suspense</channel>
<channel site="tvguide.com" lang="en" xmltv_id="StarzEncoreWesterns.us@East" site_id="9233008131">STARZ ENCORE Westerns</channel>
@@ -147,7 +147,7 @@
<channel site="tvguide.com" lang="en" xmltv_id="TravelChannel.us@East" site_id="9233000035">Travel</channel>
<channel site="tvguide.com" lang="en" xmltv_id="truTV.us@East" site_id="9200009547">truTV</channel>
<channel site="tvguide.com" lang="en" xmltv_id="TVLand.us@East" site_id="9233005468">TV Land</channel>
<channel site="tvguide.com" lang="en" xmltv_id="UniversalKids.us@East" site_id="9233003660">Universal Kids</channel>
<channel site="tvguide.com" lang="en" xmltv_id="UniversalKids.us@East" site_id="9233003660">Universal Kids (Off-Air)</channel>
<channel site="tvguide.com" lang="en" xmltv_id="USANetwork.us@East" site_id="9233004106">USA</channel>
<channel site="tvguide.com" lang="en" xmltv_id="VH1.us@East" site_id="9233000037">VH1</channel>
<channel site="tvguide.com" lang="en" xmltv_id="VICETV.us" site_id="9233002242">VICE</channel>

View File

@@ -2,22 +2,46 @@ const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const doFetch = require('@ntlab/sfetch')
const debug = require('debug')('site:tvguide.com')
dayjs.extend(utc)
dayjs.extend(timezone)
doFetch.setDebugger(debug).setCheckResult(false)
const providerId = '9100001138'
const maxDuration = 240
const segments = 1440 / maxDuration
const headers = {
'referer': 'https://www.tvguide.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
}
const east_channels = [
'5StarMax', 'ABC Network Feed', 'ActionMax', 'A&E', 'AMC', 'Animal Planet', 'BBC America',
'BET', 'BET Her', 'Bravo', 'Cartoon Network', 'CBS National', 'Cinemax', 'CMT', 'Comedy Central',
'Discovery', 'Disney', 'Disney Junior', 'Disney XD', 'E!', 'Flix', 'Food Network', 'FOX', 'Freeform',
'Fuse HD', 'FX', 'FXX', 'FYI', 'Game Show Network', 'Hallmark', 'Hallmark Mystery', 'HBO 2',
'HBO Comedy', 'HBO', 'HBO Family', 'HBO Signature', 'HBO Zone', 'HGTV', 'History', 'IFC',
'Investigation Discovery', 'ION', 'Lifetime', 'LMN', 'LOGO', 'MAGNOLIA Network', 'MGM+ Hits HD',
'MoreMax', 'MovieMax', 'MTV2', 'MTV', 'National Geographic', 'National Geographic Wild', 'NBC National',
'Nickelodeon', 'Nick Jr.', 'Nicktoons', 'OuterMax', 'OWN', 'Oxygen', 'Paramount Network', 'PBS HD',
'Pop Network', 'SHOWTIME 2', 'Paramount+ with Showtime', 'SHOWTIME EXTREME', 'SHOWTIME FAMILY ZONE',
'SHOWTIME NEXT', 'SHOWTIME SHOWCASE', 'SHOWTIME WOMEN', 'SHOxBET', 'Smithsonian', 'STARZ Cinema',
'STARZ Comedy', 'STARZ', 'STARZ Edge', 'STARZ ENCORE Action', 'STARZ ENCORE Black',
'STARZ ENCORE Classic', 'STARZ ENCORE', 'STARZ ENCORE Family', 'STARZ ENCORE Suspense',
'STARZ ENCORE Westerns', 'STARZ InBlack', 'STARZ Kids & Family', 'Sundance TV', 'Syfy', 'tbs',
'Turner Classic Movies', 'TeenNick', 'Telemundo', 'The Movie', 'The Movie Xtra', 'ThrillerMax', 'TLC',
'TNT', 'Travel', 'truTV', 'TV Land', 'Universal Kids', 'USA', 'VH1', 'WE tv', 'Univision'
]
module.exports = {
site: 'tvguide.com',
days: 2,
request: {
headers: function () {
return headers
},
responseType: 'application/json',
decompress: true,
cache: {
ttl: 24 * 60 * 60 * 1000 // 1 day
}
@@ -40,7 +64,7 @@ module.exports = {
`https://backend.tvguide.com/tvschedules/tvguide/${providerId}/web?${params.join('&')}` :
`https://backend.tvguide.com/tvschedules/tvguide/serviceprovider/${providerId}/sources/web?${params.join('&')}`
},
async parser({ content, date, channel }) {
async parser({ content, date, channel, fetchSegments = true }) {
const programs = []
const f = data => {
const result = []
@@ -60,55 +84,69 @@ module.exports = {
return result
}
const queues = f(content)
if (queues.length) {
const parts = []
for (let i = 2; i <= segments; i++) {
parts.push(await module.exports.url({ date, segment: i }))
if (queues.length && fetchSegments) {
for (let segment = 2; segment <= segments; segment++) {
const segmentUrl = await module.exports.url({ date, segment })
debug(`fetch segment ${segment}: ${segmentUrl}`)
try {
const res = await axios.get(segmentUrl, { headers })
queues.push(...f(res.data))
} catch (err) {
debug(`Failed to fetch segment ${segment}: ${err.message}`)
}
}
await doFetch(parts, (url, res) => {
queues.push(...f(res))
})
await doFetch(queues, (queue, res) => {
const item = res?.data?.item ? res.data.item : queue.i
}
for (const queue of queues) {
try {
const res = await axios.get(queue.url, { headers })
const item = res.data?.data?.item || queue.i
programs.push({
title: item.title ? item.title : queue.i.title,
title: item.title || queue.i.title,
sub_title: item.episodeNumber ? item.episodeTitle : null,
description: item.description,
season: item.seasonNumber,
episode: item.episodeNumber,
rating: item.rating ? { system: 'MPA', value: item.rating } : null,
categories: Array.isArray(item.genres) ? item.genres.map(g => g.name) : null,
start: dayjs.unix(item.startTime ? item.startTime : queue.i.startTime),
stop: dayjs.unix(item.endTime ? item.endTime : queue.i.endTime)
start: dayjs.unix(item.startTime || queue.i.startTime),
stop: dayjs.unix(item.endTime || queue.i.endTime),
})
})
} catch (err) {
debug(`Failed to fetch program details ${queue.url}: ${err.message}`)
}
}
return programs
},
async channels() {
const channels = []
const data = await axios
.get(await this.url({}))
.then(r => r.data)
.catch(console.error)
data.data.items.forEach(item => {
channels.push({
lang: 'en',
site_id: item.sourceId,
name: item.fullName.replace(/Channel|Schedule/g, '').trim()
try {
const data = await axios
.get(await this.url({}), { headers })
.then(r => r.data)
data.data.items.forEach(item => {
const finalName = item.fullName.replace(/Channel|Schedule/g, '').trim()
const isEast = east_channels.some(name => name.toLowerCase().includes(finalName.toLowerCase()))
channels.push({
lang: 'en',
site_id: item.sourceId,
xmltv_id: finalName.replaceAll(/[ '&]/g, '') + '.us' + (isEast ? '@East' : ''),
name: finalName
})
})
})
} catch (err) {
console.error('Failed to fetch channels:', err.message)
}
return channels
},
async fetchApiKey() {
const data = await axios
.get('https://www.tvguide.com/listings/')
.then(r => r.data)
.catch(console.error)
return data ? data.match(/apiKey=([a-zA-Z0-9]+)&/)[1] : null
try {
const data = await axios
.get('https://www.tvguide.com/listings/')
.then(r => r.data)
return data ? data.match(/apiKey=([a-zA-Z0-9]+)&/)[1] : null
} catch (err) {
console.error('Failed to fetch API key:', err.message)
return null
}
}
}
}

View File

@@ -5,83 +5,66 @@ const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
dayjs.extend(utc)
jest.mock('axios')
const date = dayjs.utc('2025-01-12', 'YYYY-MM-DD').startOf('d')
const date = dayjs.utc('2025-07-29', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: '9200018514',
xmltv_id: 'CBSEast.us'
site_id: '9200004683',
xmltv_id: 'NationalGeographicWild.us@East'
}
axios.get.mockImplementation(url => {
const result = {}
const urls = {
'https://www.tvguide.com/listings/':
'content.html',
'https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736640000&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc':
'content1.json',
'https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736654400&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc':
'content2.json',
'https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000351140/web':
'program1.json',
'https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000000408/web':
'program2.json',
}
if (urls[url] !== undefined) {
result.data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString()
if (!urls[url].startsWith('content1') && !urls[url].endsWith('.html')) {
result.data = JSON.parse(result.data)
}
}
return Promise.resolve(result)
})
it('can generate valid url', async () => {
expect(await url({ date })).toBe(
'https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736640000&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc'
axios.get.mockImplementation(url => {
if (url === 'https://www.tvguide.com/listings/') {
return Promise.resolve({
data: fs.readFileSync(path.join(__dirname, '__data__', 'content.html'), 'utf8')
})
}
throw new Error(`Unexpected URL: ${url}`)
})
const result = await url({ date })
expect(result).toBe(
'https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1753747200&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc'
)
})
it('can parse response', async () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content1.json')).toString()
const results = (await parser({ content, channel, date })).map(p => {
const content = JSON.parse(fs.readFileSync(path.join(__dirname, '__data__', 'content.json'), 'utf-8'))
axios.get.mockImplementation(url => {
if (
url ===
'https://backend.tvguide.com/tvschedules/tvguide/programdetails/9000058285/web'
) {
return Promise.resolve({
data: JSON.parse(fs.readFileSync(path.join(__dirname, '__data__', 'program.json')))
})
} else {
return Promise.resolve({ data: '' })
}
})
let results = await parser({ content, date, channel, fetchSegments: false })
results = results.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})
expect(results.length).toBe(5)
expect(results[0]).toMatchObject({
start: '2025-01-12T01:00:00.000Z',
stop: '2025-01-12T02:00:00.000Z',
title: 'FBI: International',
sub_title: 'Gift',
start: '2025-07-29T00:00:00.000Z',
stop: '2025-07-29T01:00:00.000Z',
title: 'Secrets of the Zoo: North Carolina',
sub_title: 'Chimp Off the Old Block',
description:
'The owner of a prominent cyber security company is murdered in Copenhagen just before a massive data leak surfaces online, leading the NSA to ask the team for assistance in catching the killer and leaker before more data is revealed.',
categories: ['Action & Adventure', 'Suspense', 'Drama'],
season: 3,
episode: 12,
rating: {
system: 'MPA',
value: 'L'
}
})
expect(results[4]).toMatchObject({
start: '2025-01-12T06:00:00.000Z',
stop: '2025-01-12T08:00:00.000Z',
title: 'Local Programs',
description:
'Local programming information.',
categories: [],
rating: {
system: 'MPA',
value: 'L'
}
'Chimps living at the North Carolina Zoo, a zoo located in the center of North Carolina that serves as the world\'s largest natural habitat zoo, as well as one of two state-supported zoos, are cared for',
categories: ['Reality'],
season: 1,
episode: 1,
})
})
@@ -89,7 +72,7 @@ it('can handle empty guide', async () => {
const results = await parser({
date,
channel,
content: fs.readFileSync(path.join(__dirname, '__data__', 'no-content.json')).toString()
content: fs.readFileSync(path.join(__dirname, '__data__', 'no-content.json'))
})
expect(results).toMatchObject([])
})

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -12,22 +12,28 @@ module.exports = {
},
request: {
headers: {
'x-requested-with': 'XMLHttpRequest'
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
'referer': 'https://tvprofil.com/tvprogram/',
'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01'
}
},
parser: function ({ content }) {
let programs = []
const items = parseItems(content)
items.forEach(item => {
const $item = cheerio.load(item)
const title = parseTitle($item)
const category = parseCategory($item)
const start = parseStart($item)
const duration = parseDuration($item)
const stop = start.add(duration, 's')
const image = parseImage($item)
const $ = cheerio.load(item)
$('div.row').each((_, el) => {
const $item = $(el)
const title = parseTitle($item)
const category = parseCategory($item)
const start = parseStart($item)
const duration = parseDuration($item)
const stop = start.add(duration, 's')
const icon = parseImage($item)
programs.push({ title, category, start, stop, image })
programs.push({ title, category, start, stop, icon })
})
})
return programs
@@ -45,7 +51,7 @@ module.exports = {
de: { channelsPath: '/de', progsPath: 'de/tvprogramm', lang: 'de' },
es: { channelsPath: '/es', progsPath: 'es/programacion-tv', lang: 'es' },
fr: { channelsPath: '/fr', progsPath: 'fr/programme-tv', lang: 'fr' },
hr: { channelsPath: '', progsPath: 'tvprogram', lang: 'hr' },
hr: { channelsPath: '', progsPath: 'tvprogram', lang: 'hr' },
hu: { channelsPath: '/hu', progsPath: 'hu/tvmusor', lang: 'hu' },
ie: { channelsPath: '/ie', progsPath: 'ie/tvschedule', lang: 'en' },
it: { channelsPath: '/it', progsPath: 'it/guida-tv', lang: 'it' },
@@ -74,6 +80,12 @@ module.exports = {
.get(url, {
params: {
callback: 'cb'
},
headers: {
'x-requested-with': 'XMLHttpRequest',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
'referer': 'https://tvprofil.com/programtv/',
'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01',
}
})
.then(r => r.data)
@@ -91,6 +103,7 @@ module.exports = {
channels.push({
lang,
site_id: `${config.progsPath}#${item.urlID}`,
xmltv_id: `${item.title.replaceAll(/[ '&]/g, '')}.${country}`,
name: item.title
})
})
@@ -102,64 +115,73 @@ module.exports = {
}
function parseImage($item) {
return $item(':root').data('image')
return $item.attr('data-image') || null
}
function parseDuration($item) {
return $item(':root').data('len')
return parseInt($item.attr('data-len'))
}
function parseStart($item) {
const timestamp = $item(':root').data('ts')
const timestamp = parseInt($item.attr('data-ts'))
return dayjs.unix(timestamp)
}
function parseCategory($item) {
return $item('.col:nth-child(2) > small').text() || null
return $item.find('.col:nth-child(2) > small').text() || null
}
function parseTitle($item) {
let title = $item('.col:nth-child(2) > a').text()
title += $item('.col:nth-child(2)').clone().children().remove().end().text()
let title = $item.find('.col:nth-child(2) > a').text()
title += $item.find('.col:nth-child(2)').clone().children().remove().end().text()
return title.replace('®', '').trim().replace(/,$/, '')
}
function parseItems(content) {
let data = (content.match(/cb\((.*)\)/) || [null, null])[1]
let data = (content.match(/^[^(]+\(([\s\S]*)\)$/) || [null, null])[1]
if (!data) return []
let json = JSON.parse(data)
if (!json || !json.data || !json.data.program) return []
const $ = cheerio.load(json.data.program)
return $('.row').toArray()
return [json.data.program]
}
function buildQuery(site_id, date) {
const query = {
datum: date.format('YYYY-MM-DD'),
kanal: site_id,
callback: 'cb'
kanal: site_id
// callback: 'cb' // possibly still working
}
let c = 4
const a = query.datum + query.kanal + c
const ua = query.kanal + query.datum
let a = query.datum + query.kanal + c
let ua = query.kanal + query.datum
let i = a.length,
b = 2
if (
typeof ua === 'undefined' ||
ua === null ||
ua === '' ||
ua === 0 ||
ua === '0' ||
ua !== ua
) {
ua = 'none'
}
for (let j = 0; j < ua.length; j++) c += ua.charCodeAt(j)
let i = a.length
let b = 2
while (i--) {
b += (a.charCodeAt(i) + c * 2) * i
}
b = b.toString()
const key = 'b' + b.charCodeAt(b.length - 1)
const lastCharCode = b.charCodeAt(b.length - 1)
const key = 'b' + lastCharCode
query['callback'] = `tvprogramit${lastCharCode}`
query[key] = b
return new URLSearchParams(query).toString()
}
}

View File

@@ -7,7 +7,7 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
dayjs.extend(utc)
const date = dayjs.utc('2025-01-19', 'YYYY-MM-DD').startOf('d')
const date = dayjs.utc('2025-07-29', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: 'bg/tv-programa#24kitchen-bg',
xmltv_id: '24KitchenBulgaria.bg'
@@ -15,13 +15,14 @@ const channel = {
it('can generate valid url', () => {
expect(url({ channel, date })).toBe(
'https://tvprofil.com/bg/tv-programa/program/?datum=2025-01-19&kanal=24kitchen-bg&callback=cb&b52=824084'
'https://tvprofil.com/bg/tv-programa/program/?datum=2025-07-29&kanal=24kitchen-bg&callback=tvprogramit48&b48=827670'
)
})
it('can generate valid request headers', () => {
expect(request.headers).toMatchObject({
'x-requested-with': 'XMLHttpRequest'
'x-requested-with': 'XMLHttpRequest',
'referer': 'https://tvprofil.com/tvprogram/',
})
})
@@ -34,9 +35,9 @@ it('can parse response', () => {
})
expect(results[0]).toMatchObject({
title: 'Мексиканска кухня с Пати 10, еп. 9',
start: '2023-01-12T04:00:00.000Z',
stop: '2023-01-12T04:30:00.000Z'
title: 'Save with Jamie 1, ep. 2',
start: '2025-07-29T05:00:00.000Z',
stop: '2025-07-29T06:00:00.000Z'
})
})

View File

@@ -281,7 +281,7 @@
<channel site="tvtv.us" lang="en" xmltv_id="GODTV.uk" site_id="52697">GodTV</channel>
<channel site="tvtv.us" lang="en" xmltv_id="GolfChannel.us" site_id="61854">Golf Channel</channel>
<channel site="tvtv.us" lang="en" xmltv_id="GolTVUSA.us" site_id="32161">Gol TV</channel>
<channel site="tvtv.us" lang="en" xmltv_id="GreatAmericanCountry.us" site_id="16062">Great American Country</channel>
<channel site="tvtv.us" lang="en" xmltv_id="GreatAmericanFamily.us" site_id="16062">Great American Family</channel>
<channel site="tvtv.us" lang="en" xmltv_id="Grit.us" site_id="89922">Grit</channel>
<channel site="tvtv.us" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="11221">Hallmark Channel East</channel>
<channel site="tvtv.us" lang="en" xmltv_id="HallmarkChannel.us@West" site_id="19933">Hallmark Channel West</channel>