Merge branch 'master' into add-mncvision-id

This commit is contained in:
Shadix A 2021-08-31 16:47:59 +02:00 committed by GitHub
commit a9dac08589
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 2351 additions and 464 deletions

View file

@ -18,7 +18,6 @@ jobs:
hd-plus.de,
astro.com.my,
comteco.com.bo,
albepg.com,
mi.tv,
meo.pt,
tvgid.ua,
@ -35,8 +34,9 @@ jobs:
tvtv.ca,
tvtv.us,
tv.lv,
vidio.com,
mncvision.id
mncvision.id,
tvguide.com,
tvprofil.com
]
steps:
- name: Checkout
@ -51,6 +51,7 @@ jobs:
name: .gh-pages
path: .gh-pages/guides/${{ matrix.site }}.guide.xml
deploy:
if: ${{ github.ref == 'refs/heads/master' }}
needs: grab
runs-on: ubuntu-latest
steps:
@ -58,6 +59,12 @@ jobs:
uses: actions/checkout@v2
- name: Download Artifacts
uses: actions/download-artifact@v2
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.1
with:
@ -65,3 +72,7 @@ jobs:
folder: .gh-pages
target-folder: guides
clean: false
token: ${{ steps.generate-token.outputs.token }}
git-config-name: iptv-bot
git-config-email: 84861620+iptv-bot[bot]@users.noreply.github.com
commit-message: '[Bot] Deploy to GitHub Pages'

View file

@ -4,11 +4,27 @@ on:
schedule:
- cron: '0 0 * * *'
jobs:
update:
create-branch:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Create Branch
uses: peterjgrainger/action-create-branch@v2.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
branch: 'bot/update-codes'
update-codes:
runs-on: ubuntu-latest
needs: create-branch
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: bot/update-codes
- name: Install Dependencies
run: npm install
- name: Update Codes
@ -18,16 +34,36 @@ jobs:
with:
name: codes.csv
path: codes.csv
commit-changes:
runs-on: ubuntu-latest
needs: update-codes
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: bot/update-codes
- name: Download Artifacts
uses: actions/download-artifact@v2
with:
name: codes.csv
- name: Commit Changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: '[Bot] Update codes'
commit_user_name: iptv-bot
commit_user_email: 84861620+iptv-bot[bot]@users.noreply.github.com
commit_author: 'iptv-bot[bot] <84861620+iptv-bot[bot]@users.noreply.github.com>'
branch: bot/update-codes
file_pattern: codes.csv
pull-request:
needs: update
if: ${{ github.ref == 'refs/heads/master' }}
needs: commit-changes
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download codes.csv
uses: actions/download-artifact@v2
with:
name: codes.csv
ref: bot/update-codes
- name: Generate Token
uses: tibdex/github-app-token@v1
id: generate-token
@ -36,26 +72,24 @@ jobs:
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Create Pull Request
id: pr
uses: peter-evans/create-pull-request@v3
uses: repo-sync/pull-request@v2
with:
title: '[Bot] Update codes'
body: |
This pull request is created automatically by `update-codes` action.
commit-message: '[Bot] Update codes'
committer: GitHub <noreply@github.com>
branch: bot/update-codes
delete-branch: true
token: ${{ steps.generate-token.outputs.token }}
source_branch: 'bot/update-codes'
destination_branch: 'master'
pr_title: '[Bot] Update codes'
pr_body: |
This pull request is created by [update-codes][1] workflow.
[1]: https://github.com/iptv-org/iptv/actions/runs/${{ github.run_id }}
github_token: ${{ steps.generate-token.outputs.token }}
- name: Enable Pull Request Automerge
if: steps.pr.outputs.pull-request-operation == 'created'
uses: peter-evans/enable-pull-request-automerge@v1
with:
token: ${{ secrets.PAT }}
pull-request-number: ${{ steps.pr.outputs.pull-request-number }}
pull-request-number: ${{ steps.pr.outputs.pr_number }}
merge-method: squash
- name: Approve Pull Request
if: steps.pr.outputs.pull-request-operation == 'created'
uses: juliangruber/approve-pull-request-action@v1
with:
github-token: ${{ secrets.PAT }}
number: ${{ steps.pr.outputs.pull-request-number }}
number: ${{ steps.pr.outputs.pr_number }}

View file

@ -14,16 +14,19 @@ To load a program guide, all you need to do is copy the link to one of the guide
<tr><th align="left">Country</th><th align="left">EPG</th></tr>
</thead>
<tbody>
<tr><td align="left" nowrap>🇦🇱 Albania</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/albepg.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇦🇱 Albania</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇦🇩 Andorra</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/andorradifusio.ad.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇦🇷 Argentina</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇦🇺 Australia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/ontvtonight.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇧🇾 Belarus</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tv.yandex.ru.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇧🇴 Bolivia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/comteco.com.bo.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇧🇦 Bosnia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇧🇷 Brasil</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇧🇬 Bulgaria</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇨🇦 Canada</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvtv.ca.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇨🇱 Chile</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇨🇴 Colombia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇭🇷 Croatia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇨🇿 Czechia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/m.tv.sms.cz.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇸🇻 El Salvador</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇫🇮 Finland</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/telkussa.fi.guide.xml</code></td></tr>
@ -33,18 +36,23 @@ To load a program guide, all you need to do is copy the link to one of the guide
<tr><td align="left" nowrap>🇬🇹 Guatemala</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇭🇳 Honduras</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇮🇩 Indonesia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mncvision.id.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇭🇺 Hungary</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇮🇹 Italy</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/guidatv.sky.it.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇮🇪 Ireland</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/ontvtonight.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇰🇿 Kazakhstan</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tv.yandex.ru.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇱🇻 Latvia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tv.lv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇲🇾 Malaysia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/astro.com.my.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇲🇽 Mexico</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇲🇪 Montenegro</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇲🇰 North Macedonia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇵🇾 Paraguay</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇵🇪 Peru</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/mi.tv.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇵🇱 Poland</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/programtv.onet.pl.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇵🇹 Portugal</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/meo.pt.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇷🇴 Romania</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/programetv.ro.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇷🇺 Russia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tv.yandex.ru.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇷🇸 Serbia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇸🇮 Slovenia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇪🇸 Spain</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/programacion-tv.elpais.com.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇸🇪 Sweden</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/telkussa.fi.guide.xml</code></td></tr>
<tr><td align="left" nowrap>🇹🇷 Turkey</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/digiturk.com.tr.guide.xml</code></td></tr>

View file

@ -858,6 +858,7 @@ beIN Sports 11,beINSports11.qa
beIN Sports 12,beINSports12.qa
beIN Sports 13,beINSports13.qa
beIN Sports 2,beINSports2.qa
beIN Sports 2 Asia,beINSports2Asia.qa
beIN Sports 3,beINSports3.qa
beIN Sports Canada,beINSportsCanada.qa
beIN Sports en Español,beINSportsenEspanol.qa

1 Channel Name EPG Code (tvg-id)
858 beIN Sports 12 beINSports12.qa
859 beIN Sports 13 beINSports13.qa
860 beIN Sports 2 beINSports2.qa
861 beIN Sports 2 Asia beINSports2Asia.qa
862 beIN Sports 3 beINSports3.qa
863 beIN Sports Canada beINSportsCanada.qa
864 beIN Sports en Español beINSportsenEspanol.qa

266
package-lock.json generated
View file

