mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-09 16:40:07 -04:00
Merge branch 'master' into add-elcinema-com
This commit is contained in:
commit
4a939ca18e
24 changed files with 3978 additions and 269 deletions
16
.github/workflows/auto-update.yml
vendored
16
.github/workflows/auto-update.yml
vendored
|
@ -34,8 +34,11 @@ jobs:
|
|||
tvtv.ca,
|
||||
tvtv.us,
|
||||
tv.lv,
|
||||
vidio.com,
|
||||
elcinema.com
|
||||
maxtv.hrvatskitelekom.hr
|
||||
mncvision.id,
|
||||
tvguide.com,
|
||||
tvprofil.com
|
||||
]
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -50,6 +53,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:
|
||||
|
@ -57,6 +61,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:
|
||||
|
@ -64,3 +74,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'
|
||||
|
|
70
.github/workflows/update-codes.yml
vendored
70
.github/workflows/update-codes.yml
vendored
|
@ -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 }}
|
||||
|
|
13
README.md
13
README.md
|
@ -15,15 +15,20 @@ To load a program guide, all you need to do is copy the link to one of the guide
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr><td align="left" nowrap>🇩🇿 Algeria</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.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/maxtv.hrvatskitelekom.hr.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>🇪🇬 Egypt</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.com.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>
|
||||
|
@ -33,7 +38,8 @@ To load a program guide, all you need to do is copy the link to one of the guide
|
|||
<tr><td align="left" nowrap>🇬🇷 Greece</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/cosmote.gr.guide.xml</code></td></tr>
|
||||
<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/vidio.com.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>🇮🇷 Iran</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.com.guide.xml</code></td></tr>
|
||||
|
@ -46,6 +52,8 @@ To load a program guide, all you need to do is copy the link to one of the guide
|
|||
<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>🇲🇦 Morocco</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.com.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>
|
||||
|
@ -53,6 +61,9 @@ To load a program guide, all you need to do is copy the link to one of the guide
|
|||
<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>🇸🇦 Saudi Arabia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.com.guide.xml</code></td></tr>
|
||||
<tr><td align="left" nowrap>🇷🇸 Serbia</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/maxtv.hrvatskitelekom.hr.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>🇸🇾 Syria</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/elcinema.com.guide.xml</code></td></tr>
|
||||
|
|
1437
package-lock.json
generated
1437
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -7,9 +7,11 @@
|
|||
"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",
|
||||
"form-data": "^4.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"html-to-text": "^7.0.0",
|
||||
"iconv-lite": "^0.4.24",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
201
sites/maxtv.hrvatskitelekom.hr.channels.xml
Executable file
201
sites/maxtv.hrvatskitelekom.hr.channels.xml
Executable file
|
@ -0,0 +1,201 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<site site="maxtv.hrvatskitelekom.hr">
|
||||
<channels>
|
||||
<channel site_id="316" xmltv_id="24KitchenHrvatska.us">24 Kitchen Hrvatska</channel>
|
||||
<channel site_id="285" xmltv_id="3sat.de">3sat</channel>
|
||||
<channel site_id="153" xmltv_id="AlJazeeraBalkans.qa">Al Jazeera Balkans</channel>
|
||||
<channel site_id="444" xmltv_id="ArenaSport1Hrvatska.rs">Arena Sport 1 Hrvatska Hrvatska</channel>
|
||||
<channel site_id="800" xmltv_id="ArenaSport10Hrvatska.rs">Arena Sport 10 Hrvatska</channel>
|
||||
<channel site_id="453" xmltv_id="ArenaSport2Hrvatska.rs">Arena Sport 2 Hrvatska</channel>
|
||||
<channel site_id="443" xmltv_id="ArenaSport3Hrvatska.rs">Arena Sport 3 Hrvatska</channel>
|
||||
<channel site_id="445" xmltv_id="ArenaSport4Hrvatska.rs">Arena Sport 4 Hrvatska</channel>
|
||||
<channel site_id="449" xmltv_id="ArenaSport5Hrvatska.rs">Arena Sport 5 Hrvatska</channel>
|
||||
<channel site_id="207" xmltv_id="ArenaSport6Hrvatska.rs">Arena Sport 6 Hrvatska</channel>
|
||||
<channel site_id="797" xmltv_id="ArenaSport7Hrvatska.rs">Arena Sport 7 Hrvatska</channel>
|
||||
<channel site_id="798" xmltv_id="ArenaSport8Hrvatska.rs">Arena Sport 8 Hrvatska</channel>
|
||||
<channel site_id="799" xmltv_id="ArenaSport9Hrvatska.rs">Arena Sport 9 Hrvatska</channel>
|
||||
<channel site_id="719" xmltv_id="AuroraTV.hr">Aurora TV</channel>
|
||||
<channel site_id="164" xmltv_id="BabyTVEurope.uk">Baby TV Europe</channel>
|
||||
<channel site_id="271" xmltv_id="BalkanikaTV.bg">Balkanika TV</channel>
|
||||
<channel site_id="631" xmltv_id="BBCEarthRomania.uk">BBC Earth Romania</channel>
|
||||
<channel site_id="125" xmltv_id="BHT1.ba">BHT 1</channel>
|
||||
<channel site_id="291" xmltv_id="BlueHustlerEurope.us">Blue Hustler Europe</channel>
|
||||
<channel site_id="425" xmltv_id="BoomerangCentralEasternEurope.us">Boomerang Central & Eastern Europe</channel>
|
||||
<channel site_id="295" xmltv_id="BrazzersTVEurope.us">Brazzers TV Europe</channel>
|
||||
<channel site_id="427" xmltv_id="CartoonNetworkRussiaSoutheasternEuropean.us">Cartoon Network Russia & Southeastern European</channel>
|
||||
<channel site_id="435" xmltv_id="CBSRealityEurope.us">CBS Reality Europe</channel>
|
||||
<channel site_id="103" xmltv_id="CGTN.cn">CGTN</channel>
|
||||
<channel site_id="365" xmltv_id="Cinemax2CentralEurope.us">Cinemax 2 Central Europe</channel>
|
||||
<channel site_id="399" xmltv_id="CinemaxCentralEurope.us">Cinemax Central Europe</channel>
|
||||
<channel site_id="208" xmltv_id="CineStarTV1Hrvatska.hr">CineStar TV 1 Hrvatska</channel>
|
||||
<channel site_id="218" xmltv_id="CineStarTVActionHrvatska.hr">CineStar TV Action Hrvatska</channel>
|
||||
<channel site_id="633" xmltv_id="CineStarTVFantasy.hr">CineStar TV Fantasy</channel>
|
||||
<channel site_id="634" xmltv_id="CineStarTVPremiere1.hr">CineStar TV Premiere 1</channel>
|
||||
<channel site_id="635" xmltv_id="CineStarTVPremiere2.hr">CineStar TV Premiere 2</channel>
|
||||
<channel site_id="327" xmltv_id="ClubMTV.us">Club MTV</channel>
|
||||
<channel site_id="101" xmltv_id="CMCTV.hr">CMC TV</channel>
|
||||
<channel site_id="260" xmltv_id="CNBCEurope.us">CNBC Europe</channel>
|
||||
<channel site_id="170" xmltv_id="CNNInternationalEurope.us">CNN International Europe</channel>
|
||||
<channel site_id="227" xmltv_id="CrimeInvestigationUK.us">Crime & Investigation UK</channel>
|
||||
<channel site_id="423" xmltv_id="DaVinci.de">Da Vinci</channel>
|
||||
<channel site_id="261" xmltv_id="DasErste.de">Das Erste</channel>
|
||||
<channel site_id="681" xmltv_id="DiadoraTV.hr">Diadora TV</channel>
|
||||
<channel site_id="270" xmltv_id="DMSat.rs">DM Sat</channel>
|
||||
<channel site_id="298" xmltv_id="DMC.hr">DMC</channel>
|
||||
<channel site_id="92" xmltv_id="DomaTV.hr">Doma TV</channel>
|
||||
<channel site_id="118" xmltv_id="DUTV.hr">DUTV</channel>
|
||||
<channel site_id="265" xmltv_id="DWEnglish.de">DW English</channel>
|
||||
<channel site_id="317" xmltv_id="EEurope.us">E! Europe</channel>
|
||||
<channel site_id="638" xmltv_id="EpicDrama.se">Epic Drama</channel>
|
||||
<channel site_id="276" xmltv_id="EuronewsEnglish.fr">Euronews English</channel>
|
||||
<channel site_id="670" xmltv_id="ExtraTV.hr">ExtraTV</channel>
|
||||
<channel site_id="314" xmltv_id="ExtremeSportsChannel.nl">Extreme Sports Channel</channel>
|
||||
<channel site_id="326" xmltv_id="FashionTVEurope.fr">FashionTV Europe</channel>
|
||||
<channel site_id="279" xmltv_id="FederalnaTV.ba">Federalna TV</channel>
|
||||
<channel site_id="206" xmltv_id="FightChannel.hr">Fight Channel</channel>
|
||||
<channel site_id="359" xmltv_id="FoxCrimeHrvatska.us">Fox Crime Hrvatska</channel>
|
||||
<channel site_id="360" xmltv_id="FoxHrvatska.us">Fox Hrvatska</channel>
|
||||
<channel site_id="357" xmltv_id="FoxLifeHrvatska.us">Fox Life Hrvatska</channel>
|
||||
<channel site_id="358" xmltv_id="FoxMoviesHrvatska.us">Fox Movies Hrvatska</channel>
|
||||
<channel site_id="274" xmltv_id="France24English.fr">France 24 English</channel>
|
||||
<channel site_id="273" xmltv_id="France24Francais.fr">France 24 Français</channel>
|
||||
<channel site_id="109" xmltv_id="GameHub.hr">GameHub</channel>
|
||||
<channel site_id="300" xmltv_id="GrandTV.rs">Grand TV</channel>
|
||||
<channel site_id="290" xmltv_id="Happy.rs">Happy</channel>
|
||||
<channel site_id="280" xmltv_id="Hayat.ba">Hayat</channel>
|
||||
<channel site_id="397" xmltv_id="HBO2CentralEurope.us">HBO 2 Central Europe</channel>
|
||||
<channel site_id="398" xmltv_id="HBO3CentralEurope.us">HBO 3 Central Europe</channel>
|
||||
<channel site_id="440" xmltv_id="HBOAdria.us">HBO Adria</channel>
|
||||
<channel site_id="630" xmltv_id="History2Polska.us">History 2 Polska</channel>
|
||||
<channel site_id="437" xmltv_id="HistoryEurope.us">History Europe</channel>
|
||||
<channel site_id="175" xmltv_id="HITTV.hr">HIT TV</channel>
|
||||
<channel site_id="310" xmltv_id="HNTV.hr">HNTV</channel>
|
||||
<channel site_id="431" xmltv_id="HRT1.hr">HRT 1</channel>
|
||||
<channel site_id="432" xmltv_id="HRT2.hr">HRT 2</channel>
|
||||
<channel site_id="451" xmltv_id="HRT3.hr">HRT 3</channel>
|
||||
<channel site_id="94" xmltv_id="HRT4.hr">HRT 4</channel>
|
||||
<channel site_id="296" xmltv_id="HustlerTVEurope.us">Hustler TV Europe</channel>
|
||||
<channel site_id="179" xmltv_id="JugotonTV.hr">Jugoton TV</channel>
|
||||
<channel site_id="108" xmltv_id="KanalRi.hr">Kanal Ri</channel>
|
||||
<channel site_id="242" xmltv_id="KiKA.de">KiKA</channel>
|
||||
<channel site_id="647" xmltv_id="KinoTV.hr">Kino TV</channel>
|
||||
<channel site_id="178" xmltv_id="KlasikTV.hr">Klasik TV</channel>
|
||||
<channel site_id="180" xmltv_id="KreatorTV.hr">Kreator TV</channel>
|
||||
<channel site_id="318" xmltv_id="LaudatoTV.hr">Laudato TV</channel>
|
||||
<channel site_id="506" xmltv_id="LibertasTV.hr">Libertas TV</channel>
|
||||
<channel site_id="312" xmltv_id="LoviRibolov.rs">Lov i Ribolov</channel>
|
||||
<channel site_id="374" xmltv_id="LuxeTV.lu">Luxe TV</channel>
|
||||
<channel site_id="649" xmltv_id="M1Film.hr">M1 Film</channel>
|
||||
<channel site_id="651" xmltv_id="M1Gold.hr">M1 Gold</channel>
|
||||
<channel site_id="98" xmltv_id="MAXtvPromoKanal.hr">MAXtv Promo Kanal</channel>
|
||||
<channel site_id="817" xmltv_id="MariaPlusVisionMedjugorje.mx">María+Visión Medjugorje</channel>
|
||||
<channel site_id="321" xmltv_id="MediasetItalia.it">Mediaset Italia</channel>
|
||||
<channel site_id="392" xmltv_id="MiniTV.hr">Mini TV</channel>
|
||||
<channel site_id="107" xmltv_id="MrezaTV.hr">Mreža TV</channel>
|
||||
<channel site_id="268" xmltv_id="MTV00s.us">MTV 00s</channel>
|
||||
<channel site_id="302" xmltv_id="MTV80s.us">MTV 80s</channel>
|
||||
<channel site_id="266" xmltv_id="MTVHitsEurope.us">MTV Hits Europe</channel>
|
||||
<channel site_id="353" xmltv_id="MyZenTV.fr">MyZen TV</channel>
|
||||
<channel site_id="205" xmltv_id="N1Hrvatska.rs">N1 Hrvatska</channel>
|
||||
<channel site_id="182" xmltv_id="NarodniTV.hr">Narodni TV</channel>
|
||||
<channel site_id="382" xmltv_id="NationalGeographicHrvatska.us">National Geographic Hrvatska</channel>
|
||||
<channel site_id="370" xmltv_id="NationalGeographicWildEurope.us">National Geographic Wild Europe</channel>
|
||||
<channel site_id="315" xmltv_id="NauticalChannel.it">Nautical Channel</channel>
|
||||
<channel site_id="429" xmltv_id="NickJrCentralEasternEurope.us">Nick Jr Central & Eastern Europe</channel>
|
||||
<channel site_id="430" xmltv_id="NickelodeonEurope.us">Nickelodeon Europe</channel>
|
||||
<channel site_id="373" xmltv_id="NickelodeonHD.us">Nickelodeon HD</channel>
|
||||
<channel site_id="269" xmltv_id="NickMusic.us">NickMusic</channel>
|
||||
<channel site_id="364" xmltv_id="NicktoonsRomania.us">Nicktoons România</channel>
|
||||
<channel site_id="91" xmltv_id="NovaTV.hr">Nova TV</channel>
|
||||
<channel site_id="119" xmltv_id="OsjeckaTV.hr">Osječka TV</channel>
|
||||
<channel site_id="105" xmltv_id="OTV.hr">OTV</channel>
|
||||
<channel site_id="763" xmltv_id="OTVValentino.ba">OTV Valentino</channel>
|
||||
<channel site_id="612" xmltv_id="PickboxTV.hr">Pickbox TV</channel>
|
||||
<channel site_id="393" xmltv_id="Pikaboo.hr">Pikaboo</channel>
|
||||
<channel site_id="244" xmltv_id="Pink.rs">Pink</channel>
|
||||
<channel site_id="246" xmltv_id="PinkBH.rs">Pink BH</channel>
|
||||
<channel site_id="248" xmltv_id="PinkExtra.rs">Pink Extra</channel>
|
||||
<channel site_id="254" xmltv_id="PinkFashion.rs">Pink Fashion</channel>
|
||||
<channel site_id="251" xmltv_id="PinkFilm.rs">Pink Film</channel>
|
||||
<channel site_id="250" xmltv_id="PinkFolk1.rs">Pink Folk 1</channel>
|
||||
<channel site_id="253" xmltv_id="PinkKoncert.rs">Pink Koncert</channel>
|
||||
<channel site_id="245" xmltv_id="PinkM.rs">Pink M</channel>
|
||||
<channel site_id="249" xmltv_id="PinkMusic.rs">Pink Music</channel>
|
||||
<channel site_id="252" xmltv_id="PinkMusic2.rs">Pink Music 2</channel>
|
||||
<channel site_id="247" xmltv_id="PinkPlus.rs">Pink Plus</channel>
|
||||
<channel site_id="255" xmltv_id="PinkWorld.rs">Pink World</channel>
|
||||
<channel site_id="110" xmltv_id="PlavaVinkovacka.hr">Plava Vinkovačka</channel>
|
||||
<channel site_id="100" xmltv_id="PoljoprivrednaTV.hr">Poljoprivredna TV</channel>
|
||||
<channel site_id="297" xmltv_id="PrivateTV.nl">Private TV</channel>
|
||||
<channel site_id="320" xmltv_id="ProSiebenDeutschland.de">ProSieben Deutschland</channel>
|
||||
<channel site_id="284" xmltv_id="Rai1.it">Rai 1</channel>
|
||||
<channel site_id="324" xmltv_id="Rai2.it">Rai 2</channel>
|
||||
<channel site_id="257" xmltv_id="Rai3.it">Rai 3</channel>
|
||||
<channel site_id="325" xmltv_id="RaiScuola.it">Rai Scuola</channel>
|
||||
<channel site_id="275" xmltv_id="RT.ru">RT</channel>
|
||||
<channel site_id="455" xmltv_id="RTL2Hrvatska.de">RTL 2 Hrvatska</channel>
|
||||
<channel site_id="342" xmltv_id="RTLCrimeHrvatska.de">RTL Crime Hrvatska</channel>
|
||||
<channel site_id="319" xmltv_id="RTLDeutschland.de">RTL Deutschland</channel>
|
||||
<channel site_id="454" xmltv_id="RTLHrvatska.de">RTL Hrvatska</channel>
|
||||
<channel site_id="439" xmltv_id="RTLKockicaHrvatska.de">RTL Kockica Hrvatska</channel>
|
||||
<channel site_id="187" xmltv_id="RTLLivingHrvatska.de">RTL Living Hrvatska</channel>
|
||||
<channel site_id="307" xmltv_id="RTLPassionHrvatska.de">RTL Passion Hrvatska</channel>
|
||||
<channel site_id="339" xmltv_id="RTLZweiDeutschland.de">RTL Zwei Deutschland</channel>
|
||||
<channel site_id="288" xmltv_id="RTS1.rs">RTS 1</channel>
|
||||
<channel site_id="289" xmltv_id="RTS2.rs">RTS 2</channel>
|
||||
<channel site_id="721" xmltv_id="RTS3.rs">RTS 3</channel>
|
||||
<channel site_id="277" xmltv_id="RTSSvet.rs">RTS Svet</channel>
|
||||
<channel site_id="322" xmltv_id="Sat1Deutschland.de">Sat.1 Deutschland</channel>
|
||||
<channel site_id="116" xmltv_id="SBTV.hr">SBTV</channel>
|
||||
<channel site_id="231" xmltv_id="SkyNewsUK.uk">Sky News UK</channel>
|
||||
<channel site_id="502" xmltv_id="SlavonskaTV.hr">Slavonska TV</channel>
|
||||
<channel site_id="309" xmltv_id="Sport1.de">Sport 1</channel>
|
||||
<channel site_id="447" xmltv_id="SportKlub1Hrvatska.hu">Sport Klub 1 Hrvatska</channel>
|
||||
<channel site_id="755" xmltv_id="SportKlub10.hu">Sport Klub 10</channel>
|
||||
<channel site_id="448" xmltv_id="SportKlub2Srbija.hu">Sport Klub 2 Srbija</channel>
|
||||
<channel site_id="221" xmltv_id="SportKlub3.hu">Sport Klub 3</channel>
|
||||
<channel site_id="222" xmltv_id="SportKlub4.hu">Sport Klub 4</channel>
|
||||
<channel site_id="223" xmltv_id="SportKlub5.hu">Sport Klub 5</channel>
|
||||
<channel site_id="224" xmltv_id="SportKlub6.hu">Sport Klub 6</channel>
|
||||
<channel site_id="752" xmltv_id="SportKlub7.hu">Sport Klub 7</channel>
|
||||
<channel site_id="753" xmltv_id="SportKlub8.hu">Sport Klub 8</channel>
|
||||
<channel site_id="754" xmltv_id="SportKlub9.hu">Sport Klub 9</channel>
|
||||
<channel site_id="751" xmltv_id="SportKlubEsports.hu">Sport Klub Esports</channel>
|
||||
<channel site_id="313" xmltv_id="SportKlubGolf.hu">Sport Klub Golf</channel>
|
||||
<channel site_id="308" xmltv_id="SportKlubStart.hu">Sport Klub Start</channel>
|
||||
<channel site_id="96" xmltv_id="SPTV.hr">SPTV</channel>
|
||||
<channel site_id="299" xmltv_id="StingrayClassica.ca">Stingray Classica</channel>
|
||||
<channel site_id="267" xmltv_id="StingrayDjazz.ca">Stingray Djazz</channel>
|
||||
<channel site_id="323" xmltv_id="SuperRTLDeutschland.de">Super RTL Deutschland</channel>
|
||||
<channel site_id="113" xmltv_id="TelevizijaDalmacija.hr">Televizija Dalmacija</channel>
|
||||
<channel site_id="301" xmltv_id="ToonKids.hr">Toon Kids</channel>
|
||||
<channel site_id="115" xmltv_id="TrendTV.hr">Trend TV</channel>
|
||||
<channel site_id="773" xmltv_id="TRTWorld.tr">TRT World</channel>
|
||||
<channel site_id="121" xmltv_id="TVJadran.hr">TV Jadran</channel>
|
||||
<channel site_id="771" xmltv_id="TVKoperCapodistria.si">TV Koper-Capodistria</channel>
|
||||
<channel site_id="112" xmltv_id="TVNova.hr">TV Nova</channel>
|
||||
<channel site_id="104" xmltv_id="TVSabor.hr">TV Sabor</channel>
|
||||
<channel site_id="283" xmltv_id="TVSlovenija1.si">TV Slovenija 1</channel>
|
||||
<channel site_id="287" xmltv_id="TVSlovenija2.si">TV Slovenija 2</channel>
|
||||
<channel site_id="604" xmltv_id="TVZapad.hr">TV Zapad</channel>
|
||||
<channel site_id="124" xmltv_id="TVSibenik.hr">TV Šibenik</channel>
|
||||
<channel site_id="442" xmltv_id="TV1000Balkan.se">TV1000 Balkan</channel>
|
||||
<channel site_id="262" xmltv_id="TV5MondeEurope.fr">TV5Monde Europe</channel>
|
||||
<channel site_id="282" xmltv_id="TVCGSat.me">TVCG Sat</channel>
|
||||
<channel site_id="263" xmltv_id="TVEInternacionalEuropa.es">TVE Internacional Europa</channel>
|
||||
<channel site_id="388" xmltv_id="Vavoom.ch">Vavoom</channel>
|
||||
<channel site_id="386" xmltv_id="ViasatExploreEast.se">Viasat Explore East</channel>
|
||||
<channel site_id="385" xmltv_id="ViasatHistoryHrvatska.se">Viasat History Hrvatska</channel>
|
||||
<channel site_id="387" xmltv_id="ViasatNatureEast.se">Viasat Nature East</channel>
|
||||
<channel site_id="761" xmltv_id="VividRed.us">Vivid Red</channel>
|
||||
<channel site_id="762" xmltv_id="VividTouch.us">Vivid Touch</channel>
|
||||
<channel site_id="715" xmltv_id="VividTVEurope.us">Vivid TV Europe</channel>
|
||||
<channel site_id="256" xmltv_id="VoxDeutschland.de">Vox Deutschland</channel>
|
||||
<channel site_id="111" xmltv_id="VTV.hr">VTV</channel>
|
||||
<channel site_id="639" xmltv_id="Woman.hr">Woman</channel>
|
||||
<channel site_id="106" xmltv_id="Z1.hr">Z1</channel>
|
||||
<channel site_id="286" xmltv_id="ZDF.de">ZDF</channel>
|
||||
<channel site_id="272" xmltv_id="ZdravaTV.hr">Zdrava TV</channel>
|
||||
<channel site_id="258" xmltv_id="NTVMir.ru">НТВ Мир</channel>
|
||||
</channels>
|
||||
</site>
|
46
sites/maxtv.hrvatskitelekom.hr.config.js
Normal file
46
sites/maxtv.hrvatskitelekom.hr.config.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
const dayjs = require('dayjs')
|
||||
|
||||
module.exports = {
|
||||
lang: 'hr',
|
||||
site: 'maxtv.hrvatskitelekom.hr',
|
||||
channels: 'maxtv.hrvatskitelekom.hr.channels.xml',
|
||||
output: '.gh-pages/guides/maxtv.hrvatskitelekom.hr.guide.xml',
|
||||
request: {
|
||||
method: 'POST',
|
||||
data: function ({ channel, date }) {
|
||||
return {
|
||||
channelList: [channel.site_id],
|
||||
startDate: date.startOf('d').unix(),
|
||||
endDate: date.endOf('d').unix()
|
||||
}
|
||||
}
|
||||
},
|
||||
url: function ({ date, channel }) {
|
||||
return `https://player.maxtvtogo.tportal.hr:8082/OTT4Proxy/proxy/epg/shows`
|
||||
},
|
||||
logo: function ({ content }) {
|
||||
const json = JSON.parse(content)
|
||||
return json.data ? json.data[0].logo : null
|
||||
},
|
||||
parser: function ({ content }) {
|
||||
const programs = []
|
||||
const json = JSON.parse(content)
|
||||
if (!json.data) return programs
|
||||
|
||||
const items = json.data[0].shows
|
||||
items.forEach(item => {
|
||||
if (item.title && item.startTime && item.endTime) {
|
||||
const start = dayjs.unix(item.startTime)
|
||||
const stop = dayjs.unix(item.endTime)
|
||||
programs.push({
|
||||
title: item.title,
|
||||
category: item.category,
|
||||
start: start.toString(),
|
||||
stop: stop.toString()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return programs
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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')
|
||||
}
|
||||
|
|
109
sites/mncvision.id.channels.xml
Executable file
109
sites/mncvision.id.channels.xml
Executable file
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<site site="mncvision.id">
|
||||
<channels>
|
||||
<channel site_id="350" xmltv_id="ABCAustraliaAsia.au">ABC Australia Asia</channel>
|
||||
<channel site_id="331" xmltv_id="AlJazeeraEnglish.qa">Al Jazeera English</channel>
|
||||
<channel site_id="93" xmltv_id="AlQuranAlKareemTV.sa">Al Quran Al Kareem TV</channel>
|
||||
<channel site_id="203" xmltv_id="AnimalPlanetSoutheastAsia.us">Animal Planet Southeast Asia</channel>
|
||||
<channel site_id="157" xmltv_id="AnimaxAsia.jp">Animax Asia</channel>
|
||||
<channel site_id="115" xmltv_id="ANTV.id">ANTV</channel>
|
||||
<channel site_id="351" xmltv_id="ArirangWorld.kr">Arirang World</channel>
|
||||
<channel site_id="240" xmltv_id="AsianFoodNetwork.sg">Asian Food Network</channel>
|
||||
<channel site_id="154" xmltv_id="AXNEastAsia.us">AXN East Asia</channel>
|
||||
<channel site_id="40" xmltv_id="BabyTVAsia.uk">BabyTV Asia</channel>
|
||||
<channel site_id="200" xmltv_id="BBCEarthAsia.uk">BBC Earth Asia</channel>
|
||||
<channel site_id="332" xmltv_id="BBCWorldNewsAsiaPacific.uk">BBC World News Asia Pacific</channel>
|
||||
<channel site_id="305" xmltv_id="beINSports1Indonesia.qa">beIN Sports 1 Indonesia</channel>
|
||||
<channel site_id="306" xmltv_id="beINSports2Indonesia.qa">beIN Sports 2 Indonesia</channel>
|
||||
<channel site_id="103" xmltv_id="BeritaSatuNewsChannel.id">Berita Satu News Channel</channel>
|
||||
<channel site_id="112" xmltv_id="Besmart.id">Besmart</channel>
|
||||
<channel site_id="338" xmltv_id="BloombergTVAsia.us">Bloomberg TV Asia</channel>
|
||||
<channel site_id="39" xmltv_id="BoomerangSouthEastAsia.us">Boomerang South East Asia</channel>
|
||||
<channel site_id="47" xmltv_id="CartoonNetworkAsia.us">Cartoon Network Asia</channel>
|
||||
<channel site_id="41" xmltv_id="CBeebiesAsia.uk">CBeebies Asia</channel>
|
||||
<channel site_id="22" xmltv_id="CelestialClassicMovies.hk">Celestial Classic Movies</channel>
|
||||
<channel site_id="20" xmltv_id="CelestialMoviesIndonesia.hk">Celestial Movies Indonesia</channel>
|
||||
<channel site_id="353" xmltv_id="CGTN.cn">CGTN</channel>
|
||||
<channel site_id="205" xmltv_id="CGTNDocumentary.cn">CGTN Documentary</channel>
|
||||
<channel site_id="272" xmltv_id="ChannelVInternational.hk">Channel V International</channel>
|
||||
<channel site_id="8" xmltv_id="CinemaxAsia.us">Cinemax Asia</channel>
|
||||
<channel site_id="330" xmltv_id="CNA.sg">CNA</channel>
|
||||
<channel site_id="337" xmltv_id="CNBCAsiaPacific.us">CNBC Asia-Pacific</channel>
|
||||
<channel site_id="333" xmltv_id="CNNInternationalAsiaPacific.us">CNN International Asia Pacific</channel>
|
||||
<channel site_id="207" xmltv_id="CrimePlusInvestigationAsia.us">Crime + Investigation Asia</channel>
|
||||
<channel site_id="201" xmltv_id="DiscoveryChannelSoutheastAsia.us">Discovery Channel Southeast Asia</channel>
|
||||
<channel site_id="45" xmltv_id="DisneyChannelIndonesia.us">Disney Channel Indonesia</channel>
|
||||
<channel site_id="43" xmltv_id="DisneyJuniorAsia.us">Disney Junior Asia</channel>
|
||||
<channel site_id="357" xmltv_id="DWEnglish.de">DW English</channel>
|
||||
<channel site_id="86" xmltv_id="Ent.id">Ent</channel>
|
||||
<channel site_id="304" xmltv_id="FightSports.us">Fight Sports</channel>
|
||||
<channel site_id="150" xmltv_id="FMN.id">FMN</channel>
|
||||
<channel site_id="16" xmltv_id="FoxActionMovies.us">Fox Action Movies</channel>
|
||||
<channel site_id="152" xmltv_id="FoxCrimeAsia.us">Fox Crime Asia</channel>
|
||||
<channel site_id="15" xmltv_id="FoxFamilyMovies.us">Fox Family Movies</channel>
|
||||
<channel site_id="153" xmltv_id="FoxIndonesia.us">Fox Indonesia</channel>
|
||||
<channel site_id="156" xmltv_id="FoxLifeIndonesia.us">Fox Life Indonesia</channel>
|
||||
<channel site_id="14" xmltv_id="FoxMoviesIndonesia.us">Fox Movies Indonesia</channel>
|
||||
<channel site_id="335" xmltv_id="FoxNewsChannel.us">Fox News Channel</channel>
|
||||
<channel site_id="302" xmltv_id="FoxSports2Asia.us">Fox Sports 2 Asia</channel>
|
||||
<channel site_id="303" xmltv_id="FoxSports3Asia.us">Fox Sports 3 Asia</channel>
|
||||
<channel site_id="301" xmltv_id="FoxSportsAsia.us">Fox Sports Asia</channel>
|
||||
<channel site_id="352" xmltv_id="France24English.fr">France 24 English</channel>
|
||||
<channel site_id="81" xmltv_id="GTV.id">GTV</channel>
|
||||
<channel site_id="7" xmltv_id="HBOAsia.us">HBO Asia</channel>
|
||||
<channel site_id="9" xmltv_id="HBOFamilyAsia.us">HBO Family Asia</channel>
|
||||
<channel site_id="10" xmltv_id="HBOHits.us">HBO Hits</channel>
|
||||
<channel site_id="6" xmltv_id="HBOSignatureAsia.us">HBO Signature Asia</channel>
|
||||
<channel site_id="245" xmltv_id="HGTVAsia.us">HGTV Asia</channel>
|
||||
<channel site_id="206" xmltv_id="HistoryAsia.us">History Asia</channel>
|
||||
<channel site_id="160" xmltv_id="Hits.sg">Hits</channel>
|
||||
<channel site_id="11" xmltv_id="HitsMovies.sg">Hits Movies</channel>
|
||||
<channel site_id="100" xmltv_id="IDXChannel.id">IDX Channel</channel>
|
||||
<channel site_id="78" xmltv_id="Indosiar.id">Indosiar</channel>
|
||||
<channel site_id="83" xmltv_id="iNews.id">iNews</channel>
|
||||
<channel site_id="113" xmltv_id="JakTV.id">Jak TV</channel>
|
||||
<channel site_id="46" xmltv_id="KidsTV.id">Kids TV</channel>
|
||||
<channel site_id="161" xmltv_id="Kix.hk">Kix</channel>
|
||||
<channel site_id="106" xmltv_id="KompasTV.id">Kompas TV</channel>
|
||||
<channel site_id="91" xmltv_id="Life.id">Life</channel>
|
||||
<channel site_id="90" xmltv_id="LifestyleFashion.id">Lifestyle & Fashion</channel>
|
||||
<channel site_id="167" xmltv_id="LifetimeAsia.us">Lifetime Asia</channel>
|
||||
<channel site_id="107" xmltv_id="MetroTV.id">Metro TV</channel>
|
||||
<channel site_id="38" xmltv_id="MiaoMi.hk">Miao Mi</channel>
|
||||
<channel site_id="84" xmltv_id="MNCNews.id">MNC News</channel>
|
||||
<channel site_id="102" xmltv_id="MNCSports.id">MNC Sports</channel>
|
||||
<channel site_id="82" xmltv_id="MNCTV.id">MNCTV</channel>
|
||||
<channel site_id="88" xmltv_id="MShopSignature.id">MShop Signature</channel>
|
||||
<channel site_id="79" xmltv_id="MShopSuperSale.id">MShop Super Sale!</channel>
|
||||
<channel site_id="111" xmltv_id="MusicTV.id">Music TV</channel>
|
||||
<channel site_id="92" xmltv_id="MuslimTV.id">Muslim TV</channel>
|
||||
<channel site_id="247" xmltv_id="NatGeoPeopleAsia.us">Nat Geo People Asia</channel>
|
||||
<channel site_id="202" xmltv_id="NationalGeographicAsia.us">National Geographic Asia</channel>
|
||||
<channel site_id="204" xmltv_id="NationalGeographicWildAsia.us">National Geographic Wild Asia</channel>
|
||||
<channel site_id="116" xmltv_id="NET.id">NET.</channel>
|
||||
<channel site_id="355" xmltv_id="NHKWorldJapan.jp">NHK World Japan</channel>
|
||||
<channel site_id="354" xmltv_id="NHKWorldPremium.jp">NHK World Premium</channel>
|
||||
<channel site_id="37" xmltv_id="NickJrAsia.us">Nick Jr Asia</channel>
|
||||
<channel site_id="49" xmltv_id="NickelodeonSouthEastAsia.us">Nickelodeon South East Asia</channel>
|
||||
<channel site_id="95" xmltv_id="OKTV.id">OK TV</channel>
|
||||
<channel site_id="164" xmltv_id="One.in">One</channel>
|
||||
<channel site_id="80" xmltv_id="RCTI.id">RCTI</channel>
|
||||
<channel site_id="89" xmltv_id="SCTV.id">SCTV</channel>
|
||||
<channel site_id="336" xmltv_id="SEAToday.id">SEA Today</channel>
|
||||
<channel site_id="101" xmltv_id="SoccerChannel.id">Soccer Channel</channel>
|
||||
<channel site_id="24" xmltv_id="StarChineseMoviesLegend.hk">Star Chinese Movies Legend</channel>
|
||||
<channel site_id="18" xmltv_id="StarChineseMoviesSouthEastAsia.hk">Star Chinese Movies South East Asia</channel>
|
||||
<channel site_id="105" xmltv_id="TawafTV.id">Tawaf TV</channel>
|
||||
<channel site_id="19" xmltv_id="Thrill.hk">Thrill</channel>
|
||||
<channel site_id="248" xmltv_id="TLCSoutheastAsia.us">TLC Southeast Asia</channel>
|
||||
<channel site_id="110" xmltv_id="Trans7.id">Trans 7</channel>
|
||||
<channel site_id="87" xmltv_id="TransTV.id">Trans TV</channel>
|
||||
<channel site_id="25" xmltv_id="tvNMoviesIndonesia.kr">tvN Movies Indonesia</channel>
|
||||
<channel site_id="158" xmltv_id="tvNPremiumIndonesia.kr">tvN Premium Indonesia</channel>
|
||||
<channel site_id="97" xmltv_id="tvOne.id">tvOne</channel>
|
||||
<channel site_id="118" xmltv_id="TVRINasional.id">TVRI Nasional</channel>
|
||||
<channel site_id="94" xmltv_id="VisionPrime.id">Vision Prime</channel>
|
||||
<channel site_id="163" xmltv_id="WarnerTVSoutheastAsia.us">Warner TV Southeast Asia</channel>
|
||||
<channel site_id="23" xmltv_id="ZeeBioskop.in">Zee Bioskop</channel>
|
||||
</channels>
|
||||
</site>
|
81
sites/mncvision.id.config.js
Normal file
81
sites/mncvision.id.config.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
const FormData = require('form-data')
|
||||
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 = {
|
||||
lang: 'en',
|
||||
site: 'mncvision.id',
|
||||
channels: 'mncvision.id.channels.xml',
|
||||
output: '.gh-pages/guides/mncvision.id.guide.xml',
|
||||
request: {
|
||||
method: 'POST',
|
||||
data: function ({ channel, date }) {
|
||||
const formData = new FormData()
|
||||
formData.setBoundary('X-EPG-BOUNDARY')
|
||||
formData.append('search_model', 'channel')
|
||||
formData.append('af0rmelement', 'aformelement')
|
||||
formData.append('fdate', date.format('YYYY-MM-DD'))
|
||||
formData.append('fchannel', channel.site_id)
|
||||
formData.append('submit', 'Search')
|
||||
|
||||
return formData
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data; boundary=X-EPG-BOUNDARY'
|
||||
}
|
||||
},
|
||||
logo({ channel }) {
|
||||
return `https://www.mncvision.id/userfiles/image/channel/channel_${channel.site_id}.png`
|
||||
},
|
||||
url({ channel }) {
|
||||
return `https://www.mncvision.id/schedule/table`
|
||||
},
|
||||
parser({ content, date }) {
|
||||
const programs = []
|
||||
const items = parseItems(content)
|
||||
items.forEach(item => {
|
||||
const title = parseTitle(item)
|
||||
const start = parseStart(item, date)
|
||||
const duration = parseDuration(item)
|
||||
const stop = start.add(duration, 'm')
|
||||
|
||||
programs.push({ title, start, stop })
|
||||
})
|
||||
|
||||
return programs
|
||||
}
|
||||
}
|
||||
|
||||
function parseDuration(item) {
|
||||
let duration = (item.querySelector('td:nth-child(3)') || { textContent: '' }).textContent
|
||||
const match = duration.match(/(\d{2}):(\d{2})/)
|
||||
const hours = parseInt(match[1])
|
||||
const minutes = parseInt(match[2])
|
||||
|
||||
return hours * 60 + minutes
|
||||
}
|
||||
|
||||
function parseStart(item, date) {
|
||||
let time = (item.querySelector('td:nth-child(1)') || { textContent: '' }).textContent
|
||||
time = `${date.format('DD/MM/YYYY')} ${time}`
|
||||
|
||||
return dayjs.tz(time, 'DD/MM/YYYY HH:mm', 'Asia/Jakarta')
|
||||
}
|
||||
|
||||
function parseTitle(item) {
|
||||
return (item.querySelector('td:nth-child(2) > a') || { textContent: '' }).textContent
|
||||
}
|
||||
|
||||
function parseItems(content) {
|
||||
const dom = new JSDOM(content)
|
||||
|
||||
return dom.window.document.querySelectorAll('tr[valign="top"]')
|
||||
}
|
|
@ -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'
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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
93
sites/tvguide.com.channels.xml
Executable 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&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>
|
47
sites/tvguide.com.config.js
Normal file
47
sites/tvguide.com.config.js
Normal 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
1430
sites/tvprofil.com.channels.xml
Executable file
File diff suppressed because it is too large
Load diff
106
sites/tvprofil.com.config.js
Normal file
106
sites/tvprofil.com.config.js
Normal 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()
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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)`)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue