Merge pull request #1637 from iptv-org/patch-2023.01.3

Patch 2023.01.3
This commit is contained in:
Aleksandr Statciuk 2023-01-11 12:38:46 +03:00 committed by GitHub
commit ee0a721240
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
212 changed files with 398 additions and 542 deletions

View file

@ -39,14 +39,11 @@ jobs:
path: scripts/logs path: scripts/logs
- run: npm run api:update - run: npm run api:update
- run: npm run readme:update - run: npm run readme:update
- run: npm run status:update
- name: Commit Changes - name: Commit Changes
if: ${{ !env.ACT }} if: ${{ !env.ACT }}
run: | run: |
git add README.md git add README.md
git commit --allow-empty -m "[Bot] Update README.md" git commit --allow-empty -m "[Bot] Update README.md"
git add STATUS.md
git commit --allow-empty -m "[Bot] Update STATUS.md"
git status git status
- name: Push to origin - name: Push to origin
if: ${{ !env.ACT }} if: ${{ !env.ACT }}

3
.readme/.gitignore vendored
View file

@ -1,2 +1 @@
_countries.md _guides.md
_sites.md

View file

@ -4,14 +4,16 @@
EPG (Electronic Program Guide) for thousands of TV channels collected from different sources. EPG (Electronic Program Guide) for thousands of TV channels collected from different sources.
## Usage ## How to use?
To load a program guide, all you need to do is copy the link to one or more of the guides from the list below and paste it into your favorite player. To load a program guide, all you need to do is copy the link to one or more of the guides from the list below and paste it into your favorite player.
<!-- prettier-ignore --> ## Guides
#include "./.readme/_countries.md"
All guides also have a compressed and JSON version. To download them, simply change the extension from `.xml` to `.xml.gz` or `.json` respectively. All guides also have a compressed and JSON version. To load them just change the extension from `.xml` to `.xml.gz` or `.json` respectively.
<!-- prettier-ignore -->
#include "./.readme/_guides.md"
## Contribution ## Contribution

View file

@ -1,4 +0,0 @@
{
"build": "STATUS.md",
"files": ["./.readme/status.md"]
}

View file

@ -1,4 +0,0 @@
# Status
<!-- prettier-ignore -->
#include "./.readme/_sites.md"

150
STATUS.md
View file