@ -6,10 +6,11 @@
"": {
"license": "MIT",
"dependencies": {
"form-data": "^4.0.0",
"cheerio": "^1.0.0-rc.10",
"dayjs": "^1.10.4",
"epg-grabber": "^0.6.6",
"epg-parser": "^0.1.3",
"form-data": "^4.0.0",
"glob": "^7.1.6",
"html-to-text": "^7.0.0",
"iconv-lite": "^0.4.24",
@ -140,6 +141,11 @@
"tweetnacl": "^0.14.3"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -159,6 +165,41 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"node_modules/cheerio": {
"version": "1.0.0-rc.10",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
"dependencies": {
"cheerio-select": "^1.5.0",
"dom-serializer": "^1.3.2",
"domhandler": "^4.2.0",
"htmlparser2": "^6.1.0",
"parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1",
"tslib": "^2.2.0"
},
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
}
},
"node_modules/cheerio-select": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
"integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
"dependencies": {
"css-select": "^4.1.3",
"css-what": "^5.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0",
"domutils": "^2.7.0"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -188,6 +229,32 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"node_modules/css-select": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
"integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^5.0.0",
"domhandler": "^4.2.0",
"domutils": "^2.6.0",
"nth-check": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-what": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
"integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/cssom": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
@ -265,19 +332,28 @@
}
},
"node_modules/dom-serializer": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz",
"integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
"integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w=="
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domexception": {
"version": "2.0.1",
@ -299,24 +375,31 @@
}
},
"node_modules/domhandler": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
"integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz",
"integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==",
"dependencies": {
"domelementtype": "^2.1.0"
"domelementtype": "^2.2.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.0.tgz",
"integrity": "sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz",
"integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==",
"dependencies": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0"
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/ecc-jsbn": {
@ -554,13 +637,20 @@
}
},
"node_modules/htmlparser2": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.1.tgz",
"integrity": "sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.4.4",
"domutils": "^2.5.2",
"entities": "^2.0.0"
}
},
@ -758,6 +848,17 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"node_modules/nth-check": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"dependencies": {
"boolbase": "^1.0.0"
},
"funding": {
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/nwsapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@ -805,6 +906,14 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
"dependencies": {
"parse5": "^6.0.1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@ -933,7 +1042,6 @@
"engines": {
"node": ">= 0.12"
}
},
"node_modules/request/node_modules/tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@ -1037,6 +1145,11 @@
"node": ">=8"
}
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@ -1298,6 +1411,11 @@
"tweetnacl": "^0.14.3"
}
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -1317,6 +1435,32 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"cheerio": {
"version": "1.0.0-rc.10",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
"requires": {
"cheerio-select": "^1.5.0",
"dom-serializer": "^1.3.2",
"domhandler": "^4.2.0",
"htmlparser2": "^6.1.0",
"parse5": "^6.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1",
"tslib": "^2.2.0"
}
},
"cheerio-select": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
"integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
"requires": {
"css-select": "^4.1.3",
"css-what": "^5.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0",
"domutils": "^2.7.0"
}
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -1340,6 +1484,23 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"css-select": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
"integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^5.0.0",
"domhandler": "^4.2.0",
"domutils": "^2.6.0",
"nth-check": "^2.0.0"
}
},
"css-what": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
"integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg=="
},
"cssom": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
@ -1404,19 +1565,19 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"dom-serializer": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz",
"integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
}
},
"domelementtype": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
"integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w=="
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
},
"domexception": {
"version": "2.0.1",
@ -1434,21 +1595,21 @@
}
},
"domhandler": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
"integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz",
"integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==",
"requires": {
"domelementtype": "^2.1.0"
"domelementtype": "^2.2.0"
}
},
"domutils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.0.tgz",
"integrity": "sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz",
"integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==",
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0"
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
},
"ecc-jsbn": {
@ -1625,13 +1786,13 @@
}
},
"htmlparser2": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.1.tgz",
"integrity": "sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.4.4",
"domutils": "^2.5.2",
"entities": "^2.0.0"
}
},
@ -1801,6 +1962,14 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"nth-check": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"requires": {
"boolbase": "^1.0.0"
}
},
"nwsapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@ -1842,6 +2011,14 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
"requires": {
"parse5": "^6.0.1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@ -2027,6 +2204,11 @@
"punycode": "^2.1.1"
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",

View file

@ -7,6 +7,7 @@
"author": "Arhey",
"license": "MIT",
"dependencies": {
"cheerio": "^1.0.0-rc.10",
"dayjs": "^1.10.4",
"epg-grabber": "^0.6.6",
"epg-parser": "^0.1.3",

View file

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<site site="albepg.com">
<channels>
<channel site_id="21 Junior" xmltv_id="21Junior.rs">21 Junior</channel>
<channel site_id="21 Popullore" xmltv_id="21Popullore.rs">21 Popullore</channel>
<channel site_id="24 Kitchen" xmltv_id="24KitchenSrbija.us">24 Kitchen Srbija</channel>
<channel site_id="3 Plus" xmltv_id="3Plus.al">3 Plus</channel>
<channel site_id="ABC News" xmltv_id="ABCNews.al">ABC News</channel>
<channel site_id="ALBUK TV" xmltv_id="AlbUKTV.uk">AlbUK TV</channel>
<channel site_id="Alsat-M" xmltv_id="Alsat.mk">Alsat</channel>
<channel site_id="Animal Planet" xmltv_id="AnimalPlanetEurope.us">Animal Planet Europe</channel>
<channel site_id="Arena Sport 1" xmltv_id="ArenaSport1.rs">Arena Sport 1</channel>
<channel site_id="Arena Sport 2" xmltv_id="ArenaSport2.rs">Arena Sport 2</channel>
<channel site_id="Arena Sport 3" xmltv_id="ArenaSport3.rs">Arena Sport 3</channel>
<channel site_id="Arena Sport 4" xmltv_id="ArenaSport4.rs">Arena Sport 4</channel>
<channel site_id="Arta HD" xmltv_id="Arta.rs">Arta</channel>
<channel site_id="BBF" xmltv_id="BBFMusicTV.al">BBF Music TV</channel>
<channel site_id="Baby TV" xmltv_id="BabyTVEurope.uk">BabyTV Europe</channel>
<channel site_id="Balkanika" xmltv_id="BalkanikaTV.bg">Balkanika TV</channel>
<channel site_id="Bang Bang" xmltv_id="BangBang.al">Bang Bang</channel>
<channel site_id="Boomerang" xmltv_id="BoomerangEMEA.us">Boomerang EMEA</channel>
<channel site_id="Click TV" xmltv_id="ClickTV.al">Click TV</channel>
<channel site_id="Discovery Channel" xmltv_id="DiscoveryChannelBulgaria.us">Discovery Channel Bulgaria</channel>
<channel site_id="Elrodi TV" xmltv_id="ElrodiTV.al">Elrodi TV</channel>
<channel site_id="EuroNews Albania" xmltv_id="EuronewsAlbania.fr">Euronews Albania</channel>
<channel site_id="EuroSport" xmltv_id="Eurosport1.fr">Eurosport 1</channel>
<channel site_id="EXPLORER Histori" xmltv_id="ExplorerHistori.al">Explorer Histori</channel>
<channel site_id="EXPLORER Natyra" xmltv_id="ExplorerNatyra.al">Explorer Natyra</channel>
<channel site_id="EXPLORER Shkence" xmltv_id="ExplorerShkence.al">Explorer Shkencë</channel>
<channel site_id="Family HD" xmltv_id="FamilyHD.al">Family HD</channel>
<channel site_id="Fashion TV" xmltv_id="FashionTVEurope.fr">FashionTV Europe</channel>
<channel site_id="Film Aksion" xmltv_id="FilmAksion.al">Film Aksion</channel>
<channel site_id="Film Drame" xmltv_id="FilmDrame.al">Film Drame</channel>
<channel site_id="Film Dy HD" xmltv_id="FilmDyHD.al">Film Dy HD</channel>
<channel site_id="Film Hits" xmltv_id="FilmHits.al">Film Hits</channel>
<channel site_id="Film Hits+1" xmltv_id="FilmHitsPlus1.al">Film Hits +1</channel>
<channel site_id="Film Komedi" xmltv_id="FilmKomedi.al">Film Komedi</channel>
<channel site_id="Film Nje HD" xmltv_id="FilmNjeHD.al">Film Një HD</channel>
<channel site_id="Film Thriller" xmltv_id="FilmThriller.al">Film Thriller</channel>
<channel site_id="Folk Plus" xmltv_id="FolkPlus.al">Folk+</channel>
<channel site_id="FOX Life" xmltv_id="FoxLifeRegional.us">Fox Life Regional</channel>
<channel site_id="FOX" xmltv_id="FoxSrbija.us">Fox Srbija</channel>
<channel site_id="INTV" xmltv_id="InTV.al">In TV</channel>
<channel site_id="ID Xtra HD" xmltv_id="InvestigationDiscoveryEurope.us">Investigation Discovery Europe</channel>
<channel site_id="Junior" xmltv_id="JuniorTV.al">Junior TV</channel>
<channel site_id="Kanal 10" xmltv_id="Kanal10.rs">Kanal 10</channel>
<channel site_id="KanalD Drama" xmltv_id="KanalDDrama.tr">Kanal D Drama</channel>
<channel site_id="Kanali 7" xmltv_id="Kanali7.al">Kanali 7</channel>
<channel site_id="Klan Kosova" xmltv_id="KlanKosova.al">Klan Kosova</channel>
<channel site_id="Klan Macedonia" xmltv_id="KlanMacedonia.al">Klan Macedonia</channel>
<channel site_id="Klan Plus" xmltv_id="KlanPlus.al">Klan Plus</channel>
<channel site_id="KTV" xmltv_id="Kohavision.rs">Kohavision</channel>
<channel site_id="Living HD" xmltv_id="LivingHD.al">Living HD</channel>
<channel site_id="MFM" xmltv_id="MFM.al">MFM</channel>
<channel site_id="MTV Live HD" xmltv_id="MTVLiveHD.us">MTV Live HD</channel>
<channel site_id="Muse" xmltv_id="Muse.al">Muse</channel>
<channel site_id="My Music" xmltv_id="MyMusic.al">My Music</channel>
<channel site_id="National Geographic" xmltv_id="NationalGeographicChannelHDEurope.us">National Geographic Channel HD Europe</channel>
<channel site_id="Neser TV" xmltv_id="NeserTV.al">Nesër TV</channel>
<channel site_id="News 24" xmltv_id="News24.al">News 24</channel>
<channel site_id="On-TV" xmltv_id="OnTV.al">On-TV</channel>
<channel site_id="Ora News" xmltv_id="OraNews.al">Ora News</channel>
<channel site_id="Peace TV" xmltv_id="PeaceTVEnglish.ae">Peace TV English</channel>
<channel site_id="RTSH1 HD" xmltv_id="RTSH1.al">RTSH 1</channel>
<channel site_id="RTSH2 HD" xmltv_id="RTSH2.al">RTSH 2</channel>
<channel site_id="RTSH3 HD" xmltv_id="RTSH3.al">RTSH 3</channel>
<channel site_id="RTSH Agro" xmltv_id="RTSHAgro.al">RTSH Agro</channel>
<channel site_id="RTSH Femije" xmltv_id="RTSHFemije.al">RTSH Femije</channel>
<channel site_id="RTSH Film" xmltv_id="RTSHFilm.al">RTSH Film</channel>
<channel site_id="RTSH Korca" xmltv_id="RTSHKorca.al">RTSH Korca</channel>
<channel site_id="RTSH Muzike" xmltv_id="RTSHMuzike.al">RTSH Muzikë</channel>
<channel site_id="RTSH Plus" xmltv_id="RTSHPlus.al">RTSH Plus</channel>
<channel site_id="RTSH Shkolle" xmltv_id="RTSHShkolle.al">RTSH Shkolle</channel>
<channel site_id="RTSH Shqip" xmltv_id="RTSHShqip.al">RTSH Shqip</channel>
<channel site_id="RTSH Sport" xmltv_id="RTSHSport.al">RTSH Sport</channel>
<channel site_id="RTV 21" xmltv_id="RTV21.rs">RTV21</channel>
<channel site_id="STV Folk" xmltv_id="STVFolk.al">STV Folk</channel>
<channel site_id="Stinet" xmltv_id="Stinet.al">Stinët</channel>
<channel site_id="SuperSonic TV" xmltv_id="SuperSonicTV.al">Super Sonic TV</channel>
<channel site_id="SuperSport 1" xmltv_id="SuperSport1.al">SuperSport 1</channel>
<channel site_id="SuperSport 2" xmltv_id="SuperSport2.al">SuperSport 2</channel>
<channel site_id="SuperSport 3" xmltv_id="SuperSport3.al">SuperSport 3</channel>
<channel site_id="SuperSport 4" xmltv_id="SuperSport4.al">SuperSport 4</channel>
<channel site_id="SuperSport 5" xmltv_id="SuperSport5.al">SuperSport 5</channel>
<channel site_id="SuperSport 6" xmltv_id="SuperSport6.al">SuperSport 6</channel>
<channel site_id="SS Kosova 1" xmltv_id="SuperSportKosova1.al">SuperSport Kosova 1</channel>
<channel site_id="SS Kosova 2" xmltv_id="SuperSportKosova2.al">SuperSport Kosova 2</channel>
<channel site_id="SS Kosova 3" xmltv_id="SuperSportKosova3.al">SuperSport Kosova 3</channel>
<channel site_id="T 7" xmltv_id="T7.rs">T7</channel>
<channel site_id="RTV 21 MK" xmltv_id="TV21Macedonia.rs">TV 21 Macedonia</channel>
<channel site_id="Klan TV" xmltv_id="TVKlan.al">TV Klan</channel>
<channel site_id="Koha TV" xmltv_id="TVKoha.al">TV Koha</channel>
<channel site_id="Shenja TV" xmltv_id="TVShenja.mk">TV Shenja</channel>
<channel site_id="TV Tetova" xmltv_id="TVTetova.mk">TV Tetova</channel>
<channel site_id="RTM2" xmltv_id="TVM2.mk">TVM2</channel>
<channel site_id="TeleSport" xmltv_id="Telesport.al">Telesport</channel>
<channel site_id="Tip TV" xmltv_id="TipTV.al">Tip TV</channel>
<channel site_id="Top Channel" xmltv_id="TopChannel.al">Top Channel</channel>
<channel site_id="Top News" xmltv_id="TopNews.al">Top News</channel>
<channel site_id="Tribuna Channel" xmltv_id="TribunaChannel.xk">Tribuna Channel</channel>
<channel site_id="Tring Action" xmltv_id="TringAction.al">Tring Action</channel>
<channel site_id="Tring Comedy" xmltv_id="TringComedy.al">Tring Comedy</channel>
<channel site_id="Tring Family" xmltv_id="TringFamily.al">Tring Family</channel>
<channel site_id="Tring Fantasy" xmltv_id="TringFantasy.al">Tring Fantasy</channel>
<channel site_id="Tring History" xmltv_id="TringHistory.al">Tring History</channel>
<channel site_id="Tring International" xmltv_id="TringInternational.al">Tring International</channel>
<channel site_id="Jolly HD" xmltv_id="TringJolly.al">Tring Jolly</channel>
<channel site_id="Tring Kids" xmltv_id="TringKids.al">Tring Kids</channel>
<channel site_id="Tring Life" xmltv_id="TringLife.al">Tring Life</channel>
<channel site_id="Tring Planet" xmltv_id="TringPlanet.al">Tring Planet</channel>
<channel site_id="Tring Shqip" xmltv_id="TringShqip.al">Tring Shqip</channel>
<channel site_id="Smile" xmltv_id="TringSmile.al">Tring Smile</channel>
<channel site_id="Tring Sport 1 HD" xmltv_id="TringSport1.al">Tring Sport 1</channel>
<channel site_id="Tring Sport 2 HD" xmltv_id="TringSport2.al">Tring Sport 2</channel>
<channel site_id="Tring Sport 3 HD" xmltv_id="TringSport3.al">Tring Sport 3</channel>
<channel site_id="Tring Sport 4 HD" xmltv_id="TringSport4.al">Tring Sport 4</channel>
<channel site_id="Tring Sport News HD" xmltv_id="TringSportNews.al">Tring Sport News</channel>
<channel site_id="Tring Super" xmltv_id="TringSuper.al">Tring Super</channel>
<channel site_id="Tring Tring" xmltv_id="TringTring.al">Tring Tring</channel>
<channel site_id="Tring World" xmltv_id="TringWorld.al">Tring World</channel>
<channel site_id="Vizion Plus" xmltv_id="VizionPlus.al">Vizion Plus</channel>
<channel site_id="Cufo TV" xmltv_id="Cufo.al">Çufo</channel>
</channels>
</site>

View file

@ -1,51 +0,0 @@
const epgParser = require('epg-parser')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(customParseFormat)
module.exports = {
lang: 'sq',
site: 'albepg.com',
channels: 'albepg.com.channels.xml',
output: '.gh-pages/guides/albepg.com.guide.xml',
request: {
timeout: 15000,
headers: {
Referer: 'http://albepg.com/epg.html'
}
},
url: function () {
return `http://albepg.com/epg/guide.xml`
},
logo: function ({ channel }) {
return `http://albepg.com/tvlogi/${channel.site_id}.png`
},
parser: function ({ content, channel, date }) {
const results = epgParser.parse(content)
let programs = []
results.programs
.filter(item => item.channel === channel.site_id)
.forEach(item => {
if (item.title.length && item.start && item.stop) {
const description = item.desc.length ? item.desc[0].value : null
const category = item.category.length ? item.category[0].value : null
const start = dayjs.utc(item.start, 'YYYYMMDDHHmmss Z')
const stop = dayjs.utc(item.stop, 'YYYYMMDDHHmmss Z')
if (start.diff(date.format('YYYY-MM-DD'), 'd') === 0) {
programs.push({
title: item.title[0].value,
description,
category,
start: start.toString(),
stop: stop.toString()
})
}
}
})
return programs
}
}

View file

@ -2,11 +2,14 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
let PM = false
module.exports = {
lang: 'ca',
site: 'andorradifusio.ad',
@ -16,36 +19,59 @@ module.exports = {
return `https://www.andorradifusio.ad/programacio/${channel.site_id}`
},
parser({ content, date }) {
const day = date.day() - 1
const programs = []
const dom = new JSDOM(content)
const cols = dom.window.document.querySelectorAll('.programacio-dia')
const colNum = day < 0 ? 6 : day
const times = cols[colNum].querySelectorAll(`h4`)
const titles = cols[colNum].querySelectorAll(`p`)
times.forEach((time, i) => {
const title = titles[i] ? titles[i].textContent : null
if (!time || !title) return false
const start = dayjs
.utc(time.textContent, 'HH:mm')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (!start.isValid()) return false
if (programs.length && !programs[programs.length - 1].stop) {
const items = parseItems(content, date)
items.forEach(item => {
const title = parseTitle(item)
let start = parseStart(item, date)
if (start.hour() > 11) PM = true
if (start.hour() < 12 && PM) start = start.add(1, 'd')
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
start,
stop
})
})
return programs
}
}
function parseStop(item, date) {
return date.tz('Europe/Madrid').endOf('d').add(6, 'h')
}
function parseStart(item, date) {
let time = (item.time || { textContent: '' }).textContent
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'Europe/Madrid')
}
function parseTitle(item) {
return (item.title || { textContent: '' }).textContent
}
function parseItems(content, date) {
const items = []
const dom = new JSDOM(content)
const day = date.day() - 1
const colNum = day < 0 ? 6 : day
const cols = dom.window.document.querySelectorAll('.programacio-dia')
const col = cols[colNum]
const timeRows = col.querySelectorAll(`h4`)
const titleRows = col.querySelectorAll(`p`)
timeRows.forEach((time, i) => {
items.push({
time,
title: titleRows[i]
})
})
return items
}

View file

@ -2,9 +2,11 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
module.exports = {
@ -25,38 +27,43 @@ module.exports = {
},
parser: function ({ content, date }) {
const programs = []
const dom = new JSDOM(content)
const items = dom.window.document.querySelectorAll('#datosasociados > div > .list-group-item')
const items = parseItems(content)
items.forEach(item => {
const time = (
item.querySelector('div > div.col-xs-11 > p > span') || { textContent: '' }
).textContent
.toString()
.trim()
const title = (
item.querySelector('div > div.col-xs-11 > p > strong') || { textContent: '' }
).textContent
.toString()
.trim()
if (time && title) {
const start = dayjs
.utc(time, 'HH:mm:ss')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (programs.length && !programs[programs.length - 1].stop) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start: start.toString()
})
const title = parseTitle(item)
let start = parseStart(item, date)
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({ title, start, stop })
})
return programs
}
}
function parseStop(item, date) {
return date.tz('America/La_Paz').endOf('d')
}
function parseStart(item, date) {
let time = (
item.querySelector('div > div.col-xs-11 > p > span') || { textContent: '' }
).textContent.trim()
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm:ss', 'America/La_Paz')
}
function parseTitle(item) {
return (
item.querySelector('div > div.col-xs-11 > p > strong') || { textContent: '' }
).textContent.trim()
}
function parseItems(content) {
const dom = new JSDOM(content)
return dom.window.document.querySelectorAll('#datosasociados > div > .list-group-item')
}

View file

@ -2,12 +2,12 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(customParseFormat)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
module.exports = {
lang: 'de',
@ -26,29 +26,42 @@ module.exports = {
return img ? img.src : null
},
parser({ content }) {
const dom = new JSDOM(content)
const items = dom.window.document.querySelectorAll('table > tbody > tr')
let programs = []
parser({ content, date }) {
const programs = []
const items = parseItems(content)
items.forEach(item => {
const title = (item.querySelector('td:nth-child(1) > a') || { textContent: '' }).textContent
const fullDate = (item.querySelector('td:nth-child(2)') || { textContent: '' }).textContent
if (title && fullDate) {
const time = fullDate.split(' ').pop()
const local = dayjs.utc(time, 'HH:mm').toString()
const start = dayjs.tz(local.toString(), 'Europe/Berlin').toString()
if (programs.length && !programs[programs.length - 1].stop) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
})
const title = parseTitle(item)
let start = parseStart(item, date)
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({ title, start, stop })
})
return programs
}
}
function parseStop(item, date) {
return date.endOf('d')
}
function parseStart(item, date) {
let time = (item.querySelector('td:nth-child(2)') || { textContent: '' }).textContent
time = time.split(' ').pop()
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'Europe/Berlin')
}
function parseTitle(item) {
return (item.querySelector('td:nth-child(1) > a') || { textContent: '' }).textContent
}
function parseItems(content) {
const dom = new JSDOM(content)
return dom.window.document.querySelectorAll('table > tbody > tr')
}

