mirror of
https://github.com/iptv-org/epg
synced 2026-04-28 21:46:58 -04:00
Merge pull request #2821 from whitesnakeftw/master
Fix tvprofil.com + tvguide.com + tvarenasport.com + guidatv.sky.it
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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 } ] }]}
|
||||
|
||||
2417
sites/guidatv.sky.it/__data__/data.json
Normal file
2417
sites/guidatv.sky.it/__data__/data.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
@@ -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'
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
8109
sites/tvguide.com/__data__/content.json
Normal file
8109
sites/tvguide.com/__data__/content.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 +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
sites/tvguide.com/__data__/program.json
Normal file
78
sites/tvguide.com/__data__/program.json
Normal 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 +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 +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}}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user