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
+2 -2
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#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="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="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="GreatAmericanFamily.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#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="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#312">Hallmark</channel>
<channel site="directv.com" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="312#3771">Hallmark Channel HD</channel> <channel site="directv.com" lang="en" xmltv_id="HallmarkChannel.us@East" site_id="312#3771">Hallmark Channel HD</channel>
File diff suppressed because it is too large Load Diff
@@ -1,98 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<channels> <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="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="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="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="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="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="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="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="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#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="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="History.it@HD" site_id="DTH#9101">History</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@Plus1" site_id="DTH#123">History +1</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="it" xmltv_id="HorseTV.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="InterTV.it" site_id="DTH#9893">Inter TV</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="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="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="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" 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="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="MediasetExtra.it@HD" site_id="DTH#10465">Mediaset Extra 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="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="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#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="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="NHKWorldJapan.jp" site_id="DTH#6862">NHK World TV 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="Nickelodeon.it" site_id="DTH#320">Nickelodeon</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="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="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="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="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="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="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="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="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> <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="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="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="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="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="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="SkyAdventure.it" site_id="DTH#11889">Sky Adventure</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="SkyAdventure.it" site_id="DTH#11890">Sky Adventure</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="SkyArte.it" site_id="DTH#7767">Sky Arte</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="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" 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="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="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="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="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="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="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="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" 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="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#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" 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#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</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" 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="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="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#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="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" 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="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="SkySport24.it" site_id="DTH#9094">Sky Sport24</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="SkySport251.it" site_id="DTH#11497">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="SkySport252.it" site_id="DTH#11496">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="SkySport253.it" site_id="DTH#11494">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="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#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="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="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="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="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="SkySportMix.it" site_id="DTH#11909">Sky Sport Mix</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="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="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="SkySportUno.it" site_id="DTH#11346">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="SkyTG24.it" site_id="DTH#9117">Sky TG24</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" 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="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="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="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="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="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="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="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="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="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="ZonaDAZN2.it" site_id="DTH#11401">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="ZonaDAZN3.it" site_id="DTH#11849">DAZN3</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="ZonaDAZN4.it" site_id="DTH#11850">DAZN4</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">DAZN 1</channel>
<channel site="guidatv.sky.it" lang="it" xmltv_id="ZonaDAZN.it" site_id="DTH#11402">ZONA DAZN</channel>
</channels> </channels>
+13 -20
View File
@@ -1,4 +1,5 @@
const dayjs = require('dayjs') const dayjs = require('dayjs')
const axios = require('axios')
module.exports = { module.exports = {
site: 'guidatv.sky.it', site: 'guidatv.sky.it',
@@ -31,29 +32,21 @@ module.exports = {
return programs return programs
}, },
async channels() { async channels() {
const axios = require('axios') const res = await axios.get('https://apid.sky.it/gtv/v1/channels?env=DTH')
const cheerio = require('cheerio') 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 return {
.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({
lang: 'it', lang: 'it',
site_id: `DTH#${channelId}`, site_id: `DTH#${ch.id}`,
name name: ch.name,
xmltv_id: ch.name.replace(/ |HD|\+1|\+24/g, '') + num + '.it' + feeds,
}
}) })
})
return channels return channels
} }
} }
+22 -1
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 fs = require('fs')
const path = require('path') const path = require('path')
const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat') const customParseFormat = require('dayjs/plugin/customParseFormat')
@@ -50,3 +51,23 @@ it('can handle empty guide', () => {
}) })
expect(result).toMatchObject([]) 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
@@ -1,17 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<channels> <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" 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="ArenaSport1Premium.rs" site_id="a1p">Arena 1 Premium</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="ArenaSport1x2.rs" site_id="1x2">Arena Sport 1x2</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="ArenaSport2.rs" site_id="02">Arena Sport 2</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="ArenaSport2Premium.rs" site_id="a2p">Arena 2 Premium</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="ArenaSport3.rs" site_id="03">Arena Sport 3</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="ArenaSport3Premium.rs" site_id="a3p">Arena 3 Premium</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="ArenaSport4.rs" site_id="04">Arena Sport 4</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="ArenaSport5.rs" site_id="05">Arena Sport 5</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="ArenaSport6.rs" site_id="06">Arena Sport 6</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="ArenaSport7.rs" site_id="07">Arena Sport 7</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="ArenaSport8.rs" site_id="08">Arena Sport 8</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="" site_id="09">Arena Sport 9</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="" site_id="10">Arena Sport 10</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> </channels>
@@ -9,9 +9,12 @@ dayjs.extend(utc)
dayjs.extend(timezone) dayjs.extend(timezone)
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
const CHANNEL_LOGO_REGEX = /chanel-([\w-]+?)\.png/
const TIMEZONE = 'Europe/Belgrade'
module.exports = { module.exports = {
site: 'tvarenasport.com', site: 'tvarenasport.com',
tz: 'Europe/Belgrade', tz: TIMEZONE,
lang: 'sr', lang: 'sr',
days: 2, days: 2,
request: { request: {
@@ -23,110 +26,77 @@ module.exports = {
parser({ content, channel, date }) { parser({ content, channel, date }) {
const programs = [] const programs = []
const expectedDate = date.format('YYYY-MM-DD') const expectedDate = date.format('YYYY-MM-DD')
if (content) {
const dates = []
const $ = cheerio.load(content) 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')
}
})
}
return programs.filter( $('.tv-scheme-chanel').each((_, el) => {
p => const $ch = $(el)
p.start.format('YYYY-MM-DD') === expectedDate || const logo = $ch.find('.tv-scheme-chanel-header img').attr('src') || ''
p.stop.format('YYYY-MM-DD') === expectedDate 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)
})
programs.push(...entries)
})
return programs
}, },
async channels() { async channels() {
const channels = [] const data = await axios.get(this.url).then(r => r.data).catch(console.error)
const data = await axios if (!data) return []
.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 $ = cheerio.load(data)
const items = $('.tv-scheme-chanel-header img').toArray() return $('.tv-scheme-chanel-header img')
for (const item of items) { .map((_, img) => {
const [, id] = $(item) const src = $(img).attr('src') || ''
.attr('src') const m = src.match(CHANNEL_LOGO_REGEX)
.match(/chanel-([a-z0-9]+)\.png/) || [null, null] if (!m) return null
if (id) { const id = m[1]
channels.push({ const displayName = getDisplayName(id)
lang: this.lang, const xmltvId = displayName.replaceAll(' ', '').replace(/Serbia$/, '.rs')
site_id: id, const logourl = `https://www.${this.site}${src}`
name: names(id) return { site_id: id, lang: this.lang, xmltv_id: xmltvId, name: displayName, logo: logourl }
}) })
} .get()
}
}
return channels
} }
} }
function parseSchedules($s, date, tz) { function getDisplayName(id) {
const schedules = [] const template = name => `Arena Sport ${name} Serbia`
const $ = $s._make let m
$s.find('.slider-content') if ((m = /^0*(\d+)$/.exec(id))) return template(m[1])
.toArray() if ((m = /^a+(\d+)p$/.exec(id))) return template(`${m[1]} Premium`)
.forEach(el => { const formattedId = id.replace(/^a-/, '').replace(/^./, c => c.toUpperCase())
schedules.push(parseSchedule($(el), date, tz)) return template(formattedId)
})
return schedules
} }
function parseSchedule($s, date, tz) { function parseSchedules($, $slider, date) {
const time = $s.find('.slider-content-top span').text() return $slider
const start = dayjs.tz(`${date.format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm', tz) .find('.slider-content')
const category = $s.find('.slider-content-middle span').text() .map((_, el) => parseSchedule($(el), date))
const title = $s.find('.slider-content-bottom p').text() .get()
const description = $s.find('.slider-content-bottom span:first').text() }
return { function parseSchedule($s, date) {
title: description ? description : title, const time = $s.find('.slider-content-top span').text().trim()
description: description ? title : description, const start = dayjs.tz(`${date.format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm', TIMEZONE)
category, const sport = $s.find('.slider-content-middle span').text().trim()
start 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 }
} }
+11 -12
View File
@@ -8,7 +8,7 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
dayjs.extend(utc) 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 = { const channel = {
site_id: 'a1p', site_id: 'a1p',
xmltv_id: 'ArenaSport1Premium.rs' xmltv_id: 'ArenaSport1Premium.rs'
@@ -20,24 +20,23 @@ it('can generate valid url', () => {
it('can parse response', () => { it('can parse response', () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content.html')) 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.start = p.start.toJSON()
p.stop = p.stop.toJSON() p.stop = p.stop.toJSON()
return p return p
}) })
expect(result.length).toBe(19) expect(result.length).toBe(13)
expect(result[4]).toMatchObject({ expect(result[4]).toMatchObject({
start: '2024-12-07T03:30:00.000Z', start: '2025-07-30T08:00:00.000Z',
stop: '2024-12-07T05:00:00.000Z', stop: '2025-07-30T09:00:00.000Z',
title: 'EVROPSKO PRVENSTVO Ž', title: 'UEFA LIGA ŠAMPIONA: Liga Šampiona: Pregled sezone',
description: 'Francuska - Crna Gora', category: 'Fudbal'
category: 'Rukomet'
}) })
expect(result[8]).toMatchObject({ expect(result[6]).toMatchObject({
start: '2024-12-07T11:00:00.000Z', start: '2025-07-30T11:00:00.000Z',
stop: '2024-12-07T11:05:00.000Z', stop: '2025-07-30T13:00:00.000Z',
title: 'Arena News' title: '(Uživo) PRIJATELJSKE UTAKMICE: K League - Newcastle Utd'
}) })
}) })
File diff suppressed because it is too large Load Diff
-1
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}}
-1
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}}
+78
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
}
}
-1
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}}
-1
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}}
+11 -11
View File
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<channels> <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="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="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> <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="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="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="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="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="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="FoxSports1.us" 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="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="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="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> <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="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="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="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="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="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="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="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="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="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> <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="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="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="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="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="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="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="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="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="NHLNetwork.us" site_id="9233009455">NHL Network</channel>
<channel site="tvguide.com" lang="en" xmltv_id="Nickelodeon.us@East" site_id="9200006939">Nickelodeon</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="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="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="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="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="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="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="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="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="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="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="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> <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="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="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="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="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="VH1.us@East" site_id="9233000037">VH1</channel>
<channel site="tvguide.com" lang="en" xmltv_id="VICETV.us" site_id="9233002242">VICE</channel> <channel site="tvguide.com" lang="en" xmltv_id="VICETV.us" site_id="9233002242">VICE</channel>
+63 -25
View File
@@ -2,22 +2,46 @@ const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone') const timezone = require('dayjs/plugin/timezone')
const doFetch = require('@ntlab/sfetch')
const debug = require('debug')('site:tvguide.com') const debug = require('debug')('site:tvguide.com')
dayjs.extend(utc) dayjs.extend(utc)
dayjs.extend(timezone) dayjs.extend(timezone)
doFetch.setDebugger(debug).setCheckResult(false)
const providerId = '9100001138' const providerId = '9100001138'
const maxDuration = 240 const maxDuration = 240
const segments = 1440 / maxDuration 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 = { module.exports = {
site: 'tvguide.com', site: 'tvguide.com',
days: 2, days: 2,
request: { request: {
headers: function () {
return headers
},
responseType: 'application/json',
decompress: true,
cache: { cache: {
ttl: 24 * 60 * 60 * 1000 // 1 day 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/${providerId}/web?${params.join('&')}` :
`https://backend.tvguide.com/tvschedules/tvguide/serviceprovider/${providerId}/sources/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 programs = []
const f = data => { const f = data => {
const result = [] const result = []
@@ -60,55 +84,69 @@ module.exports = {
return result return result
} }
const queues = f(content) const queues = f(content)
if (queues.length) { if (queues.length && fetchSegments) {
const parts = [] for (let segment = 2; segment <= segments; segment++) {
for (let i = 2; i <= segments; i++) { const segmentUrl = await module.exports.url({ date, segment })
parts.push(await module.exports.url({ date, segment: i })) 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)) }
}) for (const queue of queues) {
await doFetch(queues, (queue, res) => { try {
const item = res?.data?.item ? res.data.item : queue.i const res = await axios.get(queue.url, { headers })
const item = res.data?.data?.item || queue.i
programs.push({ programs.push({
title: item.title ? item.title : queue.i.title, title: item.title || queue.i.title,
sub_title: item.episodeNumber ? item.episodeTitle : null, sub_title: item.episodeNumber ? item.episodeTitle : null,
description: item.description, description: item.description,
season: item.seasonNumber, season: item.seasonNumber,
episode: item.episodeNumber, episode: item.episodeNumber,
rating: item.rating ? { system: 'MPA', value: item.rating } : null, rating: item.rating ? { system: 'MPA', value: item.rating } : null,
categories: Array.isArray(item.genres) ? item.genres.map(g => g.name) : null, categories: Array.isArray(item.genres) ? item.genres.map(g => g.name) : null,
start: dayjs.unix(item.startTime ? item.startTime : queue.i.startTime), start: dayjs.unix(item.startTime || queue.i.startTime),
stop: dayjs.unix(item.endTime ? item.endTime : queue.i.endTime) stop: dayjs.unix(item.endTime || queue.i.endTime),
})
}) })
} catch (err) {
debug(`Failed to fetch program details ${queue.url}: ${err.message}`)
}
} }
return programs return programs
}, },
async channels() { async channels() {
const channels = [] const channels = []
try {
const data = await axios const data = await axios
.get(await this.url({})) .get(await this.url({}), { headers })
.then(r => r.data) .then(r => r.data)
.catch(console.error)
data.data.items.forEach(item => { 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({ channels.push({
lang: 'en', lang: 'en',
site_id: item.sourceId, site_id: item.sourceId,
name: item.fullName.replace(/Channel|Schedule/g, '').trim() xmltv_id: finalName.replaceAll(/[ '&]/g, '') + '.us' + (isEast ? '@East' : ''),
name: finalName
}) })
}) })
} catch (err) {
console.error('Failed to fetch channels:', err.message)
}
return channels return channels
}, },
async fetchApiKey() { async fetchApiKey() {
try {
const data = await axios const data = await axios
.get('https://www.tvguide.com/listings/') .get('https://www.tvguide.com/listings/')
.then(r => r.data) .then(r => r.data)
.catch(console.error)
return data ? data.match(/apiKey=([a-zA-Z0-9]+)&/)[1] : null return data ? data.match(/apiKey=([a-zA-Z0-9]+)&/)[1] : null
} catch (err) {
console.error('Failed to fetch API key:', err.message)
return null
}
} }
} }
+41 -58
View File
@@ -5,83 +5,66 @@ const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat') const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
dayjs.extend(utc) dayjs.extend(utc)
jest.mock('axios') 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 = { const channel = {
site_id: '9200018514', site_id: '9200004683',
xmltv_id: 'CBSEast.us' 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 () => { it('can generate valid url', async () => {
expect(await url({ date })).toBe( axios.get.mockImplementation(url => {
'https://backend.tvguide.com/tvschedules/tvguide/9100001138/web?start=1736640000&duration=240&apiKey=DI9elXhZ3bU6ujsA2gXEKOANyncXGUGc' 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 () => { it('can parse response', async () => {
const content = fs.readFileSync(path.join(__dirname, '__data__', 'content1.json')).toString() const content = JSON.parse(fs.readFileSync(path.join(__dirname, '__data__', 'content.json'), 'utf-8'))
const results = (await parser({ content, channel, date })).map(p => {
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.start = p.start.toJSON()
p.stop = p.stop.toJSON() p.stop = p.stop.toJSON()
return p return p
}) })
expect(results.length).toBe(5)
expect(results[0]).toMatchObject({ expect(results[0]).toMatchObject({
start: '2025-01-12T01:00:00.000Z', start: '2025-07-29T00:00:00.000Z',
stop: '2025-01-12T02:00:00.000Z', stop: '2025-07-29T01:00:00.000Z',
title: 'FBI: International', title: 'Secrets of the Zoo: North Carolina',
sub_title: 'Gift', sub_title: 'Chimp Off the Old Block',
description: 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.', '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: ['Action & Adventure', 'Suspense', 'Drama'], categories: ['Reality'],
season: 3, season: 1,
episode: 12, episode: 1,
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'
}
}) })
}) })
@@ -89,7 +72,7 @@ it('can handle empty guide', async () => {
const results = await parser({ const results = await parser({
date, date,
channel, 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([]) expect(results).toMatchObject([])
}) })
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+45 -23
View File
@@ -12,22 +12,28 @@ module.exports = {
}, },
request: { request: {
headers: { 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 }) { parser: function ({ content }) {
let programs = [] let programs = []
const items = parseItems(content) const items = parseItems(content)
items.forEach(item => { items.forEach(item => {
const $item = cheerio.load(item) const $ = cheerio.load(item)
$('div.row').each((_, el) => {
const $item = $(el)
const title = parseTitle($item) const title = parseTitle($item)
const category = parseCategory($item) const category = parseCategory($item)
const start = parseStart($item) const start = parseStart($item)
const duration = parseDuration($item) const duration = parseDuration($item)
const stop = start.add(duration, 's') const stop = start.add(duration, 's')
const image = parseImage($item) const icon = parseImage($item)
programs.push({ title, category, start, stop, image }) programs.push({ title, category, start, stop, icon })
})
}) })
return programs return programs
@@ -74,6 +80,12 @@ module.exports = {
.get(url, { .get(url, {
params: { params: {
callback: 'cb' 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) .then(r => r.data)
@@ -91,6 +103,7 @@ module.exports = {
channels.push({ channels.push({
lang, lang,
site_id: `${config.progsPath}#${item.urlID}`, site_id: `${config.progsPath}#${item.urlID}`,
xmltv_id: `${item.title.replaceAll(/[ '&]/g, '')}.${country}`,
name: item.title name: item.title
}) })
}) })
@@ -102,63 +115,72 @@ module.exports = {
} }
function parseImage($item) { function parseImage($item) {
return $item(':root').data('image') return $item.attr('data-image') || null
} }
function parseDuration($item) { function parseDuration($item) {
return $item(':root').data('len') return parseInt($item.attr('data-len'))
} }
function parseStart($item) { function parseStart($item) {
const timestamp = $item(':root').data('ts') const timestamp = parseInt($item.attr('data-ts'))
return dayjs.unix(timestamp) return dayjs.unix(timestamp)
} }
function parseCategory($item) { 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) { function parseTitle($item) {
let title = $item('.col:nth-child(2) > a').text() let title = $item.find('.col:nth-child(2) > a').text()
title += $item('.col:nth-child(2)').clone().children().remove().end().text() title += $item.find('.col:nth-child(2)').clone().children().remove().end().text()
return title.replace('®', '').trim().replace(/,$/, '') return title.replace('®', '').trim().replace(/,$/, '')
} }
function parseItems(content) { function parseItems(content) {
let data = (content.match(/cb\((.*)\)/) || [null, null])[1] let data = (content.match(/^[^(]+\(([\s\S]*)\)$/) || [null, null])[1]
if (!data) return [] if (!data) return []
let json = JSON.parse(data) let json = JSON.parse(data)
if (!json || !json.data || !json.data.program) return [] if (!json || !json.data || !json.data.program) return []
const $ = cheerio.load(json.data.program) return [json.data.program]
return $('.row').toArray()
} }
function buildQuery(site_id, date) { function buildQuery(site_id, date) {
const query = { const query = {
datum: date.format('YYYY-MM-DD'), datum: date.format('YYYY-MM-DD'),
kanal: site_id, kanal: site_id
callback: 'cb' // callback: 'cb' // possibly still working
} }
let c = 4 let c = 4
const a = query.datum + query.kanal + c let a = query.datum + query.kanal + c
const ua = query.kanal + query.datum let ua = query.kanal + query.datum
let i = a.length, if (
b = 2 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) for (let j = 0; j < ua.length; j++) c += ua.charCodeAt(j)
let i = a.length
let b = 2
while (i--) { while (i--) {
b += (a.charCodeAt(i) + c * 2) * i b += (a.charCodeAt(i) + c * 2) * i
} }
b = b.toString() 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 query[key] = b
return new URLSearchParams(query).toString() return new URLSearchParams(query).toString()
+7 -6
View File
@@ -7,7 +7,7 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
dayjs.extend(utc) 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 = { const channel = {
site_id: 'bg/tv-programa#24kitchen-bg', site_id: 'bg/tv-programa#24kitchen-bg',
xmltv_id: '24KitchenBulgaria.bg' xmltv_id: '24KitchenBulgaria.bg'
@@ -15,13 +15,14 @@ const channel = {
it('can generate valid url', () => { it('can generate valid url', () => {
expect(url({ channel, date })).toBe( 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', () => { it('can generate valid request headers', () => {
expect(request.headers).toMatchObject({ 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({ expect(results[0]).toMatchObject({
title: 'Мексиканска кухня с Пати 10, еп. 9', title: 'Save with Jamie 1, ep. 2',
start: '2023-01-12T04:00:00.000Z', start: '2025-07-29T05:00:00.000Z',
stop: '2023-01-12T04:30:00.000Z' stop: '2025-07-29T06:00:00.000Z'
}) })
}) })
+1 -1
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="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="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="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="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@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> <channel site="tvtv.us" lang="en" xmltv_id="HallmarkChannel.us@West" site_id="19933">Hallmark Channel West</channel>