View file

@ -3,13 +3,14 @@ const iconv = require('iconv-lite')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
var customParseFormat = require('dayjs/plugin/customParseFormat')
var timezone = require('dayjs/plugin/timezone')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(customParseFormat)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
let PM = false
module.exports = {
lang: 'cs',
site: 'm.tv.sms.cz',
@ -28,40 +29,53 @@ module.exports = {
},
parser: function ({ buffer, date }) {
const programs = []
const string = iconv.decode(buffer, 'win1250')
const dom = new JSDOM(string)
const items = dom.window.document.querySelectorAll('#obsah > div > div.porady > div.porad')
const items = parseItems(buffer)
items.forEach((item, i) => {
const time = (item.querySelector('div > span') || { textContent: '' }).textContent
.toString()
.trim()
const title = (item.querySelector('a > div') || { textContent: '' }).textContent
.toString()
.trim()
const description = (item.querySelector('a > div.detail') || { textContent: '' }).textContent
.toString()
.trim()
if (time && title) {
let local = dayjs.utc(time, 'HH.mm').date(date.date()).month(date.month()).year(date.year())
if (local.hour() <= 6 && i > items.length / 2) {
local = local.date(local.date() + 1)
}
const start = dayjs.tz(local.toString(), 'Europe/Prague').toString()
if (programs.length && !programs[programs.length - 1].stop) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
description,
start
})
const title = parseTitle(item)
const description = parseDescription(item)
let start = parseStart(item, date)
if (start.hour() > 11) PM = true
if (start.hour() < 12 && PM) start = start.add(1, 'd')
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
description,
start,
stop
})
})
return programs
}
}
function parseStop(item, date) {
return date.tz('Europe/Prague').endOf('d').add(6, 'h')
}
function parseStart(item, date) {
let time = (item.querySelector('div > span') || { textContent: '' }).textContent.trim()
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH.mm', 'Europe/Prague')
}
function parseDescription(item) {
return (item.querySelector('a > div.detail') || { textContent: '' }).textContent.trim()
}
function parseTitle(item) {
return (item.querySelector('a > div') || { textContent: '' }).textContent.trim()
}
function parseItems(buffer) {
const string = iconv.decode(buffer, 'win1250')
const dom = new JSDOM(string)
return dom.window.document.querySelectorAll('#obsah > div > div.porady > div.porad')
}