@ -1,150 +0,0 @@
# Status
<!-- prettier-ignore -->
<table>
<thead>
<tr><th align="left">Site</th><th align="left">Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th></tr>
</thead>
<tbody>
<tr><td valign="top" rowspan="1">9tv.co.il</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/9tv.co.il.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/9tv.co.il.yml/badge.svg" alt="9tv.co.il" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">abc.net.au</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/abc.net.au.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/abc.net.au.yml/badge.svg" alt="abc.net.au" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">allente.se</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/allente.se.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/allente.se.yml/badge.svg" alt="allente.se" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">andorradifusio.ad</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/andorradifusio.ad.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/andorradifusio.ad.yml/badge.svg" alt="andorradifusio.ad" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">arianaafgtv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/arianaafgtv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/arianaafgtv.com.yml/badge.svg" alt="arianaafgtv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">arianatelevision.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/arianatelevision.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/arianatelevision.com.yml/badge.svg" alt="arianatelevision.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">artonline.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/artonline.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/artonline.tv.yml/badge.svg" alt="artonline.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">astro.com.my</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/astro.com.my.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/astro.com.my.yml/badge.svg" alt="astro.com.my" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">bein.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/bein.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/bein.com.yml/badge.svg" alt="bein.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">beinsports.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/beinsports.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/beinsports.com.yml/badge.svg" alt="beinsports.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">bt.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/bt.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/bt.com.yml/badge.svg" alt="bt.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">cablego.com.pe</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/cablego.com.pe.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/cablego.com.pe.yml/badge.svg" alt="cablego.com.pe" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">canalplus-afrique.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/canalplus-afrique.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/canalplus-afrique.com.yml/badge.svg" alt="canalplus-afrique.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">canalplus-caraibes.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/canalplus-caraibes.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/canalplus-caraibes.com.yml/badge.svg" alt="canalplus-caraibes.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">canalplus-haiti.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/canalplus-haiti.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/canalplus-haiti.com.yml/badge.svg" alt="canalplus-haiti.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">canalplus-reunion.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/canalplus-reunion.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/canalplus-reunion.com.yml/badge.svg" alt="canalplus-reunion.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">canalplus.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/canalplus.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/canalplus.com.yml/badge.svg" alt="canalplus.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">cgates.lt</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/cgates.lt.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/cgates.lt.yml/badge.svg" alt="cgates.lt" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">chaines-tv.orange.fr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/chaines-tv.orange.fr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/chaines-tv.orange.fr.yml/badge.svg" alt="chaines-tv.orange.fr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">clickthecity.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/clickthecity.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/clickthecity.com.yml/badge.svg" alt="clickthecity.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">compulms.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/compulms.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/compulms.com.yml/badge.svg" alt="compulms.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">comteco.com.bo</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/comteco.com.bo.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/comteco.com.bo.yml/badge.svg" alt="comteco.com.bo" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">cosmote.gr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/cosmote.gr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/cosmote.gr.yml/badge.svg" alt="cosmote.gr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">delta.nl</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/delta.nl.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/delta.nl.yml/badge.svg" alt="delta.nl" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">digiturk.com.tr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/digiturk.com.tr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/digiturk.com.tr.yml/badge.svg" alt="digiturk.com.tr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">directv.com.ar</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/directv.com.ar.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/directv.com.ar.yml/badge.svg" alt="directv.com.ar" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">directv.com.uy</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/directv.com.uy.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/directv.com.uy.yml/badge.svg" alt="directv.com.uy" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">directv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/directv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/directv.com.yml/badge.svg" alt="directv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">dishtv.in</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/dishtv.in.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/dishtv.in.yml/badge.svg" alt="dishtv.in" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">dsmart.com.tr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/dsmart.com.tr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/dsmart.com.tr.yml/badge.svg" alt="dsmart.com.tr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">dstv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/dstv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/dstv.com.yml/badge.svg" alt="dstv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">elcinema.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/elcinema.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/elcinema.com.yml/badge.svg" alt="elcinema.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">epg.i-cable.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/epg.i-cable.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/epg.i-cable.com.yml/badge.svg" alt="epg.i-cable.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">foxsports.com.au</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/foxsports.com.au.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/foxsports.com.au.yml/badge.svg" alt="foxsports.com.au" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">frikanalen.no</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/frikanalen.no.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/frikanalen.no.yml/badge.svg" alt="frikanalen.no" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">gatotv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/gatotv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/gatotv.com.yml/badge.svg" alt="gatotv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">getafteritmedia.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/getafteritmedia.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/getafteritmedia.com.yml/badge.svg" alt="getafteritmedia.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">guidatv.sky.it</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/guidatv.sky.it.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/guidatv.sky.it.yml/badge.svg" alt="guidatv.sky.it" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">guide.dstv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/guide.dstv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/guide.dstv.com.yml/badge.svg" alt="guide.dstv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">hd-plus.de</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/hd-plus.de.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/hd-plus.de.yml/badge.svg" alt="hd-plus.de" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">horizon.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/horizon.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/horizon.tv.yml/badge.svg" alt="horizon.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">i.mjh.nz</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/i.mjh.nz.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/i.mjh.nz.yml/badge.svg" alt="i.mjh.nz" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">i24news.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/i24news.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/i24news.tv.yml/badge.svg" alt="i24news.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">ionplustv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/ionplustv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ionplustv.com.yml/badge.svg" alt="ionplustv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">ipko.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/ipko.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ipko.com.yml/badge.svg" alt="ipko.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">knr.gl</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/knr.gl.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/knr.gl.yml/badge.svg" alt="knr.gl" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">kvf.fo</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/kvf.fo.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/kvf.fo.yml/badge.svg" alt="kvf.fo" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">m.tv.sms.cz</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/m.tv.sms.cz.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/m.tv.sms.cz.yml/badge.svg" alt="m.tv.sms.cz" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">magentatv.at</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/magentatv.at.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/magentatv.at.yml/badge.svg" alt="magentatv.at" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">magticom.ge</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/magticom.ge.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/magticom.ge.yml/badge.svg" alt="magticom.ge" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mako.co.il</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mako.co.il.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mako.co.il.yml/badge.svg" alt="mako.co.il" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">maxtv.hrvatskitelekom.hr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/maxtv.hrvatskitelekom.hr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/maxtv.hrvatskitelekom.hr.yml/badge.svg" alt="maxtv.hrvatskitelekom.hr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">maxtvgo.mk</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/maxtvgo.mk.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/maxtvgo.mk.yml/badge.svg" alt="maxtvgo.mk" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mediaklikk.hu</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mediaklikk.hu.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mediaklikk.hu.yml/badge.svg" alt="mediaklikk.hu" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mediaset.it</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mediaset.it.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mediaset.it.yml/badge.svg" alt="mediaset.it" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">melita.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/melita.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/melita.com.yml/badge.svg" alt="melita.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">meo.pt</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/meo.pt.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/meo.pt.yml/badge.svg" alt="meo.pt" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mewatch.sg</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mewatch.sg.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mewatch.sg.yml/badge.svg" alt="mewatch.sg" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mi.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mi.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mi.tv.yml/badge.svg" alt="mi.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mncvision.id</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mncvision.id.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mncvision.id.yml/badge.svg" alt="mncvision.id" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">movistarplus.es</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/movistarplus.es.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/movistarplus.es.yml/badge.svg" alt="movistarplus.es" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mtel.ba</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mtel.ba.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mtel.ba.yml/badge.svg" alt="mtel.ba" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mts.rs</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mts.rs.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mts.rs.yml/badge.svg" alt="mts.rs" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mujtvprogram.cz</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mujtvprogram.cz.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mujtvprogram.cz.yml/badge.svg" alt="mujtvprogram.cz" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">musor.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/musor.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/musor.tv.yml/badge.svg" alt="musor.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">myafn.dodmedia.osd.mil</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/myafn.dodmedia.osd.mil.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/myafn.dodmedia.osd.mil.yml/badge.svg" alt="myafn.dodmedia.osd.mil" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mysky.com.ph</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mysky.com.ph.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mysky.com.ph.yml/badge.svg" alt="mysky.com.ph" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">mytvsuper.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/mytvsuper.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/mytvsuper.com.yml/badge.svg" alt="mytvsuper.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">novacyprus.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/novacyprus.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/novacyprus.com.yml/badge.svg" alt="novacyprus.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">novasports.gr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/novasports.gr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/novasports.gr.yml/badge.svg" alt="novasports.gr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">nowplayer.now.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/nowplayer.now.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/nowplayer.now.com.yml/badge.svg" alt="nowplayer.now.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">ontvtonight.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/ontvtonight.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ontvtonight.com.yml/badge.svg" alt="ontvtonight.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">osn.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/osn.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/osn.com.yml/badge.svg" alt="osn.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">pbsguam.org</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/pbsguam.org.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/pbsguam.org.yml/badge.svg" alt="pbsguam.org" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">plex.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/plex.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/plex.tv.yml/badge.svg" alt="plex.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programacion-tv.elpais.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programacion-tv.elpais.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programacion-tv.elpais.com.yml/badge.svg" alt="programacion-tv.elpais.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programetv.ro</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programetv.ro.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programetv.ro.yml/badge.svg" alt="programetv.ro" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programme-tv.net</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programme-tv.net.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programme-tv.net.yml/badge.svg" alt="programme-tv.net" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programme-tv.vini.pf</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programme-tv.vini.pf.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programme-tv.vini.pf.yml/badge.svg" alt="programme-tv.vini.pf" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programme.tvb.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programme.tvb.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programme.tvb.com.yml/badge.svg" alt="programme.tvb.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">programtv.onet.pl</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/programtv.onet.pl.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/programtv.onet.pl.yml/badge.svg" alt="programtv.onet.pl" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">raiplay.it</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/raiplay.it.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/raiplay.it.yml/badge.svg" alt="raiplay.it" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">reportv.com.ar</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/reportv.com.ar.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/reportv.com.ar.yml/badge.svg" alt="reportv.com.ar" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">rev.bs</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/rev.bs.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/rev.bs.yml/badge.svg" alt="rev.bs" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">rthk.hk</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/rthk.hk.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/rthk.hk.yml/badge.svg" alt="rthk.hk" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">rtmklik.rtm.gov.my</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/rtmklik.rtm.gov.my.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/rtmklik.rtm.gov.my.yml/badge.svg" alt="rtmklik.rtm.gov.my" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">rtp.pt</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/rtp.pt.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/rtp.pt.yml/badge.svg" alt="rtp.pt" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">ruv.is</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/ruv.is.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ruv.is.yml/badge.svg" alt="ruv.is" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">seezntv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/seezntv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/seezntv.com.yml/badge.svg" alt="seezntv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">siba.com.co</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/siba.com.co.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/siba.com.co.yml/badge.svg" alt="siba.com.co" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">sjonvarp.is</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/sjonvarp.is.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/sjonvarp.is.yml/badge.svg" alt="sjonvarp.is" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">sky.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/sky.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/sky.com.yml/badge.svg" alt="sky.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">sportsnet.ca</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/sportsnet.ca.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/sportsnet.ca.yml/badge.svg" alt="sportsnet.ca" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">starhubtvplus.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/starhubtvplus.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/starhubtvplus.com.yml/badge.svg" alt="starhubtvplus.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">startimestv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/startimestv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/startimestv.com.yml/badge.svg" alt="startimestv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tapdmv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tapdmv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tapdmv.com.yml/badge.svg" alt="tapdmv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">telecablesat.fr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/telecablesat.fr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/telecablesat.fr.yml/badge.svg" alt="telecablesat.fr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">telenet.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/telenet.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/telenet.tv.yml/badge.svg" alt="telenet.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">teliatv.ee</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/teliatv.ee.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/teliatv.ee.yml/badge.svg" alt="teliatv.ee" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">telkku.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/telkku.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/telkku.com.yml/badge.svg" alt="telkku.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">telkussa.fi</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/telkussa.fi.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/telkussa.fi.yml/badge.svg" alt="telkussa.fi" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">telsu.fi</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/telsu.fi.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/telsu.fi.yml/badge.svg" alt="telsu.fi" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tivu.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tivu.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tivu.tv.yml/badge.svg" alt="tivu.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">toonamiaftermath.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/toonamiaftermath.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/toonamiaftermath.com.yml/badge.svg" alt="toonamiaftermath.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">transvision.co.id</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/transvision.co.id.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/transvision.co.id.yml/badge.svg" alt="transvision.co.id" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.blue.ch</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.blue.ch.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.blue.ch.yml/badge.svg" alt="tv.blue.ch" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.cctv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.cctv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.cctv.com.yml/badge.svg" alt="tv.cctv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.dir.bg</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.dir.bg.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.dir.bg.yml/badge.svg" alt="tv.dir.bg" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.lv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.lv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.lv.yml/badge.svg" alt="tv.lv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.mail.ru</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.mail.ru.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.mail.ru.yml/badge.svg" alt="tv.mail.ru" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.movistar.com.pe</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.movistar.com.pe.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.movistar.com.pe.yml/badge.svg" alt="tv.movistar.com.pe" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.nu</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.nu.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.nu.yml/badge.svg" alt="tv.nu" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.trueid.net</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.trueid.net.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.trueid.net.yml/badge.svg" alt="tv.trueid.net" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.yandex.ru</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.yandex.ru.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.yandex.ru.yml/badge.svg" alt="tv.yandex.ru" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv.yettel.hu</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv.yettel.hu.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv.yettel.hu.yml/badge.svg" alt="tv.yettel.hu" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv24.co.uk</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv24.co.uk.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv24.co.uk.yml/badge.svg" alt="tv24.co.uk" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv24.se</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv24.se.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv24.se.yml/badge.svg" alt="tv24.se" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tv2go.t-2.net</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tv2go.t-2.net.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tv2go.t-2.net.yml/badge.svg" alt="tv2go.t-2.net" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tva.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tva.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tva.tv.yml/badge.svg" alt="tva.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvarenasport.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvarenasport.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvarenasport.com.yml/badge.svg" alt="tvarenasport.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvcubana.icrt.cu</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvcubana.icrt.cu.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvcubana.icrt.cu.yml/badge.svg" alt="tvcubana.icrt.cu" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvgids.nl</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvgids.nl.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvgids.nl.yml/badge.svg" alt="tvgids.nl" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvguide.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvguide.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvguide.com.yml/badge.svg" alt="tvguide.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvguide.myjcom.jp</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvguide.myjcom.jp.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvguide.myjcom.jp.yml/badge.svg" alt="tvguide.myjcom.jp" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvhebdo.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvhebdo.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvhebdo.com.yml/badge.svg" alt="tvhebdo.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvheute.at</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvheute.at.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvheute.at.yml/badge.svg" alt="tvheute.at" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvim.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvim.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvim.tv.yml/badge.svg" alt="tvim.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvmi.mt</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvmi.mt.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvmi.mt.yml/badge.svg" alt="tvmi.mt" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvmusor.hu</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvmusor.hu.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvmusor.hu.yml/badge.svg" alt="tvmusor.hu" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvpassport.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvpassport.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvpassport.com.yml/badge.svg" alt="tvpassport.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">tvplus.com.tr</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/tvplus.com.tr.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/tvplus.com.tr.yml/badge.svg" alt="tvplus.com.tr" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">useetv.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/useetv.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/useetv.com.yml/badge.svg" alt="useetv.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">vidio.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/vidio.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/vidio.com.yml/badge.svg" alt="vidio.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">virginmedia.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/virginmedia.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/virginmedia.com.yml/badge.svg" alt="virginmedia.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">vtm.be</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/vtm.be.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/vtm.be.yml/badge.svg" alt="vtm.be" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">watchyour.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/watchyour.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/watchyour.tv.yml/badge.svg" alt="watchyour.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">wavve.com</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/wavve.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/wavve.com.yml/badge.svg" alt="wavve.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">xumo.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/xumo.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/xumo.tv.yml/badge.svg" alt="xumo.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">ziggogo.tv</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/ziggogo.tv.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ziggogo.tv.yml/badge.svg" alt="ziggogo.tv" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top" rowspan="1">znbc.co.zm</td><td nowrap><a href="https://github.com/iptv-org/epg/actions/workflows/znbc.co.zm.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/znbc.co.zm.yml/badge.svg" alt="znbc.co.zm" style="max-width: 100%;"></a></td></tr>
</tbody>
</table>