View file

@ -114,5 +114,9 @@
<channel site_id="I24I" xmltv_id="i24NewsEnglish.il">i24 News English</channel>
<channel site_id="I24F" xmltv_id="i24NewsFrancais.il">i24 News Français</channel>
<channel site_id="1RUSS" xmltv_id="Pervyykanal.ru">Первый канал</channel>
<channel site_id="TVCTOPH" xmltv_id="TVCineTop.pt">TVCine Top</channel>
<channel site_id="TVCEDIH" xmltv_id="TVCineEdition.ru">TVCine Edition</channel>
<channel site_id="TVCEMOH" xmltv_id="TVCineEmotion.ru">TVCine Emotion</channel>
<channel site_id="TVCACTH" xmltv_id="TVCineAction.ru">TVCine Action</channel>
</channels>
</site>

View file

@ -2,11 +2,14 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
let PM = false
module.exports = {
lang: 'pt',
site: 'mi.tv',
@ -23,32 +26,48 @@ module.exports = {
},
parser({ content, date }) {
const programs = []
const dom = new JSDOM(content)
const items = dom.window.document.querySelectorAll('#listings > ul > li')
const items = parseItems(content)
items.forEach(item => {
const title = (item.querySelector('a > div.content > h2') || { textContent: '' }).textContent
const time = (item.querySelector('a > div.content > span.time') || { textContent: '' })
.textContent
if (title && time) {
const start = dayjs
.utc(time, 'HH:mm')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (programs.length && !programs[programs.length - 1].stop) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
})
const title = parseTitle(item)
let start = parseStart(item, date)
if (!start) return
if (start.hour() > 11) PM = true
if (start.hour() < 12 && PM) start = start.add(1, 'd')
const stop = parseStop(item, start)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start,
stop
})
})
return programs
}
}
function parseStop(item, date) {
return date.endOf('d').add(6, 'h')
}
function parseStart(item, date) {
let time = (item.querySelector('a > div.content > span.time') || { textContent: '' }).textContent
if (!time) return null
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'America/Sao_Paulo')
}
function parseTitle(item) {
return (item.querySelector('a > div.content > h2') || { textContent: '' }).textContent
}
function parseItems(content) {
const dom = new JSDOM(content)
return dom.window.document.querySelectorAll('#listings > ul > li')
}

View file

@ -2,9 +2,11 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
var customParseFormat = require('dayjs/plugin/customParseFormat')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
module.exports = {
@ -32,36 +34,21 @@ module.exports = {
},
parser: function ({ content, date }) {
const programs = []
const dom = new JSDOM(content)
const items = dom.window.document.querySelectorAll(
'#content > div > div > div.span6 > table > tbody > tr'
)
const items = parseItems(content)
items.forEach(item => {
const time = (item.querySelector('td:nth-child(1) > h5') || { textContent: '' }).textContent
.toString()
.trim()
const title = (
item.querySelector('td:nth-child(2) > h5 > a') || { textContent: '' }
).textContent
.toString()
.trim()
const title = parseTitle(item)
const start = parseStart(item, date)
const stop = parseStop(item, date)
if (time && title) {
const start = dayjs
.utc(time, 'h:mma')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
.toString()
if (programs.length && !programs[programs.length - 1].stop) {
if (title && start) {
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
start,
stop
})
}
})
@ -69,3 +56,28 @@ module.exports = {
return programs
}
}
function parseStop(item, date) {
return date.tz('Europe/London').endOf('d')
}
function parseStart(item, date) {
let time = (item.querySelector('td:nth-child(1) > h5') || { textContent: '' }).textContent.trim()
time = `${date.format('DD/MM/YYYY')} ${time.toUpperCase()}`
return dayjs.tz(time, 'DD/MM/YYYY H:mm A', 'Europe/London')
}
function parseTitle(item) {
return (item.querySelector('td:nth-child(2) > h5 > a') || { textContent: '' }).textContent
.toString()
.trim()
}
function parseItems(content) {
const dom = new JSDOM(content)
return dom.window.document.querySelectorAll(
'#content > div > div > div.span6 > table > tbody > tr'
)
}

View file

@ -2,11 +2,14 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
let PM = false
module.exports = {
lang: 'pl',
site: 'programtv.onet.pl',
@ -24,24 +27,16 @@ module.exports = {
},
parser: function ({ content, date }) {
const programs = []
const dom = new JSDOM(content)
const items = dom.window.document.querySelectorAll(
'#channelTV > section > div.emissions > ul > li'
)
const items = parseItems(content)
items.forEach(item => {
const title = (item.querySelector('.titles > a') || { textContent: '' }).textContent
const description = (item.querySelector('.titles > p') || { textContent: '' }).textContent
const category = (item.querySelector('.titles > .type') || { textContent: '' }).textContent
const hour = (item.querySelector('.hours > .hour') || { textContent: '' }).textContent
const start = dayjs
.utc(hour, 'H:mm')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (programs.length && !programs[programs.length - 1].stop) {
const title = parseTitle(item)
const description = parseDescription(item)
const category = parseCategory(item)
let start = parseStart(item, date)
if (start.hour() > 11) PM = true
if (start.hour() < 12 && PM) start = start.add(1, 'd')
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
@ -49,10 +44,40 @@ module.exports = {
title,
description,
category,
start
start,
stop
})
})
return programs
}
}
function parseStop(item, date) {
return date.add(1, 'd').hour(3).startOf('h')
}
function parseStart(item, date) {
let time = (item.querySelector('.hours > .hour') || { textContent: '' }).textContent
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'Europe/Warsaw')
}
function parseCategory(item) {
return (item.querySelector('.titles > .type') || { textContent: '' }).textContent
}
function parseDescription(item) {
return (item.querySelector('.titles > p') || { textContent: '' }).textContent
}
function parseTitle(item) {
return (item.querySelector('.titles > a') || { textContent: '' }).textContent
}
function parseItems(content) {
const dom = new JSDOM(content)
return dom.window.document.querySelectorAll('#channelTV > section > div.emissions > ul > li')
}