14
package-lock.json generated
View file

@ -15,7 +15,7 @@
"commander": "^8.2.0", "commander": "^8.2.0",
"csv-parser": "^3.0.0", "csv-parser": "^3.0.0",
"dayjs": "^1.10.8", "dayjs": "^1.10.8",
"epg-grabber": "^0.29.5", "epg-grabber": "^0.29.7",
"epg-parser": "^0.2.0", "epg-parser": "^0.2.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fs-extra": "^10.0.1", "fs-extra": "^10.0.1",
@ -2436,9 +2436,9 @@
} }
}, },
"node_modules/epg-grabber": { "node_modules/epg-grabber": {
"version": "0.29.5", "version": "0.29.7",
"resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.29.5.tgz", "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.29.7.tgz",
"integrity": "sha512-HJvziMNM7YDcJnfkIxWm5ulg76T5eH44mxsLL579dfold//QYZgaCKWMQKPNoGVuCW5SMIY7g90d08VC2rZe6w==", "integrity": "sha512-wvjevMnrJD/fr4TaJ0Wh4Y2Kyy0LLQtp+bOEsHFCsF8oe53jUnThOlUYsAT49Sx5v7A6K9GheGxDAXOpLXV67A==",
"dependencies": { "dependencies": {
"axios": "^0.21.1", "axios": "^0.21.1",
"axios-cache-interceptor": "^0.10.3", "axios-cache-interceptor": "^0.10.3",
@ -8213,9 +8213,9 @@
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
}, },
"epg-grabber": { "epg-grabber": {
"version": "0.29.5", "version": "0.29.7",
"resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.29.5.tgz", "resolved": "https://registry.npmjs.org/epg-grabber/-/epg-grabber-0.29.7.tgz",
"integrity": "sha512-HJvziMNM7YDcJnfkIxWm5ulg76T5eH44mxsLL579dfold//QYZgaCKWMQKPNoGVuCW5SMIY7g90d08VC2rZe6w==", "integrity": "sha512-wvjevMnrJD/fr4TaJ0Wh4Y2Kyy0LLQtp+bOEsHFCsF8oe53jUnThOlUYsAT49Sx5v7A6K9GheGxDAXOpLXV67A==",
"requires": { "requires": {
"axios": "^0.21.1", "axios": "^0.21.1",
"axios-cache-interceptor": "^0.10.3", "axios-cache-interceptor": "^0.10.3",

View file

@ -13,7 +13,6 @@
"api:load": "./scripts/commands/api/load.sh", "api:load": "./scripts/commands/api/load.sh",
"api:update": "node scripts/commands/api/update.js", "api:update": "node scripts/commands/api/update.js",
"readme:update": "node scripts/commands/readme/update.js", "readme:update": "node scripts/commands/readme/update.js",
"status:update": "node scripts/commands/status/update.js",
"lint": "npx eslint ./scripts/**/*.js", "lint": "npx eslint ./scripts/**/*.js",
"test": "TZ=Pacific/Nauru npx jest --runInBand", "test": "TZ=Pacific/Nauru npx jest --runInBand",
"test:commands": "npx jest --runInBand -- commands", "test:commands": "npx jest --runInBand -- commands",
@ -42,7 +41,7 @@
"commander": "^8.2.0", "commander": "^8.2.0",
"csv-parser": "^3.0.0", "csv-parser": "^3.0.0",
"dayjs": "^1.10.8", "dayjs": "^1.10.8",
"epg-grabber": "^0.29.5", "epg-grabber": "^0.29.7",
"epg-parser": "^0.2.0", "epg-parser": "^0.2.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fs-extra": "^10.0.1", "fs-extra": "^10.0.1",

View file

@ -16,6 +16,7 @@ async function main() {
channel: result.channel, channel: result.channel,
site: result.site, site: result.site,
lang: result.lang, lang: result.lang,
days: result.days,
url: `https://iptv-org.github.io/epg/guides/${result.filename}.xml` url: `https://iptv-org.github.io/epg/guides/${result.filename}.xml`
}) })
} }

View file

@ -1,7 +1,6 @@
const { db, api, logger, file, zip } = require('../../core') const { db, api, logger, file, zip } = require('../../core')
const { generateXMLTV, Program, Channel } = require('epg-grabber') const { generateXMLTV, Program, Channel } = require('epg-grabber')
const _ = require('lodash') const _ = require('lodash')
const langs = require('langs')
const PUBLIC_DIR = process.env.PUBLIC_DIR || '.gh-pages' const PUBLIC_DIR = process.env.PUBLIC_DIR || '.gh-pages'
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs' const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
@ -9,193 +8,110 @@ const CURR_DATE = process.env.CURR_DATE || new Date()
const logPath = `${LOGS_DIR}/guides/update.log` const logPath = `${LOGS_DIR}/guides/update.log`
let guides = [] let api_channels = {}
let db_programs = [] let db_programs = []
let guides = []
async function main() { async function main() {
logger.info(`starting...`) logger.info(`starting...`)
logger.info('loading data/countries.json...')
await api.countries.load()
logger.info('loading data/channels.json...') logger.info('loading data/channels.json...')
await api.channels.load() await api.channels.load()
logger.info('loading data/regions.json...')
await api.regions.load()
logger.info('loading data/subdivisions.json...')
await api.subdivisions.load()
let countries = await api.countries.all() api.channels.all().forEach(channel => {
let api_channels = await api.channels.all() api_channels[channel.id] = channel
let channels_dic = {}
api_channels.forEach(channel => {
channels_dic[channel.id] = channel
}) })
let api_regions = await api.regions.all()
let api_subdivisions = await api.subdivisions.all()
logger.info('loading database/programs.db...') logger.info('loading database/programs.db...')
await db.programs.load() await db.programs.load()
db_programs = await db.programs.find({}) db_programs = await db.programs.find({})
db_programs = db_programs
.map(p => {
if (p.titles.length) {
p.score = calcScore(p)
p.lang = p.titles[0].lang
return p
}
return null
})
.filter(Boolean)
logger.info(`found ${db_programs.length} programs`) logger.info(`found ${db_programs.length} programs`)
for (let country of countries) { await generate()
let countryBroadcastCode = `c/${country.code}`
let countryRegions = api_regions
.filter(r => r.countries.includes(country.code))
.map(r => `r/${r.code}`)
let countrySubdivisions = api_subdivisions
.filter(s => s.country === country.code)
.map(s => `s/${s.code}`)
let broadcastCodes = [countryBroadcastCode, ...countryRegions, ...countrySubdivisions]
let countryChannels = api_channels.filter( logger.info(`creating ${logPath}...`)
c => _.intersection(c.broadcast_area, broadcastCodes).length await file.create(logPath, guides.map(g => JSON.stringify(g)).join('\r\n'))
logger.info('finished')
}
main()
async function generate() {
let programs = _.groupBy(db_programs, p =>
p.titles.length ? `${p.titles[0].lang}/${p.site}` : `_`
) )
countryChannels = countryChannels.map(c => c.id)
let countryPrograms = db_programs.filter(p => countryChannels.includes(p.channel)) delete programs['_']
let langGroups = _.groupBy(countryPrograms, 'lang')
let countryLanguages = _.uniq([...country.languages, 'eng'])
let programs = {} for (let filename in programs) {
for (let langCode of countryLanguages) { let { channels } = await save(filename, programs[filename])
const lang = convertLangCode(langCode, '3', '1')
if (!lang) continue
let langPrograms = langGroups[lang]
if (!langPrograms || !langPrograms.length) continue
let channelGroups = _.groupBy(langPrograms, 'channel')
for (let channel in channelGroups) {
if (programs[channel]) continue
let groupedPrograms = channelGroups[channel]
let channelPrograms = getChannelPrograms(groupedPrograms)
if (!channelPrograms.length) continue
programs[channel] = channelPrograms
}
}
programs = _.flatten(Object.values(programs))
if (!programs.length) continue
let channels = programs.map(p => {
let c = channels_dic[p.channel]
c.site = p.site
c.lang = p.lang
return new Channel(c)
})
channels = _.sortBy(channels, 'id')
channels = _.uniqBy(channels, 'id')
programs = _.sortBy(programs, ['channel', 'start'])
programs = programs.map(p => new Program(p, new Channel(channels_dic[p.channel])))
programs = _.uniqBy(programs, p => p.channel + p.start)
const filename = country.code.toLowerCase()
const xmlFilepath = `${PUBLIC_DIR}/guides/${filename}.xml`
const gzFilepath = `${PUBLIC_DIR}/guides/${filename}.xml.gz`
const jsonFilepath = `${PUBLIC_DIR}/guides/${filename}.json`
logger.info(`creating ${xmlFilepath}...`)
const xmltv = generateXMLTV({
channels,
programs,
date: CURR_DATE
})
await file.create(xmlFilepath, xmltv)
logger.info(`creating ${gzFilepath}...`)
const compressed = await zip.compress(xmltv)
await file.create(gzFilepath, compressed)
logger.info(`creating ${jsonFilepath}...`)
await file.create(jsonFilepath, JSON.stringify({ channels, programs }))
for (let channel of channels) { for (let channel of channels) {
const configPath = `sites/${channel.site}/${channel.site}.config.js`
const config = require(file.resolve(configPath))
guides.push({ guides.push({
country: country.code,
lang: channel.lang,
site: channel.site, site: channel.site,
lang: channel.lang,
days: config.days,
channel: channel.id, channel: channel.id,
filename filename
}) })
} }
} }
logger.info(`creating ${logPath}...`)
await file.create(logPath, guides.map(g => JSON.stringify(g)).join('\r\n'))
await makeReport()
} }
main() async function save(filepath, programs) {
let output = {
function convertLangCode(code, from, to) { channels: [],
let found = langs.where(from, code) programs: [],
date: CURR_DATE
return found ? found[to] : null
} }
function getChannelPrograms(programs) { for (let programData of programs) {
let sites = _.groupBy(programs, 'site') let channelData = api_channels[programData.channel]
channelData.site = programData.site
channelData.lang = programData.titles[0].lang
let topScore = 0 let channel = new Channel(channelData)
let selected let program = new Program(programData, channel)
for (let site in sites) {
let sitePrograms = sites[site]
let siteScore = _.sumBy(sitePrograms, 'score')
if (siteScore > topScore) { output.channels.push(channel)
selected = site output.programs.push(program)
topScore = siteScore
}
} }
return sites[selected] || [] output.channels = _.sortBy(output.channels, 'id')
output.channels = _.uniqBy(output.channels, 'id')
output.programs = _.sortBy(output.programs, ['channel', 'start'])
output.programs = _.uniqBy(output.programs, p => p.channel + p.start)
const xmlFilepath = `${PUBLIC_DIR}/guides/${filepath}.xml`
const gzFilepath = `${PUBLIC_DIR}/guides/${filepath}.xml.gz`
const jsonFilepath = `${PUBLIC_DIR}/guides/${filepath}.json`
logger.info(`creating ${xmlFilepath}...`)
const xmltv = generateXMLTV(output)
await file.create(xmlFilepath, xmltv)
logger.info(`creating ${gzFilepath}...`)
const compressed = await zip.compress(xmltv)
await file.create(gzFilepath, compressed)
logger.info(`creating ${jsonFilepath}...`)
await file.create(jsonFilepath, JSON.stringify(output))
return output
} }
function calcScore(program) { // function merge(p1, p2) {
let score = 0 // for (let prop in p1) {
let values = Object.values(program) // if (Array.isArray(p1[prop])) {
for (let value of values) { // p1[prop] = _.orderBy(
if (Array.isArray(value) && value.length) { // _.uniqWith(p1[prop].concat(p2[prop]), _.isEqual),
score++ // v => (v.lang === 'en' ? Infinity : 1),
} else if (typeof value === 'string' && value) { // 'desc'
score++ // )
} else if (value && typeof value === 'object' && Object.values(value).map(Boolean).length) { // }
score++ // }
}
}
return score // return p1
} // }
async function makeReport() {
const errors = []
let programs = _.uniqBy(db_programs, p => p.site + p.channel)
for (let program of programs) {
if (!guides.find(g => g.channel === program.channel)) {
const channel = await api.channels.find({ id: program.channel })
errors.push({ type: 'no_guide', ...program, ...channel })
}
}
console.log()
logger.info(`report:`)
console.table(errors, ['type', 'site', 'lang', 'channel', 'broadcast_area', 'languages'])
logger.error(`found ${errors.length} error(s)`)
}

View file

@ -9,11 +9,11 @@ const options = program
parser.parseNumber, parser.parseNumber,
256 256
) )
.option('--days <days>', 'Number of days for which to grab the program', parser.parseNumber, 1)
.parse(process.argv) .parse(process.argv)
.opts() .opts()
const CHANNELS_PATH = process.env.CHANNELS_PATH || 'sites/**/*.channels.xml' const CHANNELS_PATH = process.env.CHANNELS_PATH || 'sites/**/*.channels.xml'
const CURR_DATE = process.env.CURR_DATE || new Date()
async function main() { async function main() {
logger.info('Starting...') logger.info('Starting...')
@ -33,8 +33,7 @@ async function createQueue() {
await api.channels.load().catch(console.error) await api.channels.load().catch(console.error)
const files = await file.list(CHANNELS_PATH).catch(console.error) const files = await file.list(CHANNELS_PATH).catch(console.error)
const utcDate = date.getUTC() const utcDate = date.getUTC(CURR_DATE)
const dates = Array.from({ length: options.days }, (_, i) => utcDate.add(i, 'd'))
for (const filepath of files) { for (const filepath of files) {
try { try {
const dir = file.dirname(filepath) const dir = file.dirname(filepath)
@ -44,6 +43,8 @@ async function createQueue() {
const config = require(file.resolve(configPath)) const config = require(file.resolve(configPath))
if (config.skip) continue if (config.skip) continue
const filename = file.basename(filepath) const filename = file.basename(filepath)
const days = config.days || 1
const dates = Array.from({ length: days }, (_, i) => utcDate.add(i, 'd'))
for (const channel of channels) { for (const channel of channels) {
if (!channel.site || !channel.id) continue if (!channel.site || !channel.id) continue
const found = api.channels.find({ id: channel.id }) const found = api.channels.find({ id: channel.id })

View file

@ -1,5 +1,6 @@
const { file, markdown, parser, logger, api, table } = require('../../core') const { file, markdown, parser, logger, api, table } = require('../../core')
const { program } = require('commander') const { program } = require('commander')
const langs = require('langs')
const _ = require('lodash') const _ = require('lodash')
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs' const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
@ -12,55 +13,70 @@ const options = program
async function main() { async function main() {
await api.countries.load().catch(console.error) await api.countries.load().catch(console.error)
const logPath = `${LOGS_DIR}/guides/update.log` const logPath = `${LOGS_DIR}/guides/update.log`
let results = await parser.parseLogs(logPath) let log = await parser.parseLogs(logPath)
let files = results.reduce((acc, curr) => {
if (acc[curr.filename]) {
acc[curr.filename].channels++
} else {
acc[curr.filename] = {
country: curr.country,
channels: 1,
filename: curr.filename
}
}
return acc await createTable(log)
}, {})
let data = []
for (const filename in files) {
const item = files[filename]
const country = api.countries.find({ code: item.country })
if (!country) continue
data.push([
country.name,
`${country.flag}&nbsp;${country.name}`,
item.channels,
`<code>https://iptv-org.github.io/epg/guides/${filename}.xml</code>`
])
}
data = _.orderBy(
data,
[item => item[0], item => (item[3].includes('_en') ? Infinity : item[2])],
['asc', 'desc']
)
data = data.map(i => {
i.shift()
return i
})
data = Object.values(_.groupBy(data, item => item[0]))
const output = table.create(data, ['Country', 'Channels', 'EPG'])
await file.create('./.readme/_countries.md', output)
await updateReadme() await updateReadme()
} }
main() main()
async function createTable(log) {
let files = log.reduce((acc, curr) => {
if (!acc[curr.filename]) {
acc[curr.filename] = {
site: curr.site,
lang: curr.lang,
channels: 0,
filename: curr.filename
}
}
acc[curr.filename].channels++
return acc
}, {})
let groups = {}
for (const filename in files) {
const item = files[filename]
const lang = langs.where('1', item.lang)
if (!lang) continue
if (!groups[lang.name]) groups[lang.name] = { lang: lang.name, data: [] }
groups[lang.name].data.push([
`<a href="https://${item.site}">${item.site}</a>`,
item.channels,
`<code>https://iptv-org.github.io/epg/guides/${filename}.xml</code>`,
`<a href="https://github.com/iptv-org/epg/actions/workflows/${item.site}.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/${item.site}.yml/badge.svg" alt="${item.site}" style="max-width: 100%;"></a>`
])
}
groups = _.sortBy(Object.values(groups), 'lang')
let guides = ''
for (let group of groups) {
let lang = group.lang
let data = group.data
data = _.orderBy(data, [item => item[0], item => item[1]], ['asc', 'desc'])
data = Object.values(_.groupBy(data, item => item[0]))
guides += `### ${lang}\r\n\r\n`
guides += table.create(data, [
'Site',
'Channels',
'EPG',
'Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
])
guides += `\r\n\r\n`
}
await file.create('./.readme/_guides.md', guides)
}
async function updateReadme() { async function updateReadme() {
logger.info('updating readme.md...') logger.info('updating readme.md...')

View file

@ -1,52 +0,0 @@
const { file, markdown, logger, table } = require('../../core')
const { program } = require('commander')
const _ = require('lodash')
const CONFIGS_PATH = process.env.CONFIGS_PATH || 'sites/**/*.config.js'
const options = program
.option('-c, --config <config>', 'Set path to config file', '.readme/status.json')
.parse(process.argv)
.opts()
async function main() {
let data = []
const files = await file.list(CONFIGS_PATH).catch(console.error)
for (const filepath of files) {
try {
const { site, skip } = require(file.resolve(filepath))
if (skip) continue
data.push([
site,
`<a href="https://github.com/iptv-org/epg/actions/workflows/${site}.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/${site}.yml/badge.svg" alt="${site}" style="max-width: 100%;"></a>`
])
} catch (err) {
console.error(err)
continue
}
}
data = Object.values(_.groupBy(data, item => item[0]))
const output = table.create(data, [
'Site',
'Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
])
await file.create('./.readme/_sites.md', output)
await updateMarkdown()
}
main()
async function updateMarkdown() {
logger.info('updating status.md...')
const config = require(file.resolve(options.config))
await file.createDir(file.dirname(config.build))
await markdown.compile(options.config)
}

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: '9tv.co.il', site: '9tv.co.il',
days: 2,
url: function ({ date }) { url: function ({ date }) {
return `https://www.9tv.co.il/BroadcastSchedule/getBrodcastSchedule?date=${date.format( return `https://www.9tv.co.il/BroadcastSchedule/getBrodcastSchedule?date=${date.format(
'DD/MM/YYYY 00:00:00' 'DD/MM/YYYY 00:00:00'

View file

@ -9,6 +9,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'abc.net.au', site: 'abc.net.au',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -3,6 +3,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'allente.se', site: 'allente.se',
days: 2,
url({ date, channel }) { url({ date, channel }) {
const [country] = channel.site_id.split('#') const [country] = channel.site_id.split('#')

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'andorradifusio.ad', site: 'andorradifusio.ad',
days: 2,
url({ channel }) { url({ channel }) {
return `https://www.andorradifusio.ad/programacio/${channel.site_id}` return `https://www.andorradifusio.ad/programacio/${channel.site_id}`
}, },

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'arianaafgtv.com', site: 'arianaafgtv.com',
days: 2,
url() { url() {
return `https://www.arianaafgtv.com/index.html` return `https://www.arianaafgtv.com/index.html`
}, },

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'arianatelevision.com', site: 'arianatelevision.com',
days: 2,
url: `https://www.arianatelevision.com/program-schedule/`, url: `https://www.arianatelevision.com/program-schedule/`,
parser({ content, date }) { parser({ content, date }) {
const programs = [] const programs = []

View file

@ -9,6 +9,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'artonline.tv', site: 'artonline.tv',
days: 2,
url: function ({ channel }) { url: function ({ channel }) {
return `https://www.artonline.tv/Home/Tvlist${channel.site_id}` return `https://www.artonline.tv/Home/Tvlist${channel.site_id}`
}, },

View file

@ -8,6 +8,7 @@ const API_ENDPOINT = `https://contenthub-api.eco.astro.com.my`
module.exports = { module.exports = {
site: 'astro.com.my', site: 'astro.com.my',
days: 2,
url: function ({ channel }) { url: function ({ channel }) {
return `${API_ENDPOINT}/channel/${channel.site_id}.json` return `${API_ENDPOINT}/channel/${channel.site_id}.json`
}, },

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'bein.com', site: 'bein.com',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const [index] = channel.site_id.split('#') const [index] = channel.site_id.split('#')

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'beinsports.com', site: 'beinsports.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000, // 1h ttl: 60 * 60 * 1000, // 1h

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'bt.com', site: 'bt.com',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://voila.metabroadcast.com/4/schedules/${ return `https://voila.metabroadcast.com/4/schedules/${
channel.site_id channel.site_id

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'cablego.com.pe', site: 'cablego.com.pe',
days: 2,
request: { request: {
method: 'POST', method: 'POST',
headers: { headers: {

View file

@ -7,6 +7,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'canalplus-afrique.com', site: 'canalplus-afrique.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')

View file

@ -7,6 +7,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'canalplus-caraibes.com', site: 'canalplus-caraibes.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')

View file

@ -7,6 +7,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'canalplus-haiti.com', site: 'canalplus-haiti.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')

View file

@ -6,6 +6,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'canalplus-reunion.com', site: 'canalplus-reunion.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')

View file

@ -9,6 +9,7 @@ const API_KEY = 'da2291af3b10e9900d1c55e1a65d3388' // 10.2022
module.exports = { module.exports = {
site: 'canalplus.com', site: 'canalplus.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'cgates.lt', site: 'cgates.lt',
days: 2,
url: function ({ channel }) { url: function ({ channel }) {
return `https://www.cgates.lt/tv-kanalai/${channel.site_id}/` return `https://www.cgates.lt/tv-kanalai/${channel.site_id}/`
}, },

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'chaines-tv.orange.fr', site: 'chaines-tv.orange.fr',
days: 2,
url({ channel, date }) { url({ channel, date }) {
return `https://rp-ott-mediation-tv.woopic.com/api-gw/live/v3/applications/STB4PC/programs?groupBy=channel&includeEmptyChannels=false&period=${date.valueOf()},${date return `https://rp-ott-mediation-tv.woopic.com/api-gw/live/v3/applications/STB4PC/programs?groupBy=channel&includeEmptyChannels=false&period=${date.valueOf()},${date
.add(1, 'd') .add(1, 'd')

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'clickthecity.com', site: 'clickthecity.com',
days: 2,
url({ channel }) { url({ channel }) {
return `https://www.clickthecity.com/tv/network/${channel.site_id}` return `https://www.clickthecity.com/tv/network/${channel.site_id}`
}, },

View file

@ -2,6 +2,7 @@ const parser = require('epg-parser')
module.exports = { module.exports = {
site: 'compulms.com', site: 'compulms.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'comteco.com.bo', site: 'comteco.com.bo',
days: 2,
url: function ({ channel }) { url: function ({ channel }) {
return `https://comteco.com.bo/pages/canales-y-programacion-tv/paquete-oro/${channel.site_id}` return `https://comteco.com.bo/pages/canales-y-programacion-tv/paquete-oro/${channel.site_id}`
}, },

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'cosmote.gr', site: 'cosmote.gr',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://www.cosmote.gr/cosmotetv/residential/program/epg/programchannel?p_p_id=channelprogram_WAR_OTETVportlet&p_p_lifecycle=0&_channelprogram_WAR_OTETVportlet_platform=IPTV&_channelprogram_WAR_OTETVportlet_date=${date.format( return `https://www.cosmote.gr/cosmotetv/residential/program/epg/programchannel?p_p_id=channelprogram_WAR_OTETVportlet&p_p_lifecycle=0&_channelprogram_WAR_OTETVportlet_platform=IPTV&_channelprogram_WAR_OTETVportlet_date=${date.format(
'DD-MM-YYYY' 'DD-MM-YYYY'

View file

@ -3,6 +3,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'delta.nl', site: 'delta.nl',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://clientapi.tv.delta.nl/guide/channels/list?start=${date.unix()}&end=${date return `https://clientapi.tv.delta.nl/guide/channels/list?start=${date.unix()}&end=${date
.add(1, 'd') .add(1, 'd')

View file

@ -8,6 +8,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'digiturk.com.tr', site: 'digiturk.com.tr',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://www.digiturk.com.tr/yayin-akisi/api/program/kanal/${ return `https://www.digiturk.com.tr/yayin-akisi/api/program/kanal/${
channel.site_id channel.site_id

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'directv.com.ar', site: 'directv.com.ar',
days: 2,
url: `https://www.directv.com.ar/guia/ChannelDetail.aspx/GetProgramming`, url: `https://www.directv.com.ar/guia/ChannelDetail.aspx/GetProgramming`,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'directv.com.uy', site: 'directv.com.uy',
days: 2,
url: `https://www.directv.com.uy/guia/ChannelDetail.aspx/GetProgramming`, url: `https://www.directv.com.uy/guia/ChannelDetail.aspx/GetProgramming`,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -8,6 +8,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'directv.com', site: 'directv.com',
days: 2,
url({ channel, date }) { url({ channel, date }) {
return `https://www.directv.com/json/channelschedule?channels=${ return `https://www.directv.com/json/channelschedule?channels=${
channel.site_id channel.site_id

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'dishtv.in', site: 'dishtv.in',
days: 2,
url: `https://www.dishtv.in/WhatsonIndiaWebService.asmx/LoadPagginResultDataForProgram`, url: `https://www.dishtv.in/WhatsonIndiaWebService.asmx/LoadPagginResultDataForProgram`,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -5,6 +5,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'dsmart.com.tr', site: 'dsmart.com.tr',
days: 2,
url({ date, channel }) { url({ date, channel }) {
return `https://www.dsmart.com.tr/api/v1/public/epg/schedules?page=1&limit=500&day=${date.format( return `https://www.dsmart.com.tr/api/v1/public/epg/schedules?page=1&limit=500&day=${date.format(
'YYYY-MM-DD' 'YYYY-MM-DD'

View file

@ -12,6 +12,7 @@ const API_ENDPOINT = 'https://www.dstv.com/umbraco/api/TvGuide'
module.exports = { module.exports = {
site: 'dstv.com', site: 'dstv.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 3 * 60 * 60 * 1000, // 3h ttl: 3 * 60 * 60 * 1000, // 3h

View file

@ -11,6 +11,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'elcinema.com', site: 'elcinema.com',
days: 2,
url({ channel }) { url({ channel }) {
const lang = channel.lang === 'en' ? 'en/' : '/' const lang = channel.lang === 'en' ? 'en/' : '/'

View file

@ -12,6 +12,7 @@ const API_ENDPOINT = 'http://epg.i-cable.com/ci/channel'
module.exports = { module.exports = {
site: 'epg.i-cable.com', site: 'epg.i-cable.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1h ttl: 60 * 60 * 1000 // 1h

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'foxsports.com.au', site: 'foxsports.com.au',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -5,6 +5,7 @@ const cheerio = require('cheerio')
module.exports = { module.exports = {
skip: true, // returns "Access Denied" or nothing skip: true, // returns "Access Denied" or nothing
site: 'foxtel.com.au', site: 'foxtel.com.au',
days: 2,
url({ channel, date }) { url({ channel, date }) {
return `https://www.foxtel.com.au/tv-guide/channel/${channel.site_id}/${date.format( return `https://www.foxtel.com.au/tv-guide/channel/${channel.site_id}/${date.format(
'YYYY/MM/DD' 'YYYY/MM/DD'

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'frikanalen.no', site: 'frikanalen.no',
days: 2,
url({ date }) { url({ date }) {
return `https://frikanalen.no/api/scheduleitems/?date=${date.format( return `https://frikanalen.no/api/scheduleitems/?date=${date.format(
'YYYY-MM-DD' 'YYYY-MM-DD'

View file

@ -9,6 +9,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'gatotv.com', site: 'gatotv.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://www.gatotv.com/canal/${channel.site_id}/${date.format('YYYY-MM-DD')}` return `https://www.gatotv.com/canal/${channel.site_id}/${date.format('YYYY-MM-DD')}`
}, },

View file

@ -13,6 +13,7 @@ dayjs.extend(isoWeek)
module.exports = { module.exports = {
site: 'getafteritmedia.com', site: 'getafteritmedia.com',
days: 2,
url: 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQcDmb9OnO0HpbjINfGaepqgGTp3VSmPs7hs654n3sRKrq4Q9y6uPSEvVvq9MwTLYG_n_V7vh0rFYP9/pubhtml', url: 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQcDmb9OnO0HpbjINfGaepqgGTp3VSmPs7hs654n3sRKrq4Q9y6uPSEvVvq9MwTLYG_n_V7vh0rFYP9/pubhtml',
parser({ content, channel, date }) { parser({ content, channel, date }) {
const programs = [] const programs = []

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'guidatv.sky.it', site: 'guidatv.sky.it',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const [env, id] = channel.site_id.split('#') const [env, id] = channel.site_id.split('#')
return `https://apid.sky.it/gtv/v1/events?from=${date.format('YYYY-MM-DD')}T00:00:00Z&to=${date return `https://apid.sky.it/gtv/v1/events?from=${date.format('YYYY-MM-DD')}T00:00:00Z&to=${date

View file

@ -9,6 +9,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'guide.dstv.com', site: 'guide.dstv.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000, ttl: 60 * 60 * 1000,

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'hd-plus.de', site: 'hd-plus.de',
days: 2,
url({ date, channel }) { url({ date, channel }) {
const today = dayjs().utc().startOf('d') const today = dayjs().utc().startOf('d')
const day = date.diff(today, 'd') const day = date.diff(today, 'd')

View file

@ -5,6 +5,7 @@ const API_ENDPOINT = `https://legacy-static.oesp.horizon.tv/oesp/v4`
module.exports = { module.exports = {
site: 'horizon.tv', site: 'horizon.tv',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const [country, lang] = channel.site_id.split('#') const [country, lang] = channel.site_id.split('#')

View file

@ -11,6 +11,7 @@ const API_ENDPOINT = 'https://raw.githubusercontent.com/matthuisman/i.mjh.nz/mas
module.exports = { module.exports = {
site: 'i.mjh.nz', site: 'i.mjh.nz',
days: 2,
request: { request: {
cache: { cache: {
ttl: 3 * 60 * 60 * 1000 // 3h ttl: 3 * 60 * 60 * 1000 // 3h

View file

@ -9,6 +9,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'i24news.tv', site: 'i24news.tv',
days: 2,
url: function ({ channel }) { url: function ({ channel }) {
const [lang] = channel.site_id.split('#') const [lang] = channel.site_id.split('#')

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'ionplustv.com', site: 'ionplustv.com',
days: 2,
url({ date }) { url({ date }) {
return `https://ionplustv.com/schedule/${date.format('YYYY-MM-DD')}` return `https://ionplustv.com/schedule/${date.format('YYYY-MM-DD')}`
}, },

View file

@ -5,6 +5,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'ipko.com', site: 'ipko.com',
days: 2,
url: function ({ date }) { url: function ({ date }) {
return `https://www.ipko.com/epg/admin/programs.php?date=${date.format('YYYY-MM-DD')}` return `https://www.ipko.com/epg/admin/programs.php?date=${date.format('YYYY-MM-DD')}`
}, },

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
skip: true, // INFO: Request failed with status code 403 (Access denied) skip: true, // INFO: Request failed with status code 403 (Access denied)
site: 'kan.org.il', site: 'kan.org.il',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://www.kan.org.il/tv-guide/tv_guidePrograms.ashx?stationID=${ return `https://www.kan.org.il/tv-guide/tv_guidePrograms.ashx?stationID=${
channel.site_id channel.site_id

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'knr.gl', site: 'knr.gl',
days: 2,
url({ date }) { url({ date }) {
return `https://knr.gl/admin/knr/TV/program/${date.format('YYYY-MM-DD')}/gl` return `https://knr.gl/admin/knr/TV/program/${date.format('YYYY-MM-DD')}/gl`
}, },

View file

@ -10,6 +10,7 @@ const API_ENDPOINT = `https://www.kplus.vn/Schedule/getSchedule`
module.exports = { module.exports = {
site: 'kplus.vn', site: 'kplus.vn',
days: 2,
skip: true, // channel list changes with each request skip: true, // channel list changes with each request
url: API_ENDPOINT, url: API_ENDPOINT,
request: { request: {

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'kvf.fo', site: 'kvf.fo',
days: 2,
url({ date }) { url({ date }) {
return `https://kvf.fo/nskra/sv?date=${date.format('YYYY-MM-DD')}` return `https://kvf.fo/nskra/sv?date=${date.format('YYYY-MM-DD')}`
}, },

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'm.tv.sms.cz', site: 'm.tv.sms.cz',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://m.tv.sms.cz/index.php?stanice=${channel.site_id}&cas=0&den=${date.format( return `https://m.tv.sms.cz/index.php?stanice=${channel.site_id}&cas=0&den=${date.format(
'YYYY-MM-DD' 'YYYY-MM-DD'

View file

@ -6,6 +6,7 @@ const API_PROD_ENDPOINT = 'https://prod.spark.magentatv.at/deu/web/linear-servic
module.exports = { module.exports = {
site: 'magentatv.at', site: 'magentatv.at',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -7,6 +7,7 @@ const COOKIE =
module.exports = { module.exports = {
site: 'magentatv.de', site: 'magentatv.de',
days: 2,
skip: true, // the site uses a constantly updated session ID skip: true, // the site uses a constantly updated session ID
url: `https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList`, url: `https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList`,
request: { request: {

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'magticom.ge', site: 'magticom.ge',
days: 2,
url: 'https://www.magticom.ge/request/channel-program.php', url: 'https://www.magticom.ge/request/channel-program.php',
request: { request: {
method: 'POST', method: 'POST',

View file

@ -9,6 +9,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mako.co.il', site: 'mako.co.il',
days: 2,
url: 'https://www.mako.co.il/AjaxPage?jspName=EPGResponse.jsp', url: 'https://www.mako.co.il/AjaxPage?jspName=EPGResponse.jsp',
parser: function ({ content, date }) { parser: function ({ content, date }) {
let programs = [] let programs = []

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'maxtv.hrvatskitelekom.hr', site: 'maxtv.hrvatskitelekom.hr',
days: 2,
url: 'https://player.maxtvtogo.tportal.hr:8082/OTT4Proxy/proxy/epg/shows', url: 'https://player.maxtvtogo.tportal.hr:8082/OTT4Proxy/proxy/epg/shows',
request: { request: {
method: 'POST', method: 'POST',

View file

@ -6,6 +6,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'maxtvgo.mk', site: 'maxtvgo.mk',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://prd-static-mkt.spectar.tv/rev-1636968171/client_api.php/epg/list/instance_id/1/language/mk/channel_id/${ return `https://prd-static-mkt.spectar.tv/rev-1636968171/client_api.php/epg/list/instance_id/1/language/mk/channel_id/${
channel.site_id channel.site_id

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'mbc.net', site: 'mbc.net',
days: 2,
skip: true, // NOTE: there is no program on the site skip: true, // NOTE: there is no program on the site
url({ date, channel }) { url({ date, channel }) {
return `https://www.mbc.net/.rest/api/channel/grids?from=${date.valueOf()}&to=${date return `https://www.mbc.net/.rest/api/channel/grids?from=${date.valueOf()}&to=${date

View file

@ -8,6 +8,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mediaklikk.hu', site: 'mediaklikk.hu',
days: 2,
url: 'https://mediaklikk.hu/wp-content/plugins/hms-global-widgets/widgets/programGuide/programGuideInterface.php', url: 'https://mediaklikk.hu/wp-content/plugins/hms-global-widgets/widgets/programGuide/programGuideInterface.php',
request: { request: {
method: 'POST', method: 'POST',

View file

@ -7,6 +7,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mediaset.it', site: 'mediaset.it',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `http://www.mediaset.it/guidatv/inc/canali/${date.format('YYYYMM')}/${date.format( return `http://www.mediaset.it/guidatv/inc/canali/${date.format('YYYYMM')}/${date.format(
'YYYYMMDD' 'YYYYMMDD'

View file

@ -3,6 +3,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'melita.com', site: 'melita.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://androme.melitacable.com/api/epg/v1/schedule/channel/${ return `https://androme.melitacable.com/api/epg/v1/schedule/channel/${
channel.site_id channel.site_id

View file

@ -9,6 +9,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'meo.pt', site: 'meo.pt',
days: 2,
url: `https://www.meo.pt/_layouts/15/Ptsi.Isites.GridTv/GridTvMng.asmx/getProgramsFromChannels`, url: `https://www.meo.pt/_layouts/15/Ptsi.Isites.GridTv/GridTvMng.asmx/getProgramsFromChannels`,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -2,6 +2,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'mewatch.sg', site: 'mewatch.sg',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://cdn.mewatch.sg/api/schedules?channels=${channel.site_id}&date=${date.format( return `https://cdn.mewatch.sg/api/schedules?channels=${channel.site_id}&date=${date.format(
'YYYY-MM-DD' 'YYYY-MM-DD'

View file

@ -8,6 +8,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mi.tv', site: 'mi.tv',
days: 2,
url({ date, channel }) { url({ date, channel }) {
const [country, id] = channel.site_id.split('#') const [country, id] = channel.site_id.split('#')

View file

@ -12,6 +12,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mncvision.id', site: 'mncvision.id',
days: 2,
url: 'https://mncvision.id/schedule/table', url: 'https://mncvision.id/schedule/table',
request: { request: {
method: 'POST', method: 'POST',

View file

@ -8,6 +8,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'movistarplus.es', site: 'movistarplus.es',
days: 2,
url: function ({ date }) { url: function ({ date }) {
return `https://www.movistarplus.es/programacion-tv/${date.format('YYYY-MM-DD')}?v=json` return `https://www.movistarplus.es/programacion-tv/${date.format('YYYY-MM-DD')}?v=json`
}, },

View file

@ -5,6 +5,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'mtel.ba', site: 'mtel.ba',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const [position] = channel.site_id.split('#') const [position] = channel.site_id.split('#')

View file

@ -7,6 +7,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'mts.rs', site: 'mts.rs',
days: 2,
url({ date, channel }) { url({ date, channel }) {
const [position] = channel.site_id.split('#') const [position] = channel.site_id.split('#')

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mujtvprogram.cz', site: 'mujtvprogram.cz',
days: 2,
url({ channel, date }) { url({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')
return `https://services.mujtvprogram.cz/tvprogram2services/services/tvprogrammelist_mobile.php?channel_cid=${channel.site_id}&day=${diff}` return `https://services.mujtvprogram.cz/tvprogram2services/services/tvprogrammelist_mobile.php?channel_cid=${channel.site_id}&day=${diff}`

View file

@ -9,6 +9,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'musor.tv', site: 'musor.tv',
days: 2,
url({ channel, date }) { url({ channel, date }) {
return dayjs.utc().isSame(date, 'd') return dayjs.utc().isSame(date, 'd')
? `https://musor.tv/mai/tvmusor/${channel.site_id}` ? `https://musor.tv/mai/tvmusor/${channel.site_id}`

View file

@ -8,6 +8,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'myafn.dodmedia.osd.mil', site: 'myafn.dodmedia.osd.mil',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'mysky.com.ph', site: 'mysky.com.ph',
days: 2,
url: 'https://skyepg.mysky.com.ph/Main/getEventsbyType', url: 'https://skyepg.mysky.com.ph/Main/getEventsbyType',
request: { request: {
cache: { cache: {

View file

@ -10,6 +10,7 @@ const API_ENDPOINT = 'https://content-api.mytvsuper.com/v1'
module.exports = { module.exports = {
site: 'mytvsuper.com', site: 'mytvsuper.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1h ttl: 60 * 60 * 1000 // 1h

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'novacyprus.com', site: 'novacyprus.com',
days: 2,
url({ channel, date }) { url({ channel, date }) {
return `https://www.novacyprus.com/api/v1/tvprogram/from/${date.format('YYYYMMDD')}/to/${date return `https://www.novacyprus.com/api/v1/tvprogram/from/${date.format('YYYYMMDD')}/to/${date
.add(1, 'd') .add(1, 'd')

View file

@ -9,6 +9,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'novasports.gr', site: 'novasports.gr',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://www.novasports.gr/wp-admin/admin-ajax.php?action=nova_get_template&template=tv-program/broadcast&dt=${date.format( return `https://www.novasports.gr/wp-admin/admin-ajax.php?action=nova_get_template&template=tv-program/broadcast&dt=${date.format(
'YYYY-MM-DD' 'YYYY-MM-DD'

View file

@ -7,6 +7,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'nowplayer.now.com', site: 'nowplayer.now.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') + 1 const diff = date.diff(dayjs.utc().startOf('d'), 'd') + 1

View file

@ -17,6 +17,7 @@ const tz = {
module.exports = { module.exports = {
site: 'ontvtonight.com', site: 'ontvtonight.com',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const [region, id] = channel.site_id.split('#') const [region, id] = channel.site_id.split('#')
let url = `https://www.ontvtonight.com` let url = `https://www.ontvtonight.com`

View file

@ -7,6 +7,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'osn.com', site: 'osn.com',
days: 2,
url: `https://www.osn.com/CMSPages/TVScheduleWebService.asmx/GetTVChannelsProgramTimeTable`, url: `https://www.osn.com/CMSPages/TVScheduleWebService.asmx/GetTVChannelsProgramTimeTable`,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -4,7 +4,8 @@ const isBetween = require('dayjs/plugin/isBetween')
dayjs.extend(isBetween) dayjs.extend(isBetween)
module.exports = { module.exports = {
site: 'pbsguam.org', // the program is only available Thursday through Sunday site: 'pbsguam.org',
days: 2, // the program is only available Thursday through Sunday
url: 'https://pbsguam.org/calendar/', url: 'https://pbsguam.org/calendar/',
parser: function ({ content, date }) { parser: function ({ content, date }) {
let programs = [] let programs = []

View file

@ -5,6 +5,7 @@ const API_ENDPOINT = 'https://epg.provider.plex.tv'
module.exports = { module.exports = {
site: 'plex.tv', site: 'plex.tv',
days: 2,
request: { request: {
headers: { headers: {
'x-plex-provider-version': '5.1' 'x-plex-provider-version': '5.1'

View file

@ -8,6 +8,7 @@ dayjs.extend(timezone)
module.exports = { module.exports = {
site: 'programacion-tv.elpais.com', site: 'programacion-tv.elpais.com',
days: 2,
request: { request: {
cache: { cache: {
ttl: 60 * 60 * 1000 // 1 hour ttl: 60 * 60 * 1000 // 1 hour

View file

@ -5,6 +5,7 @@ dayjs.extend(utc)
module.exports = { module.exports = {
site: 'programetv.ro', site: 'programetv.ro',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const daysOfWeek = { const daysOfWeek = {
0: 'duminica', 0: 'duminica',

View file

@ -12,6 +12,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'programme-tv.net', site: 'programme-tv.net',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
return `https://www.programme-tv.net/programme/chaine/${date.format('YYYY-MM-DD')}/programme-${ return `https://www.programme-tv.net/programme/chaine/${date.format('YYYY-MM-DD')}/programme-${
channel.site_id channel.site_id

View file

@ -5,6 +5,7 @@ const apiUrl = `https://programme-tv.vini.pf/programmesJSON`
module.exports = { module.exports = {
site: 'programme-tv.vini.pf', site: 'programme-tv.vini.pf',
days: 2,
url: apiUrl, url: apiUrl,
request: { request: {
method: 'POST', method: 'POST',

View file

@ -10,6 +10,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'programme.tvb.com', site: 'programme.tvb.com',
days: 2,
url: function ({ channel, date }) { url: function ({ channel, date }) {
return `https://programme.tvb.com/ajax.php?action=channellist&code=${ return `https://programme.tvb.com/ajax.php?action=channellist&code=${
channel.site_id channel.site_id

View file

@ -11,6 +11,7 @@ dayjs.extend(customParseFormat)
module.exports = { module.exports = {
delay: 5000, delay: 5000,
site: 'programtv.onet.pl', site: 'programtv.onet.pl',
days: 2,
url: function ({ date, channel }) { url: function ({ date, channel }) {
const currDate = dayjs.utc().startOf('d') const currDate = dayjs.utc().startOf('d')
const day = date.diff(currDate, 'd') const day = date.diff(currDate, 'd')

View file

@ -3,6 +3,7 @@ const dayjs = require('dayjs')
module.exports = { module.exports = {
site: 'proximusmwc.be', site: 'proximusmwc.be',
days: 2,
skip: true, // site is not working (https://github.com/iptv-org/epg/runs/5505070902?check_suite_focus=true) skip: true, // site is not working (https://github.com/iptv-org/epg/runs/5505070902?check_suite_focus=true)
url: 'https://api.proximusmwc.be/v2/graphql', url: 'https://api.proximusmwc.be/v2/graphql',
request: { request: {

Some files were not shown because too many files have changed in this diff Show more