View file

@ -3,11 +3,14 @@ const iconv = require('iconv-lite')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
let PM = false
module.exports = {
lang: 'uk',
site: 'tvgid.ua',
@ -18,36 +21,50 @@ module.exports = {
},
parser: function ({ buffer, date }) {
const programs = []
const string = iconv.decode(buffer, 'win1251')
const dom = new JSDOM(string)
const items = dom.window.document.querySelectorAll(
'#container > tbody > tr:nth-child(2) > td > table > tbody > tr > td > table:nth-child(2) > tbody > tr'
)
const items = parseItems(buffer)
items.forEach(item => {
const time = (item.querySelector('td > table > tbody > tr > td.time') || { textContent: '' })
.textContent
const title = (
item.querySelector('td > table > tbody > tr > td.item > a') ||
item.querySelector('td > table > tbody > tr > td.item') || { textContent: '' }
).textContent
const start = dayjs
.utc(time, 'HH:mm')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (programs.length && !programs[programs.length - 1].stop) {
const title = parseTitle(item)
let start = parseStart(item, date)
if (!start) return
if (start.hour() > 11) PM = true
if (start.hour() < 12 && PM) start = start.add(1, 'd')
const stop = parseStop(item, start)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
})
programs.push({ title, start, stop })
})
return programs
}
}
function parseStop(item, date) {
return date.hour(7)
}
function parseStart(item, date) {
let time = (item.querySelector('td > table > tbody > tr > td.time') || { textContent: '' })
.textContent
if (!time) return null
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'Europe/Kiev')
}
function parseTitle(item) {
return (
item.querySelector('td > table > tbody > tr > td.item > a') ||
item.querySelector('td > table > tbody > tr > td.item') || { textContent: '' }
).textContent
}
function parseItems(buffer) {
const string = iconv.decode(buffer, 'win1251')
const dom = new JSDOM(string)
return dom.window.document.querySelectorAll(
'#container > tbody > tr:nth-child(2) > td > table > tbody > tr > td > table:nth-child(2) > tbody > tr:not(:first-child)'
)
}

93
sites/tvguide.com.channels.xml Executable file
View file

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<site site="tvguide.com">
<channels>
<channel site_id="9100001138#9200004889" xmltv_id="AEEast.us">A&amp;E East</channel>
<channel site_id="9100001138#9233011874" xmltv_id="ABCEast.us">ABC East</channel>
<channel site_id="9100001138#9233011832" xmltv_id="AMCEast.us">AMC East</channel>
<channel site_id="9100001138#9200018479" xmltv_id="AnimalPlanetEast.us">Animal Planet East</channel>
<channel site_id="9100001138#9200014701" xmltv_id="BBCAmericaEast.uk">BBC America East</channel>
<channel site_id="9100001138#9233005931" xmltv_id="BETEast.us">BET East</channel>
<channel site_id="9100001138#9200002886" xmltv_id="BravoEast.us">Bravo East</channel>
<channel site_id="9100001138#9200004848" xmltv_id="CartoonNetworkEast.us">Cartoon Network East</channel>
<channel site_id="9100001138#9200018514" xmltv_id="CBSEast.us">CBS East</channel>
<channel site_id="9100001138#9233009829" xmltv_id="CinemaxEast.us">Cinemax East</channel>
<channel site_id="9100001138#9200012085" xmltv_id="CMTEast.us">CMT East</channel>
<channel site_id="9100001138#9200009413" xmltv_id="CNBCUS.us">CNBC US</channel>
<channel site_id="9100001138#9233013812" xmltv_id="CNNUSA.us">CNN USA</channel>
<channel site_id="9100001138#9200000657" xmltv_id="ComedyCentralEast.us">Comedy Central East</channel>
<channel site_id="9100001138#9233004102" xmltv_id="DiscoveryChannelEast.us">Discovery Channel East</channel>
<channel site_id="9100001138#9233013857" xmltv_id="DiscoveryLifeChannel.us">Discovery Life Channel</channel>
<channel site_id="9100001138#9200018475" xmltv_id="DisneyChannelEast.us">Disney Channel East</channel>
<channel site_id="9100001138#9200004852" xmltv_id="DisneyXDEast.us">Disney XD East</channel>
<channel site_id="9100001138#9200012415" xmltv_id="DIYNetworkUSA.us">DIY Network USA</channel>
<channel site_id="9100001138#9200012343" xmltv_id="EEast.us">E! East</channel>
<channel site_id="9100001138#9200006937" xmltv_id="ESPN.us">ESPN</channel>
<channel site_id="9100001138#9200012351" xmltv_id="ESPN2US.us">ESPN 2 US</channel>
<channel site_id="9100001138#9233011637" xmltv_id="ESPNClassicUSA.us">ESPN Classic USA</channel>
<channel site_id="9100001138#9233011350" xmltv_id="ESPNU.us">ESPNU</channel>
<channel site_id="9100001138#9233000217" xmltv_id="FlixEast.us">Flix East</channel>
<channel site_id="9100001138#9233009448" xmltv_id="FoodNetworkEast.us">Food Network East</channel>
<channel site_id="9100001138#9233002271" xmltv_id="FoxEast.us">Fox East</channel>
<channel site_id="9100001138#9233000410" xmltv_id="FoxNewsChannel.us">Fox News Channel</channel>
<channel site_id="9100001138#9233008440" xmltv_id="FoxSports1.us">Fox Sports 1</channel>
<channel site_id="9100001138#9200006942" xmltv_id="FreeformEast.us">Freeform East</channel>
<channel site_id="9100001138#9233000028" xmltv_id="FuseEast.us">Fuse East</channel>
<channel site_id="9100001138#9200006932" xmltv_id="FXEast.us">FX East</channel>
<channel site_id="9100001138#9233013967" xmltv_id="FXMovieChannel.us">FX Movie Channel</channel>
<channel site_id="9100001138#9200018644" xmltv_id="FXXEast.us">FXX East</channel>
<channel site_id="9100001138#9200020460" xmltv_id="FYIEast.us">FYI East</channel>
<channel site_id="9100001138#9200019858" xmltv_id="GameShowNetworkEast.us">Game Show Network East</channel>
<channel site_id="9100001138#9233005443" xmltv_id="GolfChannelUS.us">Golf Channel US</channel>
<channel site_id="9100001138#9200016034" xmltv_id="HallmarkChannelEast.us">Hallmark Channel East</channel>
<channel site_id="9100001138#9233003524" xmltv_id="HBO2East.us">HBO 2 East</channel>
<channel site_id="9100001138#9200004886" xmltv_id="HBOEast.us">HBO East</channel>
<channel site_id="9100001138#9233008160" xmltv_id="HBOSignatureEast.us">HBO Signature East</channel>
<channel site_id="9100001138#9233004104" xmltv_id="HGTVEast.us">HGTV East</channel>
<channel site_id="9100001138#9233008002" xmltv_id="HistoryEast.us">History East</channel>
<channel site_id="9100001138#9200004303" xmltv_id="IFCEast.us">IFC East</channel>
<channel site_id="9100001138#9200002243" xmltv_id="InvestigationDiscoveryEast.us">Investigation Discovery East</channel>
<channel site_id="9100001138#9233011910" xmltv_id="IONTVEast.us">ION TV East</channel>
<channel site_id="9100001138#9200020452" xmltv_id="LifetimeEast.us">Lifetime East</channel>
<channel site_id="9100001138#9233009825" xmltv_id="LifetimeMoviesEast.us">Lifetime Movies East</channel>
<channel site_id="9100001138#9233001621" xmltv_id="LifetimeRealWomen.us">Lifetime Real Women</channel>
<channel site_id="9100001138#9233015766" xmltv_id="MoreMaxEast.us">MoreMax East</channel>
<channel site_id="9100001138#9233006803" xmltv_id="MSNBC.us">MSNBC</channel>
<channel site_id="9100001138#9200014754" xmltv_id="MTVEast.us">MTV East</channel>
<channel site_id="9100001138#9233001847" xmltv_id="MyNetworkTV.us">MyNetworkTV</channel>
<channel site_id="9100001138#9233002310" xmltv_id="NationalGeographicEast.us">National Geographic East</channel>
<channel site_id="9100001138#9233009876" xmltv_id="NBCEast.us">NBC East</channel>
<channel site_id="9100001138#9233000030" xmltv_id="NBCSN.us">NBCSN</channel>
<channel site_id="9100001138#9233013251" xmltv_id="NewsNationEast.us">NewsNation East</channel>
<channel site_id="9100001138#9200006939" xmltv_id="NickelodeonEast.us">Nickelodeon East</channel>
<channel site_id="9100001138#9200002736" xmltv_id="OprahWinfreyNetworkEast.us">Oprah Winfrey Network East</channel>
<channel site_id="9100001138#9200004949" xmltv_id="OxygenEast.us">Oxygen East</channel>
<channel site_id="9100001138#9233013810" xmltv_id="ParamountNetworkEast.us">Paramount Network East</channel>
<channel site_id="9100001138#9233004141" xmltv_id="PBSEast.us">PBS East</channel>
<channel site_id="9100001138#9200020464" xmltv_id="PopEast.us">Pop East</channel>
<channel site_id="9100001138#9200002891" xmltv_id="QVCUS.us">QVC US</channel>
<channel site_id="9100001138#9200011769" xmltv_id="Reelz.us">Reelz</channel>
<channel site_id="9100001138#9200019847" xmltv_id="Science.us">Science</channel>
<channel site_id="9100001138#9200018178" xmltv_id="Showtime2East.us">Showtime 2 East</channel>
<channel site_id="9100001138#9200016599" xmltv_id="ShowtimeEast.us">Showtime East</channel>
<channel site_id="9100001138#9233002112" xmltv_id="SmithsonianChannelEast.us">Smithsonian Channel East</channel>
<channel site_id="9100001138#9233013809" xmltv_id="StarzEast.us">Starz East</channel>
<channel site_id="9100001138#9200009649" xmltv_id="StarzEncoreEast.us">Starz Encore East</channel>
<channel site_id="9100001138#9233001687" xmltv_id="SundanceTVEast.us">Sundance TV East</channel>
<channel site_id="9100001138#9200004316" xmltv_id="SyfyEast.us">Syfy East</channel>
<channel site_id="9100001138#9233000403" xmltv_id="TBSEast.us">TBS East</channel>
<channel site_id="9100001138#9200017928" xmltv_id="TCMUS.us">TCM US</channel>
<channel site_id="9100001138#9200011857" xmltv_id="TelemundoEste.us">Telemundo Este</channel>
<channel site_id="9100001138#9233011398" xmltv_id="TheCWEast.us">The CW East</channel>
<channel site_id="9100001138#9233015305" xmltv_id="TheMovieChannelEast.us">The Movie Channel East</channel>
<channel site_id="9100001138#9233004112" xmltv_id="TLCEast.us">TLC East</channel>
<channel site_id="9100001138#9233011830" xmltv_id="TNTEast.us">TNT East</channel>
<channel site_id="9100001138#9233000035" xmltv_id="TravelChannelEast.us">Travel Channel East</channel>
<channel site_id="9100001138#9200009547" xmltv_id="truTVEast.us">truTV East</channel>
<channel site_id="9100001138#9233005468" xmltv_id="TVLandEast.us">TV Land East</channel>
<channel site_id="9100001138#9200012412" xmltv_id="TVG.us">TVG</channel>
<channel site_id="9100001138#9200000867" xmltv_id="UnivisionEast.us">Univisión East</channel>
<channel site_id="9100001138#9233004106" xmltv_id="USANetworkEast.us">USA Network East</channel>
<channel site_id="9100001138#9233000037" xmltv_id="VH1East.us">VH1 East</channel>
<channel site_id="9100001138#9200018188" xmltv_id="WeTVEast.us">We TV East</channel>
</channels>
</site>

View file

@ -0,0 +1,47 @@
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
dayjs.extend(utc)
dayjs.extend(timezone)
module.exports = {
lang: 'en',
site: 'tvguide.com',
channels: 'tvguide.com.channels.xml',
output: '.gh-pages/guides/tvguide.com.guide.xml',
url: function ({ date, channel }) {
const localTime = date.tz('America/New_York')
const parts = channel.site_id.split('#')
const start = localTime.startOf('d')
const duration = localTime.endOf('d').diff(start, 'm')
const url = `https://cmg-prod.apigee.net/v1/xapi/tvschedules/tvguide/${
parts[0]
}/web?start=${start.unix()}&duration=${duration}&channelSourceIds=${parts[1]}`
return url
},
parser: function ({ content }) {
const programs = []
const items = parseItems(content)
items.forEach(item => {
programs.push({
title: item.title,
start: parseTime(item.startTime),
stop: parseTime(item.endTime)
})
})
return programs
}
}
function parseTime(timestamp) {
return dayjs.unix(timestamp)
}
function parseItems(content) {
const json = JSON.parse(content)
return json.data.items[0].programSchedules
}

1430
sites/tvprofil.com.channels.xml Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,106 @@
const cheerio = require('cheerio')
const dayjs = require('dayjs')
module.exports = {
lang: 'hr',
site: 'tvprofil.com',
channels: 'tvprofil.com.channels.xml',
output: '.gh-pages/guides/tvprofil.com.guide.xml',
request: {
headers: {
'x-requested-with': 'XMLHttpRequest'
}
},
url: function ({ channel, date }) {
const parts = channel.site_id.split('#')
const query = buildQuery(parts[1], date)
return `https://tvprofil.com/${parts[0]}/program/?${query}`
},
logo: function ({ content }) {
const result = parseContent(content)
return `https://cdn-0.tvprofil.com/cdn/100x40/10/img/kanali-logo/${result.data.channel.logo}`
},
parser: function ({ content, channel, date }) {
let programs = []
const result = parseContent(content)
const items = parseItems(result.data.program)
items.forEach(item => {
const $item = cheerio.load(item)
const title = parseTitle($item)
const category = parseCategory($item)
const start = parseStart($item)
const duration = parseDuration($item)
const stop = start.add(duration, 's')
const icon = parseIcon($item)
programs.push({ title, category, start, stop, icon })
})
return programs
}
}
function parseIcon($item) {
return $item(':root').data('image')
}
function parseDuration($item) {
return $item(':root').data('len')
}
function parseStart($item) {
const timestamp = $item(':root').data('ts')
return dayjs.unix(timestamp)
}
function parseCategory($item) {
return $item('.col:nth-child(2) > small').text() || null
}
function parseTitle($item) {
let title = $item('.col:nth-child(2) > a').text()
title += $item('.col:nth-child(2)').clone().children().remove().end().text()
return title.replace('®', '').trim().replace(/,$/, '')
}
function parseItems(program) {
const $ = cheerio.load(program)
return $('.row').toArray()
}
function parseContent(content) {
let data = (content.match(/cb\((.*)\)/) || [null, null])[1]
return JSON.parse(data)
}
function buildQuery(site_id, date) {
const query = {
datum: date.format('YYYY-MM-DD'),
kanal: site_id,
callback: `cb`
}
const a = query.datum + query.kanal
const ua = query.kanal + query.datum
let i = a.length,
b = 2,
c = 2
for (var j = 0; j < ua.length; j++) c += ua.charCodeAt(j)
while (i--) {
b += (a.charCodeAt(i) + c * 2) * i
}
const key = 'b' + b.toString().charCodeAt(2)
query[key] = b
return new URLSearchParams(query).toString()
}

View file

@ -2437,7 +2437,7 @@
<channel site_id="7232" xmltv_id="MASN2.us" logo="https://cdn.tvpassport.com/image/station/100x100/masn.png">MASN2</channel>
<channel site_id="14771" xmltv_id="MBCAmerica.kr" logo="https://cdn.tvpassport.com/image/station/100x100/mbc-america.png">MBC America</channel>
<channel site_id="14772" xmltv_id="WKTBCD5.us" logo="https://cdn.tvpassport.com/image/station/100x100/mbc-america.png">MBC America (WKTB-CD5)</channel>
<channel site_id="15014" xmltv_id="MBCDrama.us">MBC Drama (Korean)</channel>
<channel site_id="15014" xmltv_id="MBCDrama.us">MBC Drama</channel>
<channel site_id="12630" xmltv_id="MCAETTV.us" logo="https://cdn.tvpassport.com/image/station/100x100/mcaet.png">MCAETv</channel>
<channel site_id="18760" xmltv_id="K38JPD3.us" logo="https://cdn.tvpassport.com/image/station/100x100/mcaet.png">MCAETv (K38JP-DT3)</channel>
<channel site_id="6107" xmltv_id="MGMHDUSA.us" logo="https://cdn.tvpassport.com/image/station/100x100/mgmhd.png">MGM HD USA</channel>

View file

@ -8,13 +8,13 @@
<channel site_id="7464" xmltv_id="AjwaTV.id">AJWA TV</channel>
<channel site_id="874" xmltv_id="KompasTV.id">Kompas TV</channel>
<channel site_id="6165" xmltv_id="BeritaSatu.id">BeritaSatu</channel>
<channel site_id="777" xmltv_id="METROTV.id">METRO TV</channel>
<channel site_id="777" xmltv_id="MetroTV.id">Metro TV</channel>
<channel site_id="875" xmltv_id="NET.id">NET.</channel>
<channel site_id="733" xmltv_id="TRANSTVHD.id">TRANS TV HD</channel>
<channel site_id="733" xmltv_id="TransTV.id">Trans TV</channel>
<channel site_id="6441" xmltv_id="TVRINasional.id">TVRI Nasional</channel>
<channel site_id="734" xmltv_id="TRANS7HD.id">TRANS 7 HD</channel>
<channel site_id="734" xmltv_id="Trans7.id">Trans 7</channel>
<channel site_id="870" xmltv_id="MNCTV.id">MNCTV</channel>
<channel site_id="5415" xmltv_id="JAKTV.id">Jaktv</channel>
<channel site_id="5415" xmltv_id="JakTV.id">Jak TV</channel>
<channel site_id="778" xmltv_id="GTV.id">GTV</channel>
<channel site_id="1561" xmltv_id="RTV.id">RTV</channel>
<channel site_id="5409" xmltv_id="iNews.id">iNews</channel>
@ -27,6 +27,7 @@
<channel site_id="6786" xmltv_id="ChampionTV3.id">Champions TV 2</channel>
<channel site_id="7648" xmltv_id="FoxSportsAsia.us">Fox Sports Asia</channel>
<channel site_id="6299" xmltv_id="beINSports1Asia.qa">beIN Sports 1 Asia</channel>
<channel site_id="6317" xmltv_id="beINSports2Asia.qa">beIN Sports 2 Asia</channel>
<channel site_id="7649" xmltv_id="FoxSports2Asia.us">Fox Sports 2 Asia</channel>
<channel site_id="7650" xmltv_id="FoxSports3Asia.us">Fox Sports 3 Asia</channel>
<channel site_id="6784" xmltv_id="ArirangTV.kr">Arirang TV</channel>

View file

@ -2,9 +2,11 @@ const jsdom = require('jsdom')
const { JSDOM } = jsdom
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
module.exports = {
@ -24,43 +26,52 @@ module.exports = {
return img ? img.dataset.src : null
},
parser({ content, date }) {
const day = date.day() // 0 => Sunday
const programs = []
const dom = new JSDOM(content)
const tabs = dom.window.document.querySelectorAll(
`.elementor-tabs-content-wrapper > div[id*='elementor-tab-content']`
)
const items = tabs[day].querySelectorAll(`table > tbody > tr`)
const items = parseItems(content, date)
items.forEach(item => {
const row = (item.querySelector('td > p') || { textContent: '' }).textContent
const parts = row.split(' ')
const time = parts.shift()
const title = parts
.filter(str => str && /\S/g.test(str))
.map(i => i.trim())
.join(' ')
if (!time || !title) return false
const start = dayjs
.utc(time, 'HH:mm')
.set('D', date.get('D'))
.set('M', date.get('M'))
.set('y', date.get('y'))
if (!start.isValid()) return false
if (programs.length && !programs[programs.length - 1].stop) {
const title = parseTitle(item)
const start = parseStart(item, date)
const stop = parseStop(item, date)
if (programs.length) {
programs[programs.length - 1].stop = start
}
programs.push({
title,
start
})
programs.push({ title, start, stop })
})
return programs
}
}
function parseStop(item, date) {
return date.endOf('d')
}
function parseStart(item, date) {
const row = (item.querySelector('td > p') || { textContent: '' }).textContent
let time = row.split(' ').shift()
time = `${date.format('MM/DD/YYYY')} ${time}`
return dayjs.tz(time, 'MM/DD/YYYY HH:mm', 'Africa/Lusaka')
}
function parseTitle(item) {
const row = (item.querySelector('td > p') || { textContent: '' }).textContent
const title = row.split(' ')
title.shift()
return title
.map(i => i.trim())
.filter(s => s)
.join(' ')
}
function parseItems(content, date) {
const day = date.day() // 0 => Sunday
const dom = new JSDOM(content)
const tabs = dom.window.document.querySelectorAll(
`.elementor-tabs-content-wrapper > div[id*='elementor-tab-content']`
)
return tabs[day].querySelectorAll(`table > tbody > tr:not(:first-child)`)
}