Compare commits

..
64 Commits
Author SHA1 Message Date
david f2959af0ac update readme
Build docker container / build (push) Successful in 3m33s
2026-10-27 10:52:21 +01:00
david 1062769e13 add fixes to pick.be provider 2026-10-27 10:45:02 +01:00
david bcfd38cb19 update custom fixes to latest code 2026-10-27 10:43:05 +01:00
david 3876463747 update readme
Build docker container / build (push) Successful in 3m5s
2026-10-25 15:52:20 +01:00
david 8411e28b0a update readme 2026-10-25 15:51:44 +01:00
david 5f228031e1 update readme
Build docker container / build (push) Successful in 4m4s
2026-10-23 14:28:36 +02:00
david 21881c43a7 update readme
Build docker container / build (push) Successful in 4m44s
2026-10-06 10:59:36 +02:00
david d72cc13659 update action 2026-09-30 15:40:07 +02:00
david 3a325f4cb3 update readme
Build docker container / build (push) Successful in 11m48s
2026-09-25 13:01:38 +02:00
david 59ba4f298e update readme
Build docker container / build (push) Successful in 15m16s
2026-09-08 13:09:58 +02:00
david fd1df8ac0b update readme 2026-08-05 11:33:24 +02:00
david 65c2ed8208 update build action 2026-08-05 11:27:01 +02:00
david 054adcd9ec update readme
Build docker container / build (push) Successful in 17m47s
2026-08-05 10:52:22 +02:00
david 51a830bb2c update readme and build action
Build docker container / build (push) Successful in 21m24s
2026-07-22 09:20:10 +02:00
david cedf4cb9cf update readme
Build docker container / build (push) Successful in 23m6s
2026-07-09 15:45:11 +02:00
david 09b2a32c7e update readme
Build docker container / build (push) Successful in 19m37s
2026-06-09 08:20:41 +02:00
david faf359760e update readme
Build docker container / build (push) Successful in 14m3s
2026-05-22 08:44:09 +02:00
david d1c2a2cce6 update readme
Build docker container / build (push) Successful in 21m35s
2026-04-17 08:34:17 +02:00
david f10acb48dd update readme
Build docker container / build (push) Successful in 10m44s
2026-04-13 09:59:08 +02:00
david 97b2e2b7c9 fix issues in docker file
Build docker container / build (push) Successful in 9m6s
2026-04-01 16:37:22 +02:00
david 421bebb294 update readme
Build docker container / build (push) Failing after 14m5s
2026-04-01 15:44:22 +02:00
david b77bf97acd update readme
Build docker container / build (push) Successful in 8m43s
2026-03-23 08:41:38 +01:00
david b671040deb update readme
Build docker container / build (push) Successful in 8m43s
2026-03-16 09:12:30 +01:00
david 86e66ede1d update readme and update custom fixes
Build docker container / build (push) Successful in 15m44s
2026-02-24 12:46:24 +01:00
david c113fd0bbc update readme
Build docker container / build (push) Successful in 10m25s
2026-02-18 12:56:29 +01:00
david 54f8e6b157 update action 2026-02-18 12:54:40 +01:00
david be44be878c change action
Build docker container / build (push) Successful in 7m33s
2026-02-12 10:17:30 +01:00
david 1700fbe251 update readme
Build docker container / build (push) Failing after 1m49s
2026-02-12 08:59:35 +01:00
david b760bbdf3e update action 2026-02-12 08:58:18 +01:00
david 8c609f5515 update action 2026-02-09 15:48:15 +01:00
david ff31a3b737 update action 2026-02-09 15:32:40 +01:00
david 123285107d update action
Build docker container / build (push) Successful in 8m2s
2026-02-09 10:16:06 +01:00
david 3d13569146 update action 2026-02-09 09:57:40 +01:00
david e9bc6f5246 update action
Build docker container / build (push) Failing after 6m51s
2026-02-09 09:37:49 +01:00
david 5c662bae69 update docker action + readme
Build docker container / build (push) Failing after 7m26s
2026-02-09 09:25:34 +01:00
David Claeys eece21742c update readme
Build docker container / build (push) Successful in 8m2s
2026-01-08 13:44:06 +01:00
David Claeys ee126cf60c update readme
Build docker container / build (push) Successful in 8m51s
2025-12-24 14:25:57 +01:00
David Claeys db28863295 update readme
Build docker container / build (push) Successful in 11m38s
2025-11-26 11:26:24 +01:00
David Claeys 223a4ea6b5 update readme
Build docker container / build (push) Successful in 7m36s
2025-11-19 10:53:46 +01:00
David Claeys e6ee948355 update readme
Build docker container / build (push) Successful in 9m23s
2025-10-09 14:18:30 +02:00
David Claeys 2662567576 update readme
Build docker container / build (push) Successful in 18m38s
2025-09-25 09:36:24 +02:00
David Claeys 309038bb4a update readme + config
Build docker container / build (push) Successful in 25m21s
2025-07-15 09:24:34 +02:00
David Claeys 3b019df919 update readme
Build docker container / build (push) Successful in 8m14s
2025-07-07 08:53:11 +02:00
David Claeys 1cf21ddb98 update readme
Build docker container / build (push) Successful in 8m52s
2025-06-27 11:15:21 +02:00
David Claeys 0aeb48fe2f update readme
Build docker container / build (push) Successful in 6m37s
2025-06-17 08:10:34 +02:00
David Claeys 70c7ee79b0 update readme
Build docker container / build (push) Successful in 8m4s
2025-06-02 11:13:55 +02:00
David Claeys 62937901c2 update readme
Build docker container / build (push) Successful in 6m34s
2025-05-16 08:42:21 +02:00
David Claeys 4e5a2b4d27 update readme
Build docker container / build (push) Successful in 6m3s
2025-04-23 08:43:25 +02:00
David Claeys ab9a8d7160 add delay option
Build docker container / build (push) Successful in 6m12s
2025-04-14 09:15:43 +02:00
David Claeys e080a976a6 update readme
Build docker container / build (push) Successful in 13m7s
2025-04-09 10:23:29 +02:00
David Claeys 252a7b23aa bugfixes
Build docker container / build (push) Failing after 20m44s
2025-04-07 09:02:22 +02:00
David Claeys 0a4d9c4452 update readme
Build docker container / build (push) Successful in 12m5s
2025-04-04 08:25:49 +02:00
David Claeys 6939823646 update readme
Build docker container / build (push) Successful in 7m3s
2025-03-27 08:32:17 +01:00
David Claeys 60503e87ed update readme
Build docker container / build (push) Successful in 7m23s
2025-03-20 10:00:44 +01:00
David Claeys 2f732b6dcc update readme
Build docker container / build (push) Successful in 6m14s
2025-03-11 08:09:05 +01:00
David Claeys 1f999d1c3c update readme
Build docker container / build (push) Successful in 4m55s
2025-03-07 09:11:14 +01:00
David Claeys 3f5b36a878 update readme
Build docker container / build (push) Successful in 5m10s
2025-02-26 08:41:29 +01:00
David Claeys f1c905f5dd update readme
Build docker container / build (push) Successful in 5m44s
2025-02-18 08:44:54 +01:00
David Claeys d83069f300 update pickx.be 2025-02-18 08:44:02 +01:00
David Claeys 092ad56487 update readme
Build docker container / build (push) Successful in 9m37s
2025-02-11 10:02:04 +01:00
David Claeys cfedd1e091 update build actions 2025-02-06 16:56:56 +01:00
David Claeys 7bf14e4f10 update readme
Build docker container / build (push) Successful in 5m2s
2025-02-05 09:04:30 +01:00
David Claeys 1521795dd8 update readme
Build docker container / build (push) Successful in 7m0s
2025-02-03 08:45:34 +01:00
David Claeys 645569dc97 update readme
Build docker container / build (push) Successful in 4m1s
2025-01-30 10:11:58 +01:00
13 changed files with 1082 additions and 583 deletions

No files matched your search

+24 -14
View File
@@ -8,21 +8,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
defaults: defaults:
run: run:
working-directory: ${{ GITHUB_WORKSPACE }} working-directory: ${{ github.workspace }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install Docker - name: Setup docker
run: | uses: https://git.claeyscloud.com/david/gitea-actions/setup-docker@main
echo "Checking docker installation"
if command -v docker &> /dev/null; then
echo "Docker installation found"
else
echo "Docker installation not found. Docker will be installed"
curl -fsSL https://get.docker.com | sh
fi
- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v3
- name: Login to Gitea container registry - name: Login to Gitea container registry
uses: https://github.com/docker/login-action@v3 uses: https://github.com/docker/login-action@v3
with: with:
@@ -32,18 +23,38 @@ jobs:
- name: Login to DockerHub container registry - name: Login to DockerHub container registry
uses: https://github.com/docker/login-action@v3 uses: https://github.com/docker/login-action@v3
with: with:
username: ${{ secrets.DOCKER_HUB_USERNAME}} username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }} password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Login to Lavaforge container registry
uses: https://github.com/docker/login-action@v3
with:
registry: lavaforge.org
username: ${{ secrets.LAVAFORGE_USERNAME }}
password: ${{ secrets.LAVAFORGE_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker - name: Extract metadata (tags, labels) for Docker
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
labels: |
org.opencontainers.image.title=epg-info
org.opencontainers.image.description=Docker image of https://github.com/iptv-org/epg
org.opencontainers.image.authors=Davidquinonescl
org.opencontainers.image.documentation=https://git.claeyscloud.com/david/epg-info-docker/src/branch/main/README.md
images: | images: |
davidquinonescl/epg-info davidquinonescl/epg-info
git.claeyscloud.com/david/epg-info git.claeyscloud.com/david/epg-info
lavaforge.org/davidquinonescl/epg-info
flavor: |
latest=true
tags: | tags: |
type=semver,pattern={{raw}} type=semver,pattern={{raw}}
type=sha type=sha
- name: Update docker Hub Description
uses: https://git.claeyscloud.com/david/gitea-actions/dockerhub-description@main
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
repository: davidquinonescl/epg-info
- name: Build and push - name: Build and push
uses: https://github.com/docker/build-push-action@v5 uses: https://github.com/docker/build-push-action@v5
with: with:
@@ -51,4 +62,3 @@ jobs:
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
+5
View File
@@ -24,6 +24,11 @@ jobs:
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
labels: |
org.opencontainers.image.title=epg-info
org.opencontainers.image.description=Docker image of https://github.com/iptv-org/epg
org.opencontainers.image.authors=Davidquinonescl
org.opencontainers.image.documentation=https://github.com/davidclaeysquinones/epg-info-docker/blob/main/README.md
images: ghcr.io/davidclaeysquinones/epg-info images: ghcr.io/davidclaeysquinones/epg-info
tags: | tags: |
type=semver,pattern={{raw}} type=semver,pattern={{raw}}
+14 -10
View File
@@ -1,9 +1,10 @@
FROM node:22-alpine FROM node:24-alpine
ARG GIT_REPO=https://github.com/iptv-org/epg.git ARG GIT_REPO=https://github.com/iptv-org/epg.git
ARG GIT_BRANCH=master ARG GIT_BRANCH=master
ENV CRON_SCHEDULE="0 0,12 * * *" ENV CRON_SCHEDULE="0 0,12 * * *"
ENV API_URL="https://iptv-org.github.io/api" ENV API_URL="https://iptv-org.github.io/api"
ENV DAYS=14 ENV DAYS=14
ENV DELAY=0
ENV MAX_CONNECTIONS=10 ENV MAX_CONNECTIONS=10
ENV ENABLE_FIXES=false ENV ENABLE_FIXES=false
ARG BIN_FOLDER=/bin ARG BIN_FOLDER=/bin
@@ -22,20 +23,22 @@ RUN apk update \
&& npm install pm2 -g \ && npm install pm2 -g \
&& mkdir $(echo "${BIN_FOLDER}/${EPG_FOLDER}") -p \ && mkdir $(echo "${BIN_FOLDER}/${EPG_FOLDER}") -p \
&& git -C $(echo "${BIN_FOLDER}") clone --depth 1 -b $(echo "${GIT_BRANCH} ${GIT_REPO}") \ && git -C $(echo "${BIN_FOLDER}") clone --depth 1 -b $(echo "${GIT_BRANCH} ${GIT_REPO}") \
&& cd $WORKDIR && npm install && npm update \ && cd $WORKDIR && npm install && npm update \
&& rm -rf .sites \ && rm -rf .sites \
&& rm -rf .husky \ && rm -rf .husky \
&& rm -rf .github \ && rm -rf .github \
&& rm -rf .git \ && rm -rf .git \
&& rm .gitignore \ && rm Dockerfile \
&& rm CONTRIBUTING.md \ && rm .gitignore \
&& rm LICENSE \ && rm -f CONTRIBUTING.md \
&& rm README.md \ && rm -f GUIDES.md \
&& rm SITES.md \ && rm -f LICENSE \
&& rm -f README.md \
&& rm -f SITES.md \
&& rm -rf tests \ && rm -rf tests \
&& rm sites/**/readme.md \ && rm -f sites/**/readme.md \
&& rm -rf sites/**/__data__ \ && rm -rf sites/**/__data__ \
&& rm sites/**/**.test.js \ && rm -f sites/**/**.test.js \
&& rm -rf node_modules/**/.package-lock.json \ && rm -rf node_modules/**/.package-lock.json \
&& rm -rf node_modules/**/.tsconfig.json \ && rm -rf node_modules/**/.tsconfig.json \
&& rm -rf node_modules/**/.tsconfig.tsbuildinfo.json \ && rm -rf node_modules/**/.tsconfig.tsbuildinfo.json \
@@ -52,9 +55,10 @@ RUN apk update \
&& mkdir /public && mkdir /public
COPY start.sh $WORKDIR COPY start.sh $WORKDIR
COPY serve.json $WORKDIR COPY serve.json $WORKDIR
COPY pm2.config.js $WORKDIR
RUN chmod +x "$START_SCRIPT" \ RUN chmod +x "$START_SCRIPT" \
&& apk del git curl \ && apk del git curl \
&& rm -rf /var/cache/apk/* && rm -rf /var/cache/apk/*
SHELL ["/bin/bash", "-c"] SHELL ["/bin/bash", "-c"]
ENTRYPOINT bash $START_SCRIPT chron-schedule="$CRON_SCHEDULE" work-dir="$WORKDIR" days="$DAYS" max_connections="$MAX_CONNECTIONS" enable_fixes="$ENABLE_FIXES" api_url="$API_URL" ENTRYPOINT bash $START_SCRIPT chron-schedule="$CRON_SCHEDULE" work-dir="$WORKDIR" days="$DAYS" delay=$DELAY max_connections="$MAX_CONNECTIONS" enable_fixes="$ENABLE_FIXES" api_url="$API_URL"
EXPOSE 3000 EXPOSE 3000
+122 -18
View File
@@ -4,14 +4,20 @@ This repo builds and Docker image of [iptv-org/epg](https://github.com/iptv-org/
The purpose is to make the deployment easier and more suitable for different environments. The purpose is to make the deployment easier and more suitable for different environments.
The original repository of this image is hosted on https://git.claeyscloud.com/david/epg-info-docker.<br> The original repository of this image is hosted on https://git.claeyscloud.com/david/epg-info-docker.<br>
A public mirror is available at https://github.com/davidclaeysquinones/epg-info-docker. A mirror of this repository can be found in https://github.com/davidclaeysquinones/epg-info-docker and in [lavaforge](https://lavaforge.org/davidquinonescl/epg-info-docker).
The image is distributed in the following container registries :
- [gitea](https://git.claeyscloud.com/david/-/packages/container/epg-info/latest)
- [lavaforge](https://lavaforge.org/davidquinonescl/-/packages/container/epg-info/latest)
- [github](https://github.com/davidclaeysquinones/epg-info-docker/pkgs/container/epg-info)
- [docker hub](https://hub.docker.com/repository/docker/davidquinonescl/epg-info/general)
## Dependencies ## Dependencies
[Node](https://nodejs.org/en)<br> [Node](https://nodejs.org/en)<br>
[pm2](https://www.npmjs.com/package/pm2)<br> [pm2](https://www.npmjs.com/package/pm2)<br>
[serve](https://www.npmjs.com/package/serve)<br> [serve](https://www.npmjs.com/package/serve)<br>
The image is based on `node:22-alpine` in order to be more lightweight. The image is based on `node:24-alpine` in order to be more lightweight.
The `pm2` and `serve` packages are used in order to run the application in the container. The `pm2` and `serve` packages are used in order to run the application in the container.
## Docker image ## Docker image
@@ -40,11 +46,11 @@ This the list of the provided custom fixes :
| Provider | Author(s) | Status | | Provider | Author(s) | Status |
|--------------------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| |--------------------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| movistarplus.es | [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2440) pending approval | | movistarplus.es | | |
| orangetv.orange.es | [fraudiay79](https://github.com/fraudiay79) and [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2485) merged since commit [8a8262e](https://github.com/iptv-org/epg/commit/8a8262eacb46b2d35df7eb11f46de22263eab053) | | orangetv.orange.es | | |
| pickx.be | [davidclaeysquinones](https://github.com/davidclaeysquinones) and [BellezaEmporium](https://github.com/BellezaEmporium) | [PR](https://github.com/iptv-org/epg/pull/2525) merged since commit [fd91a9c](https://github.com/iptv-org/epg/commit/fd91a9c532b476f6e192a564371d30e766b762ab) | | pickx.be | [davidclaeysquinones](https://github.com/davidclaeysquinones) | In testing |
| telenet.tv | [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2429) merged since commit [fd382db](https://github.com/iptv-org/epg/commit/fd382db08da7a96150928b8dcfef115e29e661d3) | | telenet.tv | | |
| web.magentatv.de | [klausellus-wallace](https://github.com/klausellus-wallace) | [PR](https://github.com/iptv-org/epg/pull/2458) merged since commit [61afe09](https://github.com/iptv-org/epg/commit/61afe090b6e7892cc5426457d960e9452222f885) | | web.magentatv.de | | |
If for some reason you want to include your own provider fixes this is possible by creation a mapping in the `/fixes` folder.<br> If for some reason you want to include your own provider fixes this is possible by creation a mapping in the `/fixes` folder.<br>
The expected structure is */fixes/`provider_name`/`provider_name`.config.js*.<br> The expected structure is */fixes/`provider_name`/`provider_name`.config.js*.<br>
@@ -56,6 +62,7 @@ It is recommended that you take existing provider code as a base for your custom
|-------------------------------|----------------------------------------------------------------------------|----------------------------------| |-------------------------------|----------------------------------------------------------------------------|----------------------------------|
| CRON_SCHEDULE | CRON expression describing the recurrence for epg retrieval. | `0 0,12 * * *` | | CRON_SCHEDULE | CRON expression describing the recurrence for epg retrieval. | `0 0,12 * * *` |
| DAYS | Describes the desired amount of days in the future for for epg retrieval. | 14 | | DAYS | Describes the desired amount of days in the future for for epg retrieval. | 14 |
| DELAY | Delay between requests in milliseconds | 0 |
| MAX_CONNECTIONS | The maximum amount of parallel connections that can be established | 10 | | MAX_CONNECTIONS | The maximum amount of parallel connections that can be established | 10 |
| ENABLE_FIXES | Some fixes to providers take a long time to be merged into the main branch.<br>When this option is enabled some of these fixes will also be included.<br>The source code for these fixes can be seen under the `fixes` folder.<br> Recreate the container when changing this variable in order for it to take effect | false | | ENABLE_FIXES | Some fixes to providers take a long time to be merged into the main branch.<br>When this option is enabled some of these fixes will also be included.<br>The source code for these fixes can be seen under the `fixes` folder.<br> Recreate the container when changing this variable in order for it to take effect | false |
| API_URL | The endpoint where channel information will be grabbed | `https://iptv-org.github.io/api` | | API_URL | The endpoint where channel information will be grabbed | `https://iptv-org.github.io/api` |
@@ -165,24 +172,121 @@ Sometimes a new version of this image will be bound to the same source commit. T
- 1.0.36 - 1.0.36
[12-31-2024 17:32](https://github.com/iptv-org/epg/commit/5ffe285c1e5882e905c5aaee672849f6f89e5cf3) [12-31-2024 17:32](https://github.com/iptv-org/epg/commit/5ffe285c1e5882e905c5aaee672849f6f89e5cf3)
- 1.0.37 - 1.0.37
[09-01-2025](https://github.com/iptv-org/epg/commit/8e39af2a4d7c15f442a3e686144278e97151d46e) [01-09-2025](https://github.com/iptv-org/epg/commit/8e39af2a4d7c15f442a3e686144278e97151d46e)
- 1.0.38 - 1.0.38
[13-01-2025](https://github.com/iptv-org/epg/commit/9a565f16f4016e49d17b762477e0f6d29bb0f970) [01-13-2025](https://github.com/iptv-org/epg/commit/9a565f16f4016e49d17b762477e0f6d29bb0f970)
- 1.0.39 - 1.0.39
[14-01-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608) [01-14-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608)
- 1.0.40 - 1.0.40
[14-01-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608)<br> Fixes issue with api url [01-14-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608)<br> Fixes issue with api url
- 1.0.41 - 1.0.41
[15-01-2025](https://github.com/iptv-org/epg/commit/65331dff1c6728c3012e314e51d40da85d2d7f3c) [01-15-2025](https://github.com/iptv-org/epg/commit/65331dff1c6728c3012e314e51d40da85d2d7f3c)
- 1.0.42 - 1.0.42
[15-01-2025](https://github.com/iptv-org/epg/commit/5958c77c65a652285da64ad8a77d137306ca46d7) [01-15-2025](https://github.com/iptv-org/epg/commit/5958c77c65a652285da64ad8a77d137306ca46d7)
- 1.0.43 - 1.0.43
[20-01-2025](https://github.com/iptv-org/epg/commit/7b2cfba7f5d4df8c01ff74a7c26d7695cb750244) [01-20-2025](https://github.com/iptv-org/epg/commit/7b2cfba7f5d4df8c01ff74a7c26d7695cb750244)
- 1.0.44 - 1.0.44
[21-01-2025](https://github.com/iptv-org/epg/commit/b69d61af5e46cea4f7dcb15a00d897397c23defa) [01-21-2025](https://github.com/iptv-org/epg/commit/b69d61af5e46cea4f7dcb15a00d897397c23defa)
- 1.0.45 - 1.0.45
[23-01-2025](https://github.com/iptv-org/epg/commit/bc4b7fcfd51325cc597ccce13821f355dd0fbc72) [01-23-2025](https://github.com/iptv-org/epg/commit/bc4b7fcfd51325cc597ccce13821f355dd0fbc72)
- 1.0.46 - 1.0.46
[27-01-2025](https://github.com/iptv-org/epg/commit/a45a346ec83cae3863b8d0e1cbe7abd99d6fef36) [01-27-2025](https://github.com/iptv-org/epg/commit/a45a346ec83cae3863b8d0e1cbe7abd99d6fef36)
- 1.0.47 - 1.0.47
[29-01-2025](https://github.com/iptv-org/epg/commit/106ae083d243df825958dcf4fea1d48d2765cf72) [01-29-2025](https://github.com/iptv-org/epg/commit/106ae083d243df825958dcf4fea1d48d2765cf72)
- 1.0.48
[01-30-2025](https://github.com/iptv-org/epg/commit/e57dfaff41f498ffbfe79ecadd37f7f254dad0cc)
- 1.0.49
[02-02-2025](https://github.com/iptv-org/epg/commit/6b45cd9bd60058fdb7b974ad610c2d6565317f3b)
- 1.0.50
[02-05-2025](https://github.com/iptv-org/epg/commit/7f6849869f7182ddfa1a01b08a160ff8d2129441)
- 1.0.51
[02-11-2025](https://github.com/iptv-org/epg/commit/6cbe64f2dde47a3eb042cac35932989a7eefb2db)
- 1.0.52
[02-18-2025](https://github.com/iptv-org/epg/commit/39c4c5143e7cf7591ac49227e73e564be70c7615)
- 1.0.53
[02-23-2025](https://github.com/iptv-org/epg/commit/2721fe1ba06761fd06799a233dda27af6184fd17)
- 1.0.54
[03-07-2025](https://github.com/iptv-org/epg/commit/40c9af82d6f7f4e562cd239237fdf46a396d5728)
- 1.0.55
[03-11-2025](https://github.com/iptv-org/epg/commit/40c9af82d6f7f4e562cd239237fdf46a396d5728)
- 1.0.56
[03-16-2025](https://github.com/iptv-org/epg/commit/cf82b4089ef00c1fc94b7751652bfa598f8ab06a)
- 1.0.57
[03-25-2025](https://github.com/iptv-org/epg/commit/138842009bb3f9135430cdc667502ffa51d4a295)
- 1.0.58
[04-04-2025](https://github.com/iptv-org/epg/commit/4df25c92bcad1e4892640f532eae71cf9f5e7b95)
- 1.0.59
[04-04-2025](https://github.com/iptv-org/epg/commit/4df25c92bcad1e4892640f532eae71cf9f5e7b95)<br>Includes fixes for new configuration changes
- 1.0.60
[04-07-2025](https://github.com/iptv-org/epg/commit/7e1fbcbe154f4efd5c81341351cceb06f71b79a0)
- 1.0.61
[04-07-2025](https://github.com/iptv-org/epg/commit/7e1fbcbe154f4efd5c81341351cceb06f71b79a0)<br>Add delay option
- 1.0.62
[04-22-2025](https://github.com/iptv-org/epg/commit/db56a4d6c0ec7f1169ae60361b623dc032365e47)
- 1.0.63
[05-10-2025](https://github.com/iptv-org/epg/commit/db56a4d6c0ec7f1169ae60361b623dc032365e47)
- 1.0.64
[06-02-2025](https://github.com/iptv-org/epg/commit/cb7e91d3938804618625e381a7fd139e11dfa380)
- 1.0.65
[06-16-2025](https://github.com/iptv-org/epg/commit/e0fdf221e2d2707fe7a9d06a4c2797672888c0eb)
- 1.0.66
[06-26-2025](https://github.com/iptv-org/epg/commit/93f857f3c36cbe00e76fceb4ad875d8e6f6ec6aa)
- 1.0.67
[07-07-2025](https://github.com/iptv-org/epg/commit/3107571168eea356e6fa6311519e3777db99b5a6)
- 1.0.68
[07-14-2025](https://github.com/iptv-org/epg/commit/10685b064d9cc65c1a22234a19527da53d544cbf)
- 1.0.69
[09-21-2025](https://github.com/iptv-org/epg/commit/69774a7e6a2c752d769ad5dfdc41b3fe4baeace1)
- 1.0.70
[10-07-2025](https://github.com/iptv-org/epg/commit/eebfcc8278dc31e9ef17ebbd298d4af061cdc23f)
- 1.0.71
[11-15-2025](https://github.com/iptv-org/epg/commit/4ed1e39d95da18d54628525f9173b7b7f7ae1d21)
- 1.0.72
[11-23-2025](https://github.com/iptv-org/epg/commit/9b331e6cfab19ad2f683b212aa079aac07fe72fe)
- 1.0.73
[12-24-2025](https://github.com/iptv-org/epg/commit/ba1fb58194464a6c50a597ac28a35dc8a4895038)
- 1.0.74
[01-06-2026](https://github.com/iptv-org/epg/commit/cbe17252ca7ef70780600952cf97790f352c8c15)
- 1.0.75
[02-07-2026](https://github.com/iptv-org/epg/commit/c1b3ef5a0e22979ffe06e4e688366eadc05b8537)
- 1.0.76
[02-10-2026](https://github.com/iptv-org/epg/commit/de08d7df85184bb6418cabf56501a9faed2889be)
- 1.0.77
[02-18-2026](https://github.com/iptv-org/epg/commit/a1168b74f5d51a26fdf51129c9af7a296f04b9f6)
- 1.0.78
[02-23-2026](https://github.com/iptv-org/epg/commit/e4f92bb2a2768dcba3dbbd52b19d78d96bebc31e)
<br>Updates custom fixes to latest code
<br>Includes fix for pickx.be provider
- 1.0.79
[03-16-2026](https://github.com/iptv-org/epg/commit/d10c95f326b8c36798c47e63bfd28ec0f116f974)
- 1.0.80
[03-23-2026](https://github.com/iptv-org/epg/commit/9d6339bf0f22444fa8967f0a5b2af64d13a7cdc3)
- 1.0.81
[04-01-2026](https://github.com/iptv-org/epg/commit/03250d4a07eae90200d9e0af6962776e91d7a0c1)
- 1.0.82
[04-13-2026](https://github.com/iptv-org/epg/commit/d27160fd2b8f0509e76de0463aa5f6466c832095)
- 1.0.83
[04-17-2026](https://github.com/iptv-org/epg/commit/ce691529a58dbf9d4776563aea6dec8cd0914c06)
- 1.0.84
[05-19-2026](https://github.com/iptv-org/epg/commit/157e77c50b08aa587e126095cedc330716d78fa0)
- 1.0.85
[06-09-2026](https://github.com/iptv-org/epg/commit/ed40bb597a0c538368988822e1c0413d370a4d5c)
- 1.0.86
[07-09-2026](https://github.com/iptv-org/epg/commit/0d5e1ff08b7a133f157d18fd945792498d5ea6cb)
- 1.0.87
[07-19-2026](https://github.com/iptv-org/epg/commit/1525e895fad70151e1895691bbf2e3426bf65920)
- 1.0.88
[08-05-2026](https://github.com/iptv-org/epg/commit/a7ce846b4e761ed37cfb968dc774d693a986fc88)
- 1.0.89
[09-02-2026](https://github.com/iptv-org/epg/commit/335458005387e07417a98399eb423c78d62a3bd9)
- 1.0.90
[09-21-2026](https://github.com/iptv-org/epg/commit/c5a88bcc6b09d75b32a0b22e6312db785cd9eb80)
- 1.0.91
[10-04-2026](https://github.com/iptv-org/epg/commit/aab705c6b90decfad2c9b27d1d6dbc8eeab9bbfd)
- 1.0.92
[10-23-2026](https://github.com/iptv-org/epg/commit/4abfae092f79fd3808ccadab65dc1873bcf6d259)
- 1.0.93
[10-25-2026](https://github.com/iptv-org/epg/commit/916c225d0a5e44534f09853674769c57005e61e5)
- 1.0.94
[10-26-2026](https://github.com/iptv-org/epg/commit/2c3e24fdab86140181878af00e01e9b440962d9b)
<br> Add fix for Pickx.be provder
+88 -28
View File
@@ -1,59 +1,119 @@
//https://github.com/iptv-org/epg/blob/master/sites/movistarplus.es/movistarplus.es.config.js
const axios = require('axios') const axios = require('axios')
const cheerio = require('cheerio')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const timezone = require('dayjs/plugin/timezone')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.tz.setDefault('Europe/Madrid')
module.exports = { module.exports = {
site: 'movistarplus.es', site: 'movistarplus.es',
days: 2, days: 2,
url({ channel, date }) { url({ channel, date }) {
return `https://www.movistarplus.es/programacion-tv/${channel.site_id}/${date.format( return `https://ottcache.dof6.com/movistarplus/webplayer/OTT/epg?from=${date.format('YYYY-MM-DDTHH:mm:ss')}&span=1&channel=${channel.site_id}&version=8&mdrm=true&tlsstream=true&demarcation=18`
'YYYY-MM-DD'
)}`
}, },
parser({ content }) { request: {
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'es-ES,es;q=0.9,en;q=0.8',
Referer: 'https://www.movistarplus.es/programacion-tv'
},
maxRedirects: 5
},
async parser({ content }) {
let programs = [] let programs = []
let items = parseItems(content) let items = await parseItems(content)
if (!items.length) return programs if (!items.length) return programs
items.forEach(el => { items.forEach(el => {
programs.push({ programs.push({
title: el.item.name, title: el.title,
start: dayjs(el.item.startDate), description: el.description,
stop: dayjs(el.item.endDate) icon: el.icon,
images: el.images,
season: el.season,
episode: el.episode,
start: el.start,
stop: el.stop
}) })
}) })
return programs return programs
}, },
async channels() { async channels() {
const html = await axios const json = await axios
.get('https://www.movistarplus.es/programacion-tv') .get(
'https://ottcache.dof6.com/movistarplus/webplayer/OTT/contents/channels?mdrm=true&tlsstream=true&demarcation=18&version=8'
)
.then(r => r.data) .then(r => r.data)
.catch(console.log) .catch(console.log)
const $ = cheerio.load(html) // Load JSON, CodCadenaTv is the closest to the old MVSTR site ch. ID
let scheme = $('script:contains(ItemList)').html() return json.map(channel => {
scheme = JSON.parse(scheme)
return scheme.itemListElement.map(el => {
const urlParts = el.item.url.split('/')
const site_id = urlParts.pop().toLowerCase()
return { return {
lang: 'es', lang: 'es',
name: el.item.name, site_id: channel.CodCadenaTv,
site_id name: channel.Nombre,
logo: channel.Logo || channel.Logos?.[0]?.uri || null
} }
}) })
} }
} }
function parseItems(content) { function parseImages(images) {
try { return images.filter(image => image.id === 'watch2tgr-end').map(image => image.uri)
const $ = cheerio.load(content) }
let scheme = $('script:contains("@type": "ItemList")').html()
scheme = JSON.parse(scheme)
if (!scheme || !Array.isArray(scheme.itemListElement)) return []
return scheme.itemListElement async function parseItems(content) {
try {
const data = JSON.parse(content)
const programs = Array.isArray(data) ? data : [data]
return await Promise.all(
programs.map(async json => {
const start = dayjs.utc(Number(json?.FechaHoraInicio))
const stop = dayjs.utc(Number(json?.FechaHoraFin))
const ficha = json?.Ficha || null
if (!ficha) {
return {
title: json?.Titulo || '',
description: json?.Resena || '',
icon: json?.Imagen || '',
images: json.Imagenes ? parseImages(json.Imagenes) : [],
start,
stop
}
} else {
try {
const fichaJson = await axios.get(ficha).then(r => r.data)
return {
title: json?.Titulo || fichaJson?.Titulo || '',
description: fichaJson?.Descripcion || json?.Resena || '',
icon: fichaJson?.Imagen || '',
images: fichaJson.Imagenes ? parseImages(fichaJson.Imagenes) : [],
actors: fichaJson?.Actores || [],
directors: fichaJson?.Directores || [],
classification: fichaJson?.Clasificacion || '',
season: fichaJson?.Temporada || null,
episode: fichaJson?.NumeroEpisodio || null,
start,
stop
}
} catch {
return {
title: json?.Titulo || '',
description: json?.Resena || '',
icon: json?.Imagen || '',
images: json.Imagenes ? parseImages(json.Imagenes) : [],
start,
stop
}
}
}
})
)
} catch { } catch {
return [] return []
} }
@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="orangetv.orange.es" lang="es" xmltv_id="La1.es" site_id="1010">LA 1 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="La2.es" site_id="1062">La 2 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="24Horas.es" site_id="12051">24 Horas</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Teledeporte.es" site_id="1063">TDP HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Clan.es" site_id="1064">Clan HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Antena3.es" site_id="1011">Antena 3 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Cuatro.es" site_id="1012">Cuatro HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Telecinco.es" site_id="1013">Telecinco HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaSexta.es" site_id="1014">laSexta HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Selekt.es" site_id="11045">SELEKT</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="StarChannelSpain.es" site_id="11001">STAR Channel</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AMC.es" site_id="11011">AMC</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AMCBreak.es" site_id="11009">AMC Break</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AMCCrime.es" site_id="11042">AMC CRIME</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="WarnerTV.es" site_id="11007">Warner TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AXN.es" site_id="11002">AXN</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ComedyCentral.es" site_id="11005">Comedy Central</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Calle13Universal.es" site_id="11003">Calle 13</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="XTRM.es" site_id="12057">XTRM</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Syfy.es" site_id="11004">SYFY</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="COSMO.es" site_id="11006">Cosmo</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Enfamilia.es" site_id="11063">Enfamilia</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Decasa.es" site_id="11027">Decasa</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CanalCocina.es" site_id="11020">CanalCocina</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeSeries.es" site_id="11093">Runtime Series</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="FactoriadeFiccion.es" site_id="1032">FDF</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Neox.es" site_id="1027">Neox</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Energy.es" site_id="1030">Energy</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Atreseries.es" site_id="1042">Atreseries</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Divinity.es" site_id="1034">Divinity</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Nova.es" site_id="1028">Nova</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CanalHollywood.es" site_id="11010">Canal Hollywood</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AXNMovies.es" site_id="11008">AXN Movies</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Somos.es" site_id="11029">Somos</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TCM.es" site_id="11012">TCM</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="SundanceTV.es" site_id="11052">Sundance TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Dark.es" site_id="11053">Dark</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeCineSeries.es" site_id="1089">Runtime Cine y Series</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeThriller.es" site_id="11091">Runtime Thriller/Terror</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeAccion.es" site_id="11094">Runtime Acción</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeComedia.es" site_id="11092">Runtime Comedia</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeCrimen.es" site_id="11095">Runtime Crimen</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RuntimeRomance.es" site_id="11096">Runtime Romance</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RunTimeClasicos.es" site_id="11097">RunTime Clásicos</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CinesVerdi.es" site_id="11098">Cines Verdi TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CineFeelGood.es" site_id="11099">Cine Feel Good</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ParamountNetwork.es" site_id="12032">Paramount Network</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DreamWorksChannel.es" site_id="1085">Dreamworks</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="BomCine.es" site_id="2063">Bom Cine</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DKISS.es" site_id="1044">DKISS</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TEN.es" site_id="12054">Ten</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Odisea.es" site_id="11018">Odisea</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Mega.es" site_id="1016">Mega</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Trece.es" site_id="1017">TR3CE</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DMAX.es" site_id="1018">DMAX</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaOtra.es" site_id="2061">La otra HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Boing.es" site_id="1021">Boing</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ToonGogglesenEspanol.us" site_id="11100">Toon Goggles</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NickJr.es" site_id="11055">Nick JR</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DisneyJunior.es" site_id="11015">Disney Junior</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Nickelodeon.es" site_id="11016">Nick</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="BeMad.es" site_id="1043">Be Mad TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Historia.es" site_id="11019">Canal Historia</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NationalGeographic.es" site_id="11017">National Geographic</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NationalGeographicWild.es" site_id="1008">NatGeo Wild</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DiscoveryChannel.es" site_id="1039">Discovery</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NatureTime.es" site_id="1084">NatureTime</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="La7.es" site_id="2011">7RM HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LevanteTV.es" site_id="2070">Levante TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CanalSur.es" site_id="1035">Canal Sur</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CanalSur2.es" site_id="2022">CanalSur 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CanalSurAndalucia.es" site_id="2031">Andalucía TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="7TVAndalucia.e" site_id="2065">7 TV Andalucia</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TV3.es" site_id="2008">TV3 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TV3CAT.es" site_id="1036">TV3CAT</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="324.es" site_id="2050">3/24</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TelevisioCastello.es" site_id="2067">TV Castellon</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="La8Mediterraneo.es" site_id="2062">8 Mediterraneo</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="APunt.es" site_id="2057">A punt HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="IB3.es" site_id="2013">IB3 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TelevisionCanaria.es" site_id="2059">RTV Canaria HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ETB1.es" site_id="2014">ETB1 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ETB2.es" site_id="1037">ETB2 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ETB3.es" site_id="2032">ETB3</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ETB4.es" site_id="2037">ETB4</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ETBBasque.es" site_id="1037">ETB Basque</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="GaliciaTVEuropa.es" site_id="2052">TVG HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TVG2.es" site_id="2053">TVG2 HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TPA7.es" site_id="2009">TPA HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TeleVigo.es" site_id="2068">Televigo</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="GaliciaTVEuropa.es" site_id="1038">Galicia TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CeutaTV.es" site_id="2002">TV Ceuta</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TVR.es" site_id="2055">TVR HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NavarraTV.es" site_id="2060">Navarra TV HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NavarraTV2.es" site_id="2029">Navarra TV2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Telemadrid.es" site_id="12050">Telemadrid HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="RealMadridTV.es" site_id="12052">Real Madrid</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="SevillaFCTV.es" site_id="2081">SEVILLA FC Televisión</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="BetisTV.es" site_id="1019">Betis TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeonesporMovistarPlusPlus.es" site_id="1023">M+ Liga de Campeones</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones1porMovistarPlusPlus.es" site_id="1050">M+ Liga de Campeones 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones2porMovistarPlusPlus.es" site_id="1051">M+ Liga de Campeones 3</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones3porMovistarPlusPlus.es" site_id="1052">M+ Liga de Campeones 4</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones4porMovistarPlusPlus.es" site_id="1053">M+ Liga de Campeones 5</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones5porMovistarPlusPlus.es" site_id="1054">M+ Liga de Campeones 6</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones6porMovistarPlusPlus.es" site_id="1055">M+ Liga de Campeones 7</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones7porMovistarPlusPlus.es" site_id="1056">M+ Liga de Campeones 8</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones8porMovistarPlusPlus.es" site_id="11036">M+ Liga de Campeones 9</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones9porMovistarPlusPlus.es" site_id="1096">M+ Liga de Campeones 10</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones10porMovistarPlusPlus.es" site_id="1097">M+ Liga de Campeones 11</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones11porMovistarPlusPlus.es" site_id="1098">M+ Liga de Campeones 12</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones12porMovistarPlusPlus.es" site_id="1099">M+ Liga de Campeones 13</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones13porMovistarPlusPlus.es" site_id="11065">M+ Liga de Campeones 14</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones14porMovistarPlusPlus.es" site_id="11066">M+ Liga de Campeones 15</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones15porMovistarPlusPlus.es" site_id="11067">M+ Liga de Campeones 16</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LigadeCampeones16porMovistarPlusPlus.es" site_id="11068">M+ Liga de Campeones 17</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaTVUHDporMovistarPlusPlus.es" site_id="11043">M LALIGA TV UHD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaTVporMovistarPlusPlus.es" site_id="11013">M+ LALIGA TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLiga1porMovistarPlusPlus.es" site_id="11026">M+ LALIGA TV 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaTV2porMovistarPlusPlus.es" site_id="1057">M+ LALIGATV 3</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaTV3porMovistarPlusPlus.es" site_id="1058">M+ LALIGATV 4</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaTV.es" site_id="11129">LA LIGA TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DAZNLaLiga.es" site_id="11077">DAZN LALIGA</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DAZNLaLiga2.es" site_id="11080">DAZN LALIGA 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaHypermotion.es" site_id="11083">LALIGATV HYPERMOTION</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaHypermotion2.es" site_id="11084">LALIGATV HYPERMOTION 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="LaLigaHypermotion3.es" site_id="11085">LALIGATV HYPERMOTION 3</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="GOLPLAY.es" site_id="11031">GOL PLAY</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Mezzo.fr" site_id="1031">Mezzo HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="MTV00s.uk" site_id="1026">MTV 00s</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="HITTV.es" site_id="2046">HIT TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="MTV.es" site_id="11050">MTV España</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="MTVLive.us" site_id="11051">MTV Live</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="SolMusica.es" site_id="11119">Sol Música</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="StingrayClassica.ca" site_id="12003">Classica HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="StingrayFestival4K.ca" site_id="11060">Festival 4K</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="StingrayDJAZZ.ca" site_id="12004">Djazz</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="StingrayiConcerts.ca" site_id="12002">iConcerts</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="MezzoLive.fr" site_id="12005">MezzoLiveHD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TraceLatina.fr" site_id="11106">TRACE Latina</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TraceUrban.fr" site_id="11107">TRACE Urban</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CaracolTV.co" site_id="1029">Caracol TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="EWTNEspanaLatinAmerica.us" site_id="1068">EWTN</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Gulli.fr" site_id="1077">Gulli</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="France2.fr" site_id="1082">France 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="France5.fr" site_id="1083">France 5</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TraceSportStars.fr" site_id="1095">Trace Sport Stars</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TV5MondeEurope.fr" site_id="11023">TV5MONDE</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="QwestTV.fr" site_id="1088">Qwest TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Eurosport1.fr" site_id="11035">Eurosport 1</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Eurosport2.fr" site_id="11059">Eurosport 2</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="MyZenTV.fr" site_id="11070">Myzen TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="FightSports.us" site_id="12007">FightSports</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="FightBoxHD.nl" site_id="1091">Fight Box HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Gametoon.es" site_id="1086">Gametoon</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="EuronewsSpanish.fr" site_id="1090">Euronews</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="ElToroTV.es" site_id="11049">El Toro TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Motorvision.de" site_id="11105">Motorvision</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Esport3.es" site_id="2038">Esport3</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="BBCNewsEurope.uk" site_id="11021">BBC World HD</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="CNNInternationalEurope.us" site_id="11022">CNN</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="DWEspanol.de" site_id="11024">Deutsche Welle</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="AlJazeeraEnglish.qa" site_id="11025">Al Jazeera</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="PROTV.ba" site_id="11028">Pro TV</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="Ubeat.es" site_id="11061">Ubeat</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="OUTtv.ca" site_id="11072">OUTtv</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="BUENVIAJE.es" site_id="11112">¡BUENVIAJE!</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="TennisChannel.us" site_id="11120">Tennis Channel</channel>
<channel site="orangetv.orange.es" lang="es" xmltv_id="NauticalChannel.it" site_id="11128">Nautical Channel</channel>
</channels>
@@ -1,3 +1,5 @@
//https://github.com/iptv-org/epg/blob/master/sites/orangetv.orange.es/orangetv.orange.es.config.js
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const doFetch = require('@ntlab/sfetch') const doFetch = require('@ntlab/sfetch')
@@ -7,10 +9,12 @@ dayjs.extend(utc)
doFetch.setDebugger(debug) doFetch.setDebugger(debug)
const API_PROGRAM_ENDPOINT = 'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO' const API_PROGRAM_ENDPOINT = 'https://epg.orangetv.orange.es/epg/SmartTV_Android/1_PRO'
const API_CHANNEL_ENDPOINT =
'https://pc.orangetv.orange.es/pc/api/rtv/v1/GetChannelList?bouquet_id=1&model_external_id=PC&filter_unsupported_channels=false&client=json'
const API_IMAGE_ENDPOINT = 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images' const API_IMAGE_ENDPOINT = 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images'
const API_CHANNEL_ENDPOINT =
'https://pc.orangetv.orange.es/pc/api/rtv/v1/GetChannelList?bouquet_external_id=1_PRO&model_external_id=PC&filter_unsupported_channels=true&max_pr_level=8&client=json'
const caches = {}
module.exports = { module.exports = {
site: 'orangetv.orange.es', site: 'orangetv.orange.es',
@@ -18,22 +22,36 @@ module.exports = {
request: { request: {
cache: { cache: {
ttl: 24 * 60 * 60 * 1000 // 1 day ttl: 24 * 60 * 60 * 1000 // 1 day
},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36'
} }
}, },
url({ date, segment = 1 }) { url({ date }) {
return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_${segment}.json` return segmentUrl(date)
}, },
async parser({ content, channel, date }) { async parser({ content, channel, date }) {
const programs = [] const programs = []
const items = parseItems(content, channel) const items = parseItems(content, channel)
if (items.length) { const queues = []
const queues = [ // fetch other segments or use cache if exist
module.exports.url({ date, segment: 2 }), for (let i = 2; i <= 3; i++) {
module.exports.url({ date, segment: 3 }) const url = segmentUrl(date, i)
] if (caches[url] !== undefined) {
await doFetch(queues, (url, res) => { items.push(...parseItems(caches[url], channel))
} else {
queues.push({ url, params: module.exports.request })
}
}
if (queues.length) {
await doFetch(queues, (queue, res) => {
if (caches[queue.url] === undefined) {
caches[queue.url] = res
}
items.push(...parseItems(res, channel)) items.push(...parseItems(res, channel))
}) })
}
if (items.length) {
programs.push( programs.push(
...items.map(item => { ...items.map(item => {
return { return {
@@ -70,6 +88,10 @@ module.exports = {
} }
} }
function segmentUrl(date, segment = 1) {
return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_${segment}.json`
}
function parseIcon(item) { function parseIcon(item) {
if (item.attachments.length) { if (item.attachments.length) {
const cover = item.attachments.find(i => i.name.match(/cover/i)) const cover = item.attachments.find(i => i.name.match(/cover/i))
@@ -89,7 +111,7 @@ function parseItems(content, channel) {
typeof content === 'string' ? JSON.parse(content) : Array.isArray(content) ? content : [] typeof content === 'string' ? JSON.parse(content) : Array.isArray(content) ? content : []
if (Array.isArray(json)) { if (Array.isArray(json)) {
json json
.filter(i => i.channelExternalId === channel.site_id) .filter(i => String(i.channelExternalId) === String(channel.site_id))
.forEach(i => { .forEach(i => {
result.push(...i.programs) result.push(...i.programs)
}) })
+412
View File
@@ -0,0 +1,412 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<channel site="pickx.be" site_id="1143" lang="fr" xmltv_id="MaghrebTV.be@SD">Maghreb TV</channel>
<channel site="pickx.be" site_id="1043" lang="en" xmltv_id="">Netflix</channel>
<channel site="pickx.be" site_id="1058" lang="fr" xmltv_id="NationalGeographicWild.fr@SD">National Geographic Wild F</channel>
<channel site="pickx.be" site_id="1190" lang="nl" xmltv_id="NationalGeographicWild.nl@SD">National Geographic Wild N</channel>
<channel site="pickx.be" site_id="1130" lang="de" xmltv_id="DasErste.de@SD">Das Erste</channel>
<channel site="pickx.be" site_id="1093" lang="fr" xmltv_id="TipikVision.be@SD">TIPIK vision</channel>
<channel site="pickx.be" site_id="1131" lang="de" xmltv_id="ZDF.de@SD">ZDF</channel>
<channel site="pickx.be" site_id="1195" lang="nl" xmltv_id="DobbitTV.be@NL">Dobbit TV N</channel>
<channel site="pickx.be" site_id="1149" lang="nl" xmltv_id="VTM2.be@HD">VTM 2 HD</channel>
<channel site="pickx.be" site_id="1011" lang="fr" xmltv_id="PickxPlus.be@FR">Pickx+ F</channel>
<channel site="pickx.be" site_id="1155" lang="nl" xmltv_id="PickxPlus.be@NL">Pickx+ N</channel>
<channel site="pickx.be" site_id="1065" lang="fr" xmltv_id="DobbitTV.be@FR">Dobbit TV F</channel>
<channel site="pickx.be" site_id="1001" lang="fr" xmltv_id="Tipik.be@HD">TIPIK HD</channel>
<channel site="pickx.be" site_id="1201" lang="nl" xmltv_id="PlattelandsTV.be@SD">Plattelands</channel>
<channel site="pickx.be" site_id="1174" lang="nl" xmltv_id="DisneyJunior.nl@SD">Disney Jr. N</channel>
<channel site="pickx.be" site_id="1036" lang="fr" xmltv_id="PickxPlus.be@FRHD">Pickx+ F HD</channel>
<channel site="pickx.be" site_id="1182" lang="nl" xmltv_id="PickxPlus.be@NLHD">Pickx+ N HD</channel>
<channel site="pickx.be" site_id="1016" lang="fr" xmltv_id="AB3.be@HD">AB3 HD</channel>
<channel site="pickx.be" site_id="1054" lang="fr" xmltv_id="DiscoveryChannel.fr@SD">Discovery F</channel>
<channel site="pickx.be" site_id="1054" lang="fr" xmltv_id="DiscoveryChannel.fr@HD">Disc HD F</channel>
<channel site="pickx.be" site_id="1098" lang="fr" xmltv_id="MezzoLive.fr@SD">MezzoLive</channel>
<channel site="pickx.be" site_id="1002" lang="fr" xmltv_id="RTLTVI.be@HD">RTL tvi HD</channel>
<channel site="pickx.be" site_id="1004" lang="fr" xmltv_id="RTLPlug.be@HD">RTL plug HD</channel>
<channel site="pickx.be" site_id="1110" lang="fr" xmltv_id="Telesambre.be@SD">Télé Sambre</channel>
<channel site="pickx.be" site_id="1113" lang="fr" xmltv_id="Vedia.be@SD">Védia</channel>
<channel site="pickx.be" site_id="1111" lang="fr" xmltv_id="">TV Com</channel>
<channel site="pickx.be" site_id="1112" lang="fr" xmltv_id="TVLux.be@SD">TV Lux</channel>
<channel site="pickx.be" site_id="1106" lang="fr" xmltv_id="Matele.be@SD">MaTélé</channel>
<channel site="pickx.be" site_id="1044" lang="fr" xmltv_id="">Disney+</channel>
<channel site="pickx.be" site_id="1167" lang="nl" xmltv_id="BBCFirst.uk@Benelux">BBC First</channel>
<channel site="pickx.be" site_id="1171" lang="nl" xmltv_id="Nickelodeon.nl@HD">nick N HD</channel>
<channel site="pickx.be" site_id="1157" lang="nl" xmltv_id="Play6.be@SD">Play6</channel>
<channel site="pickx.be" site_id="1157" lang="nl" xmltv_id="Play6.be@HD">Play6 HD</channel>
<channel site="pickx.be" site_id="1129" lang="fr" xmltv_id="France24.fr@FrenchHD">France 24 HD</channel>
<channel site="pickx.be" site_id="1128" lang="fr" xmltv_id="EuronewsFrench.fr@SD">Euronews F</channel>
<channel site="pickx.be" site_id="1150" lang="nl" xmltv_id="VTM3.be@HD">VTM 3 HD</channel>
<channel site="pickx.be" site_id="1063" lang="fr" xmltv_id="CrimeDistrict.fr@SD">Crime District</channel>
<channel site="pickx.be" site_id="1092" lang="fr" xmltv_id="BelRTL.be@HD">bel RTL HD</channel>
<channel site="pickx.be" site_id="1196" lang="nl" xmltv_id="EclipsTV.be@SD">Eclips</channel>
<channel site="pickx.be" site_id="1017" lang="fr" xmltv_id="ABXplore.be@HD">ABXPLO HD</channel>
<channel site="pickx.be" site_id="1194" lang="nl" xmltv_id="Njam.be@HD">Njam! HD</channel>
<channel site="pickx.be" site_id="1194" lang="nl" xmltv_id="Njam.be@SD">Njam!</channel>
<channel site="pickx.be" site_id="1020" lang="fr" xmltv_id="arte.fr@HD">arte HD</channel>
<channel site="pickx.be" site_id="1187" lang="nl" xmltv_id="AnimalPlanet.nl@HD">Animal Pl HD</channel>
<channel site="pickx.be" site_id="1154" lang="nl" xmltv_id="Ketnet.be@HD">Ketnet HD</channel>
<channel site="pickx.be" site_id="1161" lang="nl" xmltv_id="NPO1.nl@HD">NPO 1 HD</channel>
<channel site="pickx.be" site_id="1162" lang="nl" xmltv_id="NPO2.nl@HD">NPO 2 HD</channel>
<channel site="pickx.be" site_id="1163" lang="nl" xmltv_id="NPO3.nl@HD">NPO 3 HD</channel>
<channel site="pickx.be" site_id="1037" lang="fr" xmltv_id="Be1.be@SD">Be1</channel>
<channel site="pickx.be" site_id="1039" lang="fr" xmltv_id="BeCine.be@SD">Be Ciné</channel>
<channel site="pickx.be" site_id="1038" lang="fr" xmltv_id="BeSeries.be@SD">Be Séries</channel>
<channel site="pickx.be" site_id="1040" lang="fr" xmltv_id="CinePlusOCS.fr@SD">Ciné+OCS</channel>
<channel site="pickx.be" site_id="1041" lang="fr" xmltv_id="CinePlusFrisson.fr@SD">Ciné+Frisson</channel>
<channel site="pickx.be" site_id="1042" lang="fr" xmltv_id="CinePlusClassic.be@SD">Ciné+Classic</channel>
<channel site="pickx.be" site_id="1200" lang="nl" xmltv_id="OUTtv.nl@SD">OUT tv</channel>
<channel site="pickx.be" site_id="1007" lang="fr" xmltv_id="France3.fr@HD">France 3 HD</channel>
<channel site="pickx.be" site_id="1018" lang="fr" xmltv_id="France4.fr@HD">France 4 HD</channel>
<channel site="pickx.be" site_id="1019" lang="fr" xmltv_id="France5.fr@HD">France 5 HD</channel>
<channel site="pickx.be" site_id="1015" lang="fr" xmltv_id="LN24.be@SD">LN24</channel>
<channel site="pickx.be" site_id="1160" lang="nl" xmltv_id="VTMGold.be@SD">VTM Gold</channel>
<channel site="pickx.be" site_id="1227" lang="en" xmltv_id="PenthouseGold.us@SD">Penthouse Gold</channel>
<channel site="pickx.be" site_id="1204" lang="nl" xmltv_id="PickxPlusSports1.be@NL">Pickx+ Sports 1 N</channel>
<channel site="pickx.be" site_id="1205" lang="nl" xmltv_id="PickxPlusSports2.be@NL">Pickx+ Sports 2 N</channel>
<channel site="pickx.be" site_id="1206" lang="nl" xmltv_id="PickxPlusSports3.be@NL">Pickx+ Sports 3 N</channel>
<channel site="pickx.be" site_id="1207" lang="nl" xmltv_id="PickxPlusSports4.be@NL">Pickx+ Sports 4 N</channel>
<channel site="pickx.be" site_id="1208" lang="nl" xmltv_id="PickxPlusSports5.be@NL">Pickx+ Sports 5 N</channel>
<channel site="pickx.be" site_id="1209" lang="nl" xmltv_id="PickxPlusSports6.be@NL">Pickx+ Sports 6 N</channel>
<channel site="pickx.be" site_id="1211" lang="nl" xmltv_id="PickxPlusSports8.be@NLHD">Pickx+ Sports 8 N HD</channel>
<channel site="pickx.be" site_id="1212" lang="nl" xmltv_id="PickxPlusSports9.be@NLHD">Pickx+ Sports 9 N HD</channel>
<channel site="pickx.be" site_id="1228" lang="en" xmltv_id="DuskTV.nl@SD">Dusk</channel>
<channel site="pickx.be" site_id="1203" lang="nl" xmltv_id="PickxLive.be@NLHD">Pickx Sports Pop-up N HD</channel>
<channel site="pickx.be" site_id="1156" lang="nl" xmltv_id="PickxPlusSports1.be@NLHD">Pickx+ Sports 1 N HD</channel>
<channel site="pickx.be" site_id="1205" lang="nl" xmltv_id="PickxPlusSports2.be@NLHD">Pickx+ Sports 2 N HD</channel>
<channel site="pickx.be" site_id="1206" lang="nl" xmltv_id="PickxPlusSports3.be@NLHD">Pickx+ Sports 3 N HD</channel>
<channel site="pickx.be" site_id="1207" lang="nl" xmltv_id="PickxPlusSports4.be@NLHD">Pickx+ Sports 4 N HD</channel>
<channel site="pickx.be" site_id="1208" lang="nl" xmltv_id="PickxPlusSports5.be@NLHD">Pickx+ Sports 5 N HD</channel>
<channel site="pickx.be" site_id="1209" lang="nl" xmltv_id="PickxPlusSports6.be@NLHD">Pickx+ Sports 6 N HD</channel>
<channel site="pickx.be" site_id="1084" lang="fr" xmltv_id="DAZN1.uk@France">DAZN 1 F</channel>
<channel site="pickx.be" site_id="1217" lang="nl" xmltv_id="DAZN1.uk@Netherlands">DAZN 1 N</channel>
<channel site="pickx.be" site_id="1085" lang="fr" xmltv_id="DAZN2.uk@France">DAZN 2 F</channel>
<channel site="pickx.be" site_id="1218" lang="nl" xmltv_id="DAZN2.uk@Netherlands">DAZN 2 N</channel>
<channel site="pickx.be" site_id="1084" lang="fr" xmltv_id="DAZN1.uk@FranceHD">DAZN 1 F HD</channel>
<channel site="pickx.be" site_id="1217" lang="nl" xmltv_id="DAZN1.uk@NetherlandsHD">DAZN 1 N HD</channel>
<channel site="pickx.be" site_id="1085" lang="fr" xmltv_id="DAZN2.uk@FranceHD">DAZN 2 F HD</channel>
<channel site="pickx.be" site_id="1218" lang="nl" xmltv_id="DAZN2.uk@NetherlandsHD">DAZN 2 N HD</channel>
<channel site="pickx.be" site_id="1071" lang="fr" xmltv_id="PickxPlusSports2.be@FR">Pickx+ Sports 1 F</channel>
<channel site="pickx.be" site_id="1073" lang="fr" xmltv_id="PickxPlusSports3.be@FR">Pickx+ Sports 3 F</channel>
<channel site="pickx.be" site_id="1074" lang="fr" xmltv_id="PickxPlusSports4.be@FR">Pickx+ Sports 4 F</channel>
<channel site="pickx.be" site_id="1075" lang="fr" xmltv_id="PickxPlusSports5.be@FR">Pickx+ Sports 5 F</channel>
<channel site="pickx.be" site_id="1076" lang="fr" xmltv_id="PickxPlusSports6.be@FR">Pickx+ Sports 6 F</channel>
<channel site="pickx.be" site_id="1078" lang="fr" xmltv_id="PickxPlusSports8.be@FRHD">Pickx+ Sports 8 F HD</channel>
<channel site="pickx.be" site_id="1079" lang="fr" xmltv_id="PickxPlusSports9.be@FRHD">Pickx+ Sports 9 F HD</channel>
<channel site="pickx.be" site_id="1080" lang="fr" xmltv_id="PickxPlusSports10.be@FRHD">Pickx+ Sports 10 F HD</channel>
<channel site="pickx.be" site_id="1010" lang="fr" xmltv_id="PickxLive.be@FRHD">Pickx Sports Pop-up F HD</channel>
<channel site="pickx.be" site_id="1012" lang="fr" xmltv_id="PickxPlusSports1.be@FRHD">Pickx+ Sports 1 F HD</channel>
<channel site="pickx.be" site_id="1072" lang="fr" xmltv_id="PickxPlusSports2.be@FRHD">Pickx+ Sports 2 F HD</channel>
<channel site="pickx.be" site_id="1073" lang="fr" xmltv_id="PickxPlusSports3.be@FRHD">Pickx+ Sports 3 F HD</channel>
<channel site="pickx.be" site_id="1074" lang="fr" xmltv_id="PickxPlusSports4.be@FRHD">Pickx+ Sports 4 F HD</channel>
<channel site="pickx.be" site_id="1075" lang="fr" xmltv_id="PickxPlusSports5.be@FRHD">Pickx+ Sports 5 F HD</channel>
<channel site="pickx.be" site_id="1076" lang="fr" xmltv_id="PickxPlusSports6.be@FRHD">Pickx+ Sports 6 F HD</channel>
<channel site="pickx.be" site_id="1213" lang="nl" xmltv_id="PickxPlusSports10.be@NLHD">Pickx+ Sports 10 N HD</channel>
<channel site="pickx.be" site_id="1236" lang="nl" xmltv_id="StuBru.be@SD">StuBru</channel>
<channel site="pickx.be" site_id="1256" lang="fr" xmltv_id="PromiusPickxInfoChannel.be@SD">InfoChannel</channel>
<channel site="pickx.be" site_id="1114" lang="nl" xmltv_id="VlaamsParlementTV.be@SD">Vlaamsparlement.tv</channel>
<channel site="pickx.be" site_id="1064" lang="fr" xmltv_id="E.fr@HD">E! HD F</channel>
<channel site="pickx.be" site_id="1197" lang="nl" xmltv_id="EEurope.nl@HD">E! HD N</channel>
<channel site="pickx.be" site_id="1024" lang="fr" xmltv_id="DisneyChannel.fr@HD">Disn Ch HD F</channel>
<channel site="pickx.be" site_id="1173" lang="nl" xmltv_id="DisneyChannel.nl@HD">Disn Ch HD N</channel>
<channel site="pickx.be" site_id="1140" lang="fr" xmltv_id="2MMonde.ma@SD">2M Monde</channel>
<channel site="pickx.be" site_id="1172" lang="nl" xmltv_id="VTMLife.be@HD">VTM Life HD</channel>
<channel site="pickx.be" site_id="1159" lang="nl" xmltv_id="KanaalZ.be@HD">Kanaal Z HD</channel>
<channel site="pickx.be" site_id="1014" lang="fr" xmltv_id="CanalZ.be@HD">Canal Z HD</channel>
<channel site="pickx.be" site_id="1046" lang="fr" xmltv_id="TVBreizh.fr@HD">TV Breizh HD</channel>
<channel site="pickx.be" site_id="1049" lang="fr" xmltv_id="TCMCinema.fr@HD">TCM Cinéma HD</channel>
<channel site="pickx.be" site_id="1048" lang="fr" xmltv_id="Syfy.fr@HD">SyFy HD F</channel>
<channel site="pickx.be" site_id="1047" lang="fr" xmltv_id="13emeRue.fr@HD">13è Rue HD</channel>
<channel site="pickx.be" site_id="1045" lang="fr" xmltv_id="Action.fr@HD">Action HD</channel>
<channel site="pickx.be" site_id="1222" lang="nl" xmltv_id="Sport10.be@SD">Sport 10</channel>
<channel site="pickx.be" site_id="1034" lang="fr" xmltv_id="Gulli.fr@HD">Gulli HD</channel>
<channel site="pickx.be" site_id="1186" lang="nl" xmltv_id="NationalGeographic.nl@HD">NGC HD N</channel>
<channel site="pickx.be" site_id="1089" lang="en" xmltv_id="Motorvision.de@SD">Motorvision+</channel>
<channel site="pickx.be" site_id="1021" lang="fr" xmltv_id="TV5MondeFranceBelgiumSwitzerlandMonaco.fr@HD">TV5 Monde HD</channel>
<channel site="pickx.be" site_id="1089" lang="en" xmltv_id="Motorvision.de@HD">Motorvision+ HD</channel>
<channel site="pickx.be" site_id="1050" lang="fr" xmltv_id="ComedyCentral.fr@SD">Comedy Central F</channel>
<channel site="pickx.be" site_id="1030" lang="fr" xmltv_id="NickelodeonJunior.fr@SD">nick jr F</channel>
<channel site="pickx.be" site_id="1151" lang="nl" xmltv_id="VTM4.be@HD">VTM 4 HD</channel>
<channel site="pickx.be" site_id="1203" lang="nl" xmltv_id="PickxLive.be@NL">Pickx Showcase N HD</channel>
<channel site="pickx.be" site_id="1147" lang="nl" xmltv_id="Play4.be@HD">Play4 HD</channel>
<channel site="pickx.be" site_id="1148" lang="nl" xmltv_id="Play5.be@HD">Play5 HD</channel>
<channel site="pickx.be" site_id="1081" lang="fr" xmltv_id="DAZNProLeague1.uk@FranceHD">DAZN Pro League 1 F HD</channel>
<channel site="pickx.be" site_id="1081" lang="fr" xmltv_id="DAZNProLeague1.uk@France">DAZN Pro League 1 F</channel>
<channel site="pickx.be" site_id="1193" lang="nl" xmltv_id="TLC.nl@SD">TLC</channel>
<channel site="pickx.be" site_id="1172" lang="nl" xmltv_id="VTMLife.be@SD">VTM Life</channel>
<channel site="pickx.be" site_id="1056" lang="fr" xmltv_id="Trek.fr@HD">TREK HD</channel>
<channel site="pickx.be" site_id="1214" lang="nl" xmltv_id="DAZNProLeague1.uk@NetherlandsHD">DAZN Pro League 1 N HD</channel>
<channel site="pickx.be" site_id="1214" lang="nl" xmltv_id="DAZNProLeague1.uk@Netherlands">DAZN Pro League 1 N</channel>
<channel site="pickx.be" site_id="1082" lang="fr" xmltv_id="DAZNProLeague2.uk@FranceHD">DAZN Pro League 2 F HD</channel>
<channel site="pickx.be" site_id="1082" lang="fr" xmltv_id="DAZNProLeague2.uk@France">DAZN Pro League 2 F</channel>
<channel site="pickx.be" site_id="1215" lang="nl" xmltv_id="DAZNProLeague2.uk@NetherlandsHD">DAZN Pro League 2 N HD</channel>
<channel site="pickx.be" site_id="1215" lang="nl" xmltv_id="DAZNProLeague2.uk@Netherlands">DAZN Pro League 2 N</channel>
<channel site="pickx.be" site_id="1132" lang="de" xmltv_id="RTL.de@SD">RTL</channel>
<channel site="pickx.be" site_id="1051" lang="fr" xmltv_id="TMC.fr@HD">TMC HD</channel>
<channel site="pickx.be" site_id="1158" lang="nl" xmltv_id="Play7.be@HD">Play7 HD</channel>
<channel site="pickx.be" site_id="1068" lang="fr" xmltv_id="MyZenTV.fr@SD">MyZen.tv</channel>
<channel site="pickx.be" site_id="1057" lang="fr" xmltv_id="MuseumTVFrench.fr@SD">Museum TV</channel>
<channel site="pickx.be" site_id="1103" lang="fr" xmltv_id="ACTV.be@HD">Antenne Centre HD</channel>
<channel site="pickx.be" site_id="1115" lang="nl" xmltv_id="ATV.be@HD">ATV HD</channel>
<channel site="pickx.be" site_id="1116" lang="nl" xmltv_id="AVS.be@HD">AVS HD</channel>
<channel site="pickx.be" site_id="1013" lang="nl" xmltv_id="Bruzz.be@HD">BRUZZ HD</channel>
<channel site="pickx.be" site_id="1009" lang="fr" xmltv_id="BX1.be@HD">bx1 HD</channel>
<channel site="pickx.be" site_id="1104" lang="fr" xmltv_id="Bouke.be@HD">Bouké HD</channel>
<channel site="pickx.be" site_id="1105" lang="fr" xmltv_id="CanalZoom.be@HD">Canal Zoom HD</channel>
<channel site="pickx.be" site_id="1117" lang="nl" xmltv_id="FocusTV.be@HD">Focus TV HD</channel>
<channel site="pickx.be" site_id="1106" lang="fr" xmltv_id="Matele.be@HD">MaTélé HD</channel>
<channel site="pickx.be" site_id="1107" lang="fr" xmltv_id="Notele.be@HD">No Télé HD</channel>
<channel site="pickx.be" site_id="1118" lang="nl" xmltv_id="RingTV.be@HD">Ring TV HD</channel>
<channel site="pickx.be" site_id="1119" lang="nl" xmltv_id="ROBTV.be@HD">ROBTV HD</channel>
<channel site="pickx.be" site_id="1108" lang="fr" xmltv_id="QU4TRELiegeMedia.be@HD">Quatre HD</channel>
<channel site="pickx.be" site_id="1120" lang="nl" xmltv_id="RTVKempen.be@HD">RTV Kempen HD</channel>
<channel site="pickx.be" site_id="1121" lang="nl" xmltv_id="RTVMech.be@HD">RTV Mech HD</channel>
<channel site="pickx.be" site_id="1109" lang="fr" xmltv_id="TeleMB.be@HD">Télé MB HD</channel>
<channel site="pickx.be" site_id="1110" lang="fr" xmltv_id="Telesambre.be@HD">Télé Sambre HD</channel>
<channel site="pickx.be" site_id="1122" lang="nl" xmltv_id="TVLimburg.be@HD">TV Limburg HD</channel>
<channel site="pickx.be" site_id="1112" lang="fr" xmltv_id="TVLux.be@HD">TV Lux HD</channel>
<channel site="pickx.be" site_id="1123" lang="nl" xmltv_id="TVOost.be@HD">TV Oost HD</channel>
<channel site="pickx.be" site_id="1113" lang="fr" xmltv_id="Vedia.be@HD">Védia HD</channel>
<channel site="pickx.be" site_id="1124" lang="nl" xmltv_id="WTV.be@HD">WTV HD</channel>
<channel site="pickx.be" site_id="1224" lang="nl" xmltv_id="MentTV.be@HD">Ment TV HD</channel>
<channel site="pickx.be" site_id="1192" lang="nl" xmltv_id="InsightTV.nl@SD">INPLUS</channel>
<channel site="pickx.be" site_id="1053" lang="fr" xmltv_id="TF1SeriesFilms.fr@SD">TF1 Séries Films</channel>
<channel site="pickx.be" site_id="1223" lang="nl" xmltv_id="QMusic.be@SD">Q-Music Kijk Live</channel>
<channel site="pickx.be" site_id="1165" lang="en" xmltv_id="BBCTwo.uk@HD">BBC Two HD</channel>
<channel site="pickx.be" site_id="1221" lang="nl" xmltv_id="Eurosport2.fr@NetherlandsHD">Eurosp2 HD N</channel>
<channel site="pickx.be" site_id="1029" lang="fr" xmltv_id="Boomerang.fr@HD">Boom F HD</channel>
<channel site="pickx.be" site_id="1180" lang="nl" xmltv_id="Cartoonito.uk@HD">Cartoonito HD</channel>
<channel site="pickx.be" site_id="1026" lang="fr" xmltv_id="CartoonNetworkCEE.uk@FranceHD">Cartoon F HD</channel>
<channel site="pickx.be" site_id="1176" lang="nl" xmltv_id="CartoonNetworkWesternEurope.uk@NetherlandsHD">Cartoon N HD</channel>
<channel site="pickx.be" site_id="1188" lang="nl" xmltv_id="InvestigationDiscovery.nl@HD">Inv Disc HD</channel>
<channel site="pickx.be" site_id="1271" lang="en" xmltv_id="WSport.za@SD">W Sports</channel>
<channel site="pickx.be" site_id="1025" lang="fr" xmltv_id="DisneyJr.fr@HD">Disney Jr. F HD</channel>
<channel site="pickx.be" site_id="1059" lang="fr" xmltv_id="ScienceVieTV.fr@HD">Sc et Vie TV HD</channel>
<channel site="pickx.be" site_id="1060" lang="fr" xmltv_id="HistoireTV.fr@HD">Histoire HD</channel>
<channel site="pickx.be" site_id="1189" lang="nl" xmltv_id="History.nl@HD">History HD</channel>
<channel site="pickx.be" site_id="1136" lang="fr" xmltv_id="Rai1.it@HD">RAI Uno HD</channel>
<channel site="pickx.be" site_id="1137" lang="fr" xmltv_id="Rai2.it@HD">RAI Due HD</channel>
<channel site="pickx.be" site_id="1138" lang="fr" xmltv_id="Rai3.it@HD">RAI Tre HD</channel>
<channel site="pickx.be" site_id="1195" lang="nl" xmltv_id="DobbitTV.be@NLHD">Dobbit N HD</channel>
<channel site="pickx.be" site_id="1130" lang="de" xmltv_id="DasErste.de@HD">Das Erste HD</channel>
<channel site="pickx.be" site_id="1183" lang="nl" xmltv_id="ComedyCentral.nl@HD">Comedy Central N HD</channel>
<channel site="pickx.be" site_id="1127" lang="fr" xmltv_id="LCI.fr@HD">LCI HD</channel>
<channel site="pickx.be" site_id="1033" lang="fr" xmltv_id="Mangas.fr@HD">Mangas HD</channel>
<channel site="pickx.be" site_id="1131" lang="de" xmltv_id="ZDF.de@HD">ZDF HD</channel>
<channel site="pickx.be" site_id="1226" lang="en" xmltv_id="DorcelXXX.nl@HD">Dorcel XXX HD</channel>
<channel site="pickx.be" site_id="1225" lang="nl" xmltv_id="PassieXXX.nl@HD">Passie XXX HD</channel>
<channel site="pickx.be" site_id="1229" lang="en" xmltv_id="PinkX.fr@HD">Pink HD</channel>
<channel site="pickx.be" site_id="1031" lang="fr" xmltv_id="TiJi.fr@HD">Tiji HD</channel>
<channel site="pickx.be" site_id="1096" lang="fr" xmltv_id="TraceUrban.fr@HD">Trace HD</channel>
<channel site="pickx.be" site_id="1032" lang="fr" xmltv_id="CanalJ.fr@HD">Canal J HD</channel>
<channel site="pickx.be" site_id="1198" lang="en" xmltv_id="FashionTVEurope.fr@HD">Fashion TV HD</channel>
<channel site="pickx.be" site_id="1102" lang="fr" xmltv_id="Melody.fr@HD">Melody.tv HD</channel>
<channel site="pickx.be" site_id="1199" lang="nl" xmltv_id="MTV.nl@HD">MTV N HD</channel>
<channel site="pickx.be" site_id="1141" lang="fr" xmltv_id="AlAoula.ma@HD">Al Aoula HD</channel>
<channel site="pickx.be" site_id="1142" lang="fr" xmltv_id="AlJazeera.qa@EnglishHD">Al Jazeera HD</channel>
<channel site="pickx.be" site_id="1090" lang="fr" xmltv_id="Automotolachaine.fr@HD">AUTOMOTO HD</channel>
<channel site="pickx.be" site_id="1095" lang="fr" xmltv_id="RFMTV.fr@HD">RFM TV HD</channel>
<channel site="pickx.be" site_id="1132" lang="de" xmltv_id="RTL.de@HD">RTL Deutschland HD</channel>
<channel site="pickx.be" site_id="1134" lang="fr" xmltv_id="TVEInternacionalEuropeAsia.es@HD">TVE International HD</channel>
<channel site="pickx.be" site_id="1062" lang="fr" xmltv_id="Animaux.fr@HD">Animaux HD</channel>
<channel site="pickx.be" site_id="1126" lang="en" xmltv_id="EuronewsEnglish.fr@HD">Euronews E HD</channel>
<channel site="pickx.be" site_id="1128" lang="fr" xmltv_id="EuronewsFrench.fr@HD">Euronews F HD</channel>
<channel site="pickx.be" site_id="1295" lang="nl" xmltv_id="HGTV.be@SD">HGTV</channel>
<channel site="pickx.be" site_id="1046" lang="fr" xmltv_id="TVBreizh.fr@SD">TV Breizh</channel>
<channel site="pickx.be" site_id="1060" lang="fr" xmltv_id="HistoireTV.fr@SD">Histoire</channel>
<channel site="pickx.be" site_id="1094" lang="fr" xmltv_id="RadioContact.be@SD">ContactV</channel>
<channel site="pickx.be" site_id="1137" lang="fr" xmltv_id="Rai2.it@SD">RAI Due</channel>
<channel site="pickx.be" site_id="1185" lang="nl" xmltv_id="DiscoveryChannel.nl@SD">Discovery N</channel>
<channel site="pickx.be" site_id="1020" lang="fr" xmltv_id="arte.fr@SD">Arte</channel>
<channel site="pickx.be" site_id="1045" lang="fr" xmltv_id="Action.fr@SD">Action</channel>
<channel site="pickx.be" site_id="1026" lang="fr" xmltv_id="CartoonNetworkCEE.uk@France">Cartoon F</channel>
<channel site="pickx.be" site_id="1176" lang="nl" xmltv_id="CartoonNetworkWesternEurope.uk@Netherlands">Cartoon N</channel>
<channel site="pickx.be" site_id="1056" lang="fr" xmltv_id="Trek.fr@SD">TREK</channel>
<channel site="pickx.be" site_id="1024" lang="fr" xmltv_id="DisneyChannel.fr@SD">Disn Ch F</channel>
<channel site="pickx.be" site_id="1061" lang="fr" xmltv_id="UshuaiaTV.fr@SD">Ushuaïa</channel>
<channel site="pickx.be" site_id="1004" lang="fr" xmltv_id="RTLPlug.be@SD">RTL plug</channel>
<channel site="pickx.be" site_id="1134" lang="fr" xmltv_id="TVEInternacionalEuropeAsia.es@SD">TVE Int</channel>
<channel site="pickx.be" site_id="1096" lang="fr" xmltv_id="TraceUrban.fr@SD">TraceUrban</channel>
<channel site="pickx.be" site_id="1191" lang="nl" xmltv_id="DiscoveryScienceEurope.uk@Netherlands">Discovery Science</channel>
<channel site="pickx.be" site_id="1021" lang="fr" xmltv_id="TV5MondeFranceBelgiumSwitzerlandMonaco.fr@SD">TV5 Monde</channel>
<channel site="pickx.be" site_id="1198" lang="en" xmltv_id="FashionTVEurope.fr@SD">FashionTV</channel>
<channel site="pickx.be" site_id="1125" lang="en" xmltv_id="CNNInternational.us@MENA">CNN</channel>
<channel site="pickx.be" site_id="1159" lang="nl" xmltv_id="KanaalZ.be@SD">Kanaal Z</channel>
<channel site="pickx.be" site_id="1014" lang="fr" xmltv_id="CanalZ.be@SD">Canal Z</channel>
<channel site="pickx.be" site_id="1144" lang="nl" xmltv_id="VRT1.be@SD">VRT 1</channel>
<channel site="pickx.be" site_id="1019" lang="fr" xmltv_id="France5.fr@SD">France 5</channel>
<channel site="pickx.be" site_id="1171" lang="nl" xmltv_id="Nickelodeon.nl@SD">nickelodeon N</channel>
<channel site="pickx.be" site_id="1146" lang="nl" xmltv_id="VTM.be@SD">VTM</channel>
<channel site="pickx.be" site_id="1017" lang="fr" xmltv_id="ABXplore.be@SD">ABXPLORE</channel>
<channel site="pickx.be" site_id="1095" lang="fr" xmltv_id="RFMTV.fr@SD">RFM TV</channel>
<channel site="pickx.be" site_id="1149" lang="nl" xmltv_id="VTM2.be@SD">VTM 2</channel>
<channel site="pickx.be" site_id="1033" lang="fr" xmltv_id="Mangas.fr@SD">Mangas</channel>
<channel site="pickx.be" site_id="1161" lang="nl" xmltv_id="NPO1.nl@SD">NPO 1</channel>
<channel site="pickx.be" site_id="1136" lang="fr" xmltv_id="Rai1.it@SD">RAI Uno</channel>
<channel site="pickx.be" site_id="1062" lang="fr" xmltv_id="Animaux.fr@SD">Animaux</channel>
<channel site="pickx.be" site_id="1032" lang="fr" xmltv_id="CanalJ.fr@SD">Canal J</channel>
<channel site="pickx.be" site_id="1016" lang="fr" xmltv_id="AB3.be@SD">AB3</channel>
<channel site="pickx.be" site_id="1001" lang="fr" xmltv_id="Tipik.be@SD">RTBF TIPIK</channel>
<channel site="pickx.be" site_id="1000" lang="fr" xmltv_id="LaUne.be@SD">RTBF La Une</channel>
<channel site="pickx.be" site_id="1048" lang="fr" xmltv_id="Syfy.fr@SD">SyFy F</channel>
<channel site="pickx.be" site_id="1055" lang="fr" xmltv_id="NationalGeographic.fr@SD">National Geographic F</channel>
<channel site="pickx.be" site_id="1148" lang="nl" xmltv_id="Play5.be@SD">Play5</channel>
<channel site="pickx.be" site_id="1127" lang="fr" xmltv_id="LCI.fr@SD">LCI</channel>
<channel site="pickx.be" site_id="1005" lang="fr" xmltv_id="TF1.fr@SD">TF1</channel>
<channel site="pickx.be" site_id="1166" lang="en" xmltv_id="BBCNews.uk@Europe">BBC News</channel>
<channel site="pickx.be" site_id="1003" lang="fr" xmltv_id="RTLClub.be@SD">RTL club</channel>
<channel site="pickx.be" site_id="1164" lang="en" xmltv_id="BBCOne.uk@London">BBC One</channel>
<channel site="pickx.be" site_id="1002" lang="fr" xmltv_id="RTLTVI.be@SD">RTL tvi</channel>
<channel site="pickx.be" site_id="1129" lang="fr" xmltv_id="France24.fr@French">France 24 F</channel>
<channel site="pickx.be" site_id="1009" lang="fr" xmltv_id="BX1.be@SD">bx1</channel>
<channel site="pickx.be" site_id="1087" lang="fr" xmltv_id="Eurosport1.fr@France">Eurosport F</channel>
<channel site="pickx.be" site_id="1163" lang="nl" xmltv_id="NPO3.nl@SD">NPO 3</channel>
<channel site="pickx.be" site_id="1162" lang="nl" xmltv_id="NPO2.nl@SD">NPO 2</channel>
<channel site="pickx.be" site_id="1018" lang="fr" xmltv_id="France4.fr@SD">France 4</channel>
<channel site="pickx.be" site_id="1150" lang="nl" xmltv_id="VTM3.be@SD">VTM 3</channel>
<channel site="pickx.be" site_id="1147" lang="nl" xmltv_id="Play4.be@SD">Play4</channel>
<channel site="pickx.be" site_id="1145" lang="nl" xmltv_id="VRTCanvas.be@SD">VRT Canvas</channel>
<channel site="pickx.be" site_id="1126" lang="en" xmltv_id="EuronewsEnglish.fr@SD">Euronews E</channel>
<channel site="pickx.be" site_id="1186" lang="nl" xmltv_id="NationalGeographic.nl@SD">National Geographic N</channel>
<channel site="pickx.be" site_id="1006" lang="fr" xmltv_id="France2.fr@SD">France 2</channel>
<channel site="pickx.be" site_id="1007" lang="fr" xmltv_id="France3.fr@SD">France 3</channel>
<channel site="pickx.be" site_id="1088" lang="fr" xmltv_id="Eurosport2.fr@France">Eurosp2 F</channel>
<channel site="pickx.be" site_id="1187" lang="nl" xmltv_id="AnimalPlanet.nl@SD">Animal Planet</channel>
<channel site="pickx.be" site_id="1220" lang="nl" xmltv_id="Eurosport1.fr@Netherlands">Eurosport N</channel>
<channel site="pickx.be" site_id="1031" lang="fr" xmltv_id="TiJi.fr@SD">Tiji</channel>
<channel site="pickx.be" site_id="1049" lang="fr" xmltv_id="TCMCinema.fr@SD">TCM Cinéma</channel>
<channel site="pickx.be" site_id="1226" lang="fr" xmltv_id="DorcelXXX.nl@SD">Dorcel XXX</channel>
<channel site="pickx.be" site_id="1059" lang="fr" xmltv_id="ScienceVieTV.fr@SD">Science et Vie TV</channel>
<channel site="pickx.be" site_id="1029" lang="fr" xmltv_id="Boomerang.fr@SD">Boomerang F</channel>
<channel site="pickx.be" site_id="1064" lang="fr" xmltv_id="E.fr@SD">E! F</channel>
<channel site="pickx.be" site_id="1047" lang="fr" xmltv_id="13emeRue.fr@SD">13è Rue</channel>
<channel site="pickx.be" site_id="1090" lang="fr" xmltv_id="Automotolachaine.fr@SD">AUTOMOTO</channel>
<channel site="pickx.be" site_id="1070" lang="fr" xmltv_id="PickxLive.be@FR">Pickx Showcase F</channel>
<channel site="pickx.be" site_id="1124" lang="nl" xmltv_id="WTV.be@SD">WTV</channel>
<channel site="pickx.be" site_id="1117" lang="nl" xmltv_id="FocusTV.be@SD">Focus TV</channel>
<channel site="pickx.be" site_id="1115" lang="nl" xmltv_id="ATV.be@SD">ATV</channel>
<channel site="pickx.be" site_id="1122" lang="nl" xmltv_id="TVLimburg.be@SD">TV Limburg</channel>
<channel site="pickx.be" site_id="1119" lang="nl" xmltv_id="ROBTV.be@SD">ROBTV</channel>
<channel site="pickx.be" site_id="1197" lang="nl" xmltv_id="EEurope.nl@SD">E! N</channel>
<channel site="pickx.be" site_id="1123" lang="nl" xmltv_id="TVOost.be@SD">TV Oost</channel>
<channel site="pickx.be" site_id="1013" lang="nl" xmltv_id="Bruzz.be@SD">BRUZZ</channel>
<channel site="pickx.be" site_id="1120" lang="nl" xmltv_id="RTVKempen.be@SD">RTV Kempen O</channel>
<channel site="pickx.be" site_id="1121" lang="nl" xmltv_id="RTVMech.be@SD">RTV Mech</channel>
<channel site="pickx.be" site_id="1118" lang="nl" xmltv_id="RingTV.be@SD">Ring TV</channel>
<channel site="pickx.be" site_id="1107" lang="fr" xmltv_id="Notele.be@SD">No Télé</channel>
<channel site="pickx.be" site_id="1025" lang="fr" xmltv_id="DisneyJr.fr@SD">Disney Jr. F</channel>
<channel site="pickx.be" site_id="1109" lang="fr" xmltv_id="TeleMB.be@SD">Télé MB</channel>
<channel site="pickx.be" site_id="1141" lang="fr" xmltv_id="AlAoula.ma@SD">Al Aoula</channel>
<channel site="pickx.be" site_id="1067" lang="fr" xmltv_id="MTV.fr@SD">MTV F</channel>
<channel site="pickx.be" site_id="1199" lang="nl" xmltv_id="MTV.nl@SD">MTV N</channel>
<channel site="pickx.be" site_id="1183" lang="nl" xmltv_id="ComedyCentral.nl@SD">Comedy Central N</channel>
<channel site="pickx.be" site_id="1104" lang="fr" xmltv_id="Bouke.be@SD">Bouké</channel>
<channel site="pickx.be" site_id="1105" lang="fr" xmltv_id="CanalZoom.be@SD">Canal Zoom</channel>
<channel site="pickx.be" site_id="1103" lang="fr" xmltv_id="ACTV.be@SD">Antenne C</channel>
<channel site="pickx.be" site_id="1225" lang="nl" xmltv_id="PassieXXX.nl@SD">Passie XXX</channel>
<channel site="pickx.be" site_id="1178" lang="nl" xmltv_id="NickJr.nl@SD">nick jr N</channel>
<channel site="pickx.be" site_id="1189" lang="nl" xmltv_id="History.nl@SD">History</channel>
<channel site="pickx.be" site_id="1102" lang="fr" xmltv_id="Melody.fr@SD">Melody.tv</channel>
<channel site="pickx.be" site_id="1142" lang="fr" xmltv_id="AlJazeera.qa@English">Al Jazeera</channel>
<channel site="pickx.be" site_id="1135" lang="fr" xmltv_id="KTO.fr@SD">KTO</channel>
<channel site="pickx.be" site_id="1179" lang="nl" xmltv_id="Nicktoons.nl@SD">nick Toons</channel>
<channel site="pickx.be" site_id="1005" lang="fr" xmltv_id="TF1.fr@HD">TF1 HD</channel>
<channel site="pickx.be" site_id="1229" lang="fr" xmltv_id="PinkX.fr@SD">Pink</channel>
<channel site="pickx.be" site_id="1061" lang="fr" xmltv_id="UshuaiaTV.fr@HD">Ushuaïa HD</channel>
<channel site="pickx.be" site_id="1097" lang="nl" xmltv_id="StingrayClassica.ca@SD">Classica</channel>
<channel site="pickx.be" site_id="1185" lang="nl" xmltv_id="DiscoveryChannel.nl@HD">Disc HD N</channel>
<channel site="pickx.be" site_id="1222" lang="nl" xmltv_id="Sport10.be@HD">Sport 10 HD</channel>
<channel site="pickx.be" site_id="1055" lang="fr" xmltv_id="NationalGeographic.fr@HD">NGC HD F</channel>
<channel site="pickx.be" site_id="1144" lang="nl" xmltv_id="VRT1.be@HD">VRT 1 HD</channel>
<channel site="pickx.be" site_id="1003" lang="fr" xmltv_id="RTLClub.be@HD">RTL club HD</channel>
<channel site="pickx.be" site_id="1220" lang="nl" xmltv_id="Eurosport1.fr@NetherlandsHD">Eurosp HD N</channel>
<channel site="pickx.be" site_id="1006" lang="fr" xmltv_id="France2.fr@HD">France 2 HD</channel>
<channel site="pickx.be" site_id="1210" lang="nl" xmltv_id="PickxPlusSports7.be@NL">Pickx+ Sports 7 N</channel>
<channel site="pickx.be" site_id="1188" lang="nl" xmltv_id="InvestigationDiscovery.nl@SD">Inv Disc</channel>
<channel site="pickx.be" site_id="1212" lang="nl" xmltv_id="PickxPlusSports9.be@NL">Pickx+ Sports 9 N</channel>
<channel site="pickx.be" site_id="1213" lang="nl" xmltv_id="PickxPlusSports10.be@NL">Pickx+ Sports 10 N</channel>
<channel site="pickx.be" site_id="1211" lang="nl" xmltv_id="PickxPlusSports8.be@NL">Pickx+ Sports 8 N</channel>
<channel site="pickx.be" site_id="1080" lang="fr" xmltv_id="PickxPlusSports10.be@FR">Pickx+ Sports 10 F</channel>
<channel site="pickx.be" site_id="1077" lang="fr" xmltv_id="PickxPlusSports7.be@FR">Pickx+ Sports 7 F</channel>
<channel site="pickx.be" site_id="1078" lang="fr" xmltv_id="PickxPlusSports8.be@FR">Pickx+ Sports 8 F</channel>
<channel site="pickx.be" site_id="1079" lang="fr" xmltv_id="PickxPlusSports9.be@FR">Pickx+ Sports 9 F</channel>
<channel site="pickx.be" site_id="1221" lang="nl" xmltv_id="Eurosport2.fr@Netherlands">Eurosp2 N</channel>
<channel site="pickx.be" site_id="1077" lang="fr" xmltv_id="PickxPlusSports7.be@FRHD">Pickx+ Sports 7 F HD</channel>
<channel site="pickx.be" site_id="1210" lang="nl" xmltv_id="PickxPlusSports7.be@NLHD">Pickx+ Sports 7 N HD</channel>
<channel site="pickx.be" site_id="1165" lang="en" xmltv_id="BBCTwo.uk@England">BBC Two</channel>
<channel site="pickx.be" site_id="1146" lang="nl" xmltv_id="VTM.be@HD">VTM HD</channel>
<channel site="pickx.be" site_id="1151" lang="nl" xmltv_id="VTM4.be@SD">VTM 4</channel>
<channel site="pickx.be" site_id="1008" lang="fr" xmltv_id="LaTrois.be@SD">La Trois</channel>
<channel site="pickx.be" site_id="1180" lang="nl" xmltv_id="Cartoonito.uk@SD">Cartoonito</channel>
<channel site="pickx.be" site_id="1145" lang="nl" xmltv_id="VRTCanvas.be@HD">VRT Canvas HD</channel>
<channel site="pickx.be" site_id="1170" lang="nl" xmltv_id="Ketnet.be@SD">Ketnet</channel>
<channel site="pickx.be" site_id="1023" lang="fr" xmltv_id="Nickelodeon.fr@SD">nick F</channel>
<channel site="pickx.be" site_id="1224" lang="nl" xmltv_id="MentTV.be@SD">Ment TV</channel>
<channel site="pickx.be" site_id="1000" lang="fr" xmltv_id="LaUne.be@HD">La Une HD</channel>
<channel site="pickx.be" site_id="1173" lang="nl" xmltv_id="DisneyChannel.nl@SD">Disn Ch N</channel>
<channel site="pickx.be" site_id="1008" lang="fr" xmltv_id="LaTrois.be@HD">La Trois HD</channel>
<channel site="pickx.be" site_id="1108" lang="fr" xmltv_id="QU4TRELiegeMedia.be@SD">Quatre</channel>
<channel site="pickx.be" site_id="1133" lang="de" xmltv_id="">BRF Fernsehen</channel>
<channel site="pickx.be" site_id="1245" lang="de" xmltv_id="">BRF 1</channel>
<channel site="pickx.be" site_id="1261" lang="en" xmltv_id="">Test VRT ENG</channel>
<channel site="pickx.be" site_id="1265" lang="en" xmltv_id="">Test 977</channel>
<channel site="pickx.be" site_id="1266" lang="en" xmltv_id="">Test RTBF ENG</channel>
<channel site="pickx.be" site_id="1267" lang="en" xmltv_id="">Test RTL ENG</channel>
<channel site="pickx.be" site_id="1268" lang="en" xmltv_id="">Test DPG ENG</channel>
<channel site="pickx.be" site_id="1277" lang="en" xmltv_id="">Test 998</channel>
<channel site="pickx.be" site_id="1302" lang="en" xmltv_id="">Horse and Country</channel>
<channel site="pickx.be" site_id="2000" lang="en" xmltv_id="">Sanity Check Live 01</channel>
<channel site="pickx.be" site_id="1069" lang="fr" xmltv_id="">Pickx+ F</channel>
<channel site="pickx.be" site_id="1246" lang="fr" xmltv_id="">RTBF La Prem1ère</channel>
<channel site="pickx.be" site_id="1247" lang="fr" xmltv_id="">RTBF VivaCité</channel>
<channel site="pickx.be" site_id="1248" lang="fr" xmltv_id="">RTBF Musiq&apos;3</channel>
<channel site="pickx.be" site_id="1249" lang="fr" xmltv_id="">RTBF Classic21</channel>
<channel site="pickx.be" site_id="1250" lang="fr" xmltv_id="">RTBF Tipik Radio</channel>
<channel site="pickx.be" site_id="1251" lang="fr" xmltv_id="">bel RTL</channel>
<channel site="pickx.be" site_id="1252" lang="fr" xmltv_id="">MINT</channel>
<channel site="pickx.be" site_id="1253" lang="fr" xmltv_id="">Contact</channel>
<channel site="pickx.be" site_id="1254" lang="fr" xmltv_id="">Nostalgie</channel>
<channel site="pickx.be" site_id="1255" lang="fr" xmltv_id="">LN Radio</channel>
<channel site="pickx.be" site_id="1294" lang="fr" xmltv_id="">Test 984</channel>
<channel site="pickx.be" site_id="1296" lang="fr" xmltv_id="">RTL district</channel>
<channel site="pickx.be" site_id="2001" lang="fr" xmltv_id="">Sanity Check Radio</channel>
<channel site="pickx.be" site_id="2002" lang="fr" xmltv_id="">Sanity Check Live 02</channel>
<channel site="pickx.be" site_id="2003" lang="fr" xmltv_id="">Sanity Check Live 03</channel>
<channel site="pickx.be" site_id="2004" lang="fr" xmltv_id="">Sanity Check Live 04</channel>
<channel site="pickx.be" site_id="2005" lang="fr" xmltv_id="">Sanity Check Live 05</channel>
<channel site="pickx.be" site_id="2006" lang="fr" xmltv_id="">Sanity Check Live 06</channel>
<channel site="pickx.be" site_id="2007" lang="fr" xmltv_id="">Sanity Check Live 07</channel>
<channel site="pickx.be" site_id="2008" lang="fr" xmltv_id="">Sanity Check Live 08</channel>
<channel site="pickx.be" site_id="2009" lang="fr" xmltv_id="">Sanity Check Live 09</channel>
<channel site="pickx.be" site_id="2010" lang="fr" xmltv_id="">Sanity Check Live 10</channel>
<channel site="pickx.be" site_id="2011" lang="fr" xmltv_id="">Sanity Check Live 11</channel>
<channel site="pickx.be" site_id="2012" lang="fr" xmltv_id="">Sanity Check Live 12</channel>
<channel site="pickx.be" site_id="2020" lang="fr" xmltv_id="">Sanity Check Live 20</channel>
<channel site="pickx.be" site_id="3350" lang="fr" xmltv_id="">NTVBE Test 11</channel>
<channel site="pickx.be" site_id="3351" lang="fr" xmltv_id="">NTVBE Test 12</channel>
<channel site="pickx.be" site_id="3352" lang="fr" xmltv_id="">NTVBE Test 13</channel>
<channel site="pickx.be" site_id="3353" lang="fr" xmltv_id="">NTVBE Test 14</channel>
<channel site="pickx.be" site_id="3354" lang="fr" xmltv_id="">NTVBE Test 15</channel>
<channel site="pickx.be" site_id="1139" lang="it" xmltv_id="">Mediaset Italia</channel>
<channel site="pickx.be" site_id="1152" lang="nl" xmltv_id="">Studio 100 TV</channel>
<channel site="pickx.be" site_id="1153" lang="nl" xmltv_id="">Proximus Showcase N</channel>
<channel site="pickx.be" site_id="1169" lang="nl" xmltv_id="">Studio 100 TV</channel>
<channel site="pickx.be" site_id="1184" lang="nl" xmltv_id="">STAR Channel</channel>
<channel site="pickx.be" site_id="1202" lang="nl" xmltv_id="">Pickx+ N</channel>
<channel site="pickx.be" site_id="1230" lang="nl" xmltv_id="">Radio 1</channel>
<channel site="pickx.be" site_id="1231" lang="nl" xmltv_id="">Radio 2 Antwerpen</channel>
<channel site="pickx.be" site_id="1232" lang="nl" xmltv_id="">Radio 2 Limburg</channel>
<channel site="pickx.be" site_id="1233" lang="nl" xmltv_id="">Radio 2 Oost-Vlaanderen</channel>
<channel site="pickx.be" site_id="1234" lang="nl" xmltv_id="">Radio 2 Vlaam-Brabant</channel>
<channel site="pickx.be" site_id="1235" lang="nl" xmltv_id="">Radio 2 West-Vlaanderen</channel>
<channel site="pickx.be" site_id="1237" lang="nl" xmltv_id="">MNM</channel>
<channel site="pickx.be" site_id="1238" lang="nl" xmltv_id="">MNM Hits</channel>
<channel site="pickx.be" site_id="1239" lang="nl" xmltv_id="">Klara</channel>
<channel site="pickx.be" site_id="1240" lang="nl" xmltv_id="">Klara Continuo</channel>
<channel site="pickx.be" site_id="1241" lang="nl" xmltv_id="">Radio Bene</channel>
<channel site="pickx.be" site_id="1242" lang="nl" xmltv_id="">De Tijdloze</channel>
<channel site="pickx.be" site_id="1243" lang="nl" xmltv_id="">Qmusic</channel>
<channel site="pickx.be" site_id="1244" lang="nl" xmltv_id="">JOE</channel>
<channel site="pickx.be" site_id="1278" lang="nl" xmltv_id="">Play Crime</channel>
<channel site="pickx.be" site_id="1284" lang="nl" xmltv_id="">Frame</channel>
<channel site="pickx.be" site_id="1301" lang="nl" xmltv_id="">Pickx Crime</channel>
</channels>
+125 -151
View File
@@ -1,176 +1,150 @@
// credit for this fix goes to davidclaeysquinones for his PR on https://github.com/iptv-org/epg/pull/2430, https://github.com/iptv-org/epg/pull/2520 and to BellezaEmporium for his PR on https://github.com/iptv-org/epg/pull/2480, https://github.com/iptv-org/epg/pull/2525
const axios = require('axios') const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
let apiVersion
dayjs.extend(utc) dayjs.extend(utc)
dayjs.extend(timezone)
const API_ENDPOINT = 'https://api.prod-ntvbe.tvapi-web.pickx.be'
const API_IMAGE_ENDPOINT =
'https://experience-cache.cdi.streaming.proximustv.be/posterserver/poster/EPG'
const TIMEZONE = 'Europe/Brussels'
// every tray of the AVS backend is addressed through
// /{tenant}/{version}/{cluster}/{locale}/{platform}/{property}, where the cluster is the access
// level ("A" is anonymous, which is enough for the public guide) and the platform has to be WEB
const BASE_PATH = '/AGL/1.5/A/{locale}/WEB/PXS'
// the locale only selects the language of the labels the API itself emits, never the language of
// the guide, so a channel keeps its broadcast language whichever locale is requested
const LOCALES = { en: 'ENG', fr: 'FRA', nl: 'NLD', de: 'DEU' }
const LANGUAGES = {
ara: 'ar',
deu: 'de',
eng: 'en',
fra: 'fr',
ita: 'it',
nld: 'nl',
spa: 'es'
}
// the channel tray refuses any page wider than this
const CHANNELS_PER_PAGE = 100
module.exports = { module.exports = {
site: 'pickx.be', site: 'pickx.be',
days: 2, days: 2,
setApiVersion: function (version) {
apiVersion = version
},
getApiVersion: function () {
return apiVersion
},
fetchApiVersion: fetchApiVersion,
url: async function ({ channel, date }) {
if (!apiVersion) {
await fetchApiVersion()
}
return `https://px-epg.azureedge.net/airings/${apiVersion}/${date.format(
'YYYY-MM-DD'
)}/channel/${channel.site_id}?timezone=Europe%2FBrussels`
},
request: { request: {
headers: { headers: {
Origin: 'https://www.pickx.be', Origin: 'https://tv.pickx.be',
Referer: 'https://www.pickx.be/' Referer: 'https://tv.pickx.be/'
} }
}, },
parser({ channel, content }) { url({ channel, date }) {
// the guide is cut into Brussels days, while the grabber hands us a UTC moment. Both edges
// are resolved from their own calendar date, because adding a day to the start would add a
// flat 24 hours and so cut the 25 hour day short, or overrun the 23 hour one, when the
// Brussels clock shifts
const start = brusselsMidnight(date)
const stop = brusselsMidnight(date.add(1, 'd'))
// from/to paginates the channels of the tray, not their programs, so asking for a single
// channel still returns its whole day
return `${API_ENDPOINT}${basePath(channel.lang)}/TRAY/EPG?from=1&to=1&filter_channelIds=${
channel.site_id
}&filter_startTime=${start.valueOf()}&filter_endTime=${stop.valueOf()}`
},
parser({ content }) {
const programs = [] const programs = []
if (content) { parseItems(content).forEach(item => {
const items = JSON.parse(content) const data = item.metadata
items.forEach(item => { if (!data) return
programs.push({
title: item.program.title, programs.push({
sub_title: item.program.episodeTitle, title: data.title,
description: item.program.description, sub_title: data.episodeTitle,
category: item.program.translatedCategory?.[channel.lang] description: data.longDescription || data.shortDescription,
? item.program.translatedCategory[channel.lang] category: data.genres,
: item.program.category.split('.')[1], image: parseImage(data),
image: item.program.posterFileName season: data.season,
? `https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/${item.program.posterFileName}` episode: data.episodeNumber,
: null, actors: data.actors,
season: item.program.seasonNumber, director: data.directors,
episode: item.program.episodeNumber, date: data.year,
actors: item.program.actors, country: data.country,
director: item.program.director ? [item.program.director] : null, start: dayjs(data.airingStartTime),
start: dayjs.utc(item.programScheduleStart), stop: dayjs(data.airingEndTime)
stop: dayjs.utc(item.programScheduleEnd)
})
}) })
} })
return programs return programs
}, },
async channels({ lang = '' }) { async channels() {
const query = { const channels = []
operationName: 'getChannels',
variables: {
language: lang,
queryParams: {},
id: '0',
params: {
shouldReadFromCache: true
}
},
query: `query getChannels($language: String!, $queryParams: ChannelQueryParams, $id: String, $params: ChannelParams) {
channels(language: $language, queryParams: $queryParams, id: $id, params: $params) {
id
channelReferenceNumber
name
callLetter
number
logo {
key
url
__typename
}
language
hd
radio
replayable
ottReplayable
playable
ottPlayable
recordable
subscribed
cloudRecordable
catchUpWindowInHours
isOttNPVREnabled
ottNPVRStart
subscription {
channelRef
subscribed
upselling {
upsellable
packages
__typename
}
__typename
}
packages
__typename
}
}`
}
const result = await axios
.post('https://api.proximusmwc.be/tiams/v3/graphql', query)
.then(r => r.data)
.catch(console.error)
return ( for (let from = 1; ; from += CHANNELS_PER_PAGE) {
result?.data?.channels const data = await fetchChannels(from)
.filter( if (!data) break
channel =>
!channel.radio && (!lang || channel.language === (lang === 'de' ? 'ger' : lang)) const items = data.containers || []
) items.forEach(item => {
.map(channel => { const metadata = item.metadata
return { if (!metadata) return
lang: channel.language === 'ger' ? 'de' : channel.language,
site_id: channel.id, channels.push({
name: channel.name lang: LANGUAGES[metadata.channelLanguage] || 'fr',
} site_id: String(metadata.channelId),
}) || [] name: metadata.channelName
) })
})
if (!items.length || channels.length >= data.total) break
}
return channels
} }
} }
function fetchApiVersion() {
return new Promise(async (resolve, reject) => {
try {
// you'll never find what happened here :)
// load the pickx page and get the hash from the MWC configuration.
// it's not the best way to get the version but it's the only way to get it.
const hashUrl = 'https://www.pickx.be/nl/televisie/tv-gids'; function basePath(lang) {
return BASE_PATH.replace('{locale}', LOCALES[lang] || LOCALES.nl)
}
const hashData = await axios.get(hashUrl) function brusselsMidnight(date) {
.then(r => { return dayjs.tz(date.format('YYYY-MM-DD'), TIMEZONE).startOf('d')
const re = /"hashes":\["(.*)"\]/ }
const match = r.data.match(re)
if (match && match[1]) {
return match[1]
} else {
throw new Error('React app version hash not found')
}
})
.catch(console.error);
const versionUrl = `https://www.pickx.be/api/s-${hashData}` function fetchChannels(from) {
return axios
const response = await axios.get(versionUrl, { .get(`${API_ENDPOINT}${basePath('nl')}/TRAY/LIVECHANNELS`, {
headers: { params: { from, to: from + CHANNELS_PER_PAGE - 1 },
Origin: 'https://www.pickx.be', headers: {
Referer: 'https://www.pickx.be/' Origin: 'https://tv.pickx.be',
} Referer: 'https://tv.pickx.be/'
})
if (response.status === 200) {
apiVersion = response.data.version
resolve()
} else {
console.error(`Failed to fetch API version. Status: ${response.status}`)
reject(`Failed to fetch API version. Status: ${response.status}`)
} }
} catch (error) { })
console.error('Error during fetchApiVersion:', error) .then(r => r.data.resultObj)
reject(error) .catch(console.error)
} }
})
} function parseImage(data) {
const filename = data.pictureUrl || data.extendedMetadata?.images?.landscapePoster
return filename ? `${API_IMAGE_ENDPOINT}/${filename}` : null
}
function parseItems(content) {
if (!content) return []
try {
const data = JSON.parse(content)
// the tray nests the programs of each requested channel under their own container
const channel = data?.resultObj?.containers?.[0]
return channel?.containers || []
} catch {
return []
}
}
+175 -100
View File
@@ -1,140 +1,215 @@
// credit for this fix goes to davidclaeysquinones for his PR on https://github.com/iptv-org/epg/pull/2429 //https://github.com/iptv-org/epg/blob/master/sites/web.magentatv.de/web.magentatv.de.config.js
const axios = require('axios') const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
const API_STATIC_ENDPOINT = 'https://static.spark.telenet.tv/eng/web/epg-service-lite/be' let X_CSRFTOKEN
const API_PROD_ENDPOINT = 'https://spark-prod-be.gnp.cloud.telenet.tv/eng/web/linear-service/v2' let Cookie
const API_IMAGE_ENDPOINT = 'https://staticqbr-prod-be.gnp.cloud.telenet.tv/image-service'; const cookiesToExtract = ['JSESSIONID', 'CSESSIONID', 'CSRFSESSION']
dayjs.extend(utc)
dayjs.extend(customParseFormat)
module.exports = { module.exports = {
site: 'telenet.tv', site: 'web.magentatv.de',
days: 2, days: 2,
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList',
request: { request: {
cache: { method: 'POST',
ttl: 60 * 60 * 1000 // 1 hour async headers() {
} return await setHeaders()
}, },
url: function ({ date, channel }) { data({ channel, date }) {
return `${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDDHHmmss')}` return {
}, count: -1,
async parser({ content, channel, date }) { isFillProgram: 1,
let programs = [] offset: 0,
let items = parseItems(content, channel) properties: [
if (!items.length) return programs {
const promises = [ include:
axios.get( 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date name: 'playbill'
.add(6, 'h')
.format('YYYYMMDDHHmmss')}`,
{
responseType: 'arraybuffer'
}
),
axios.get(
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date
.add(12, 'h')
.format('YYYYMMDDHHmmss')}`,
{
responseType: 'arraybuffer'
}
),
axios.get(
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date
.add(18, 'h')
.format('YYYYMMDDHHmmss')}`,
{
responseType: 'arraybuffer'
}
)
]
await Promise.allSettled(promises)
.then(results => {
results.forEach(r => {
if (r.status === 'fulfilled') {
const parsed = parseItems(r.value.data, channel)
items = items.concat(parsed)
} }
}) ],
}) type: 2,
.catch(console.error) begintime: date.format('YYYYMMDD000000'),
channelid: channel.site_id,
for (let item of items) { endtime: date.add(1, 'd').format('YYYYMMDD000000')
const detail = await loadProgramDetails(item, channel) }
programs.push({
title: item.title,
icon: parseIcon(item),
description: detail.longDescription,
category: detail.genres,
actors: detail.actors,
season: parseSeason(detail),
episode: parseEpisode(detail),
start: parseStart(item),
stop: parseStop(item)
})
} }
},
parser({ content }) {
const programs = []
const items = parseItems(content)
items.forEach(item => {
programs.push({
title: item.name,
description: item.introduce,
image: parseImage(item),
icon: parseImage(item),
category: parseCategory(item),
start: parseStart(item),
stop: parseStop(item),
sub_title: item.subName,
season: item.seasonNum,
episode: item.subNum,
directors: parseDirectors(item),
producers: parseProducers(item),
adapters: parseAdapters(item),
country: item.country?.toUpperCase(),
date: item.producedate,
urls: parseUrls(item)
})
})
return programs return programs
}, },
async channels() { async channels() {
const url = 'https://api.prod.sngtv.magentatv.de/EPG/JSON/AllChannel'
const body = {
channelNamespace: 2,
filterlist: [
{
key: 'IsHide',
value: '-1'
}
],
metaDataVer: 'Channel/1.1',
properties: [
{
include: '/channellist/logicalChannel/contentId,/channellist/logicalChannel/name',
name: 'logicalChannel'
}
],
returnSatChannel: 0
}
const params = {
headers: await setHeaders()
}
const data = await axios const data = await axios
.get(`${API_PROD_ENDPOINT}/channels?cityId=28001&language=en&productClass=Orion-DASH`) .post(url, body, params)
.then(r => r.data) .then(r => r.data)
.catch(console.log) .catch(console.log)
return data.map(item => { return data.channellist.map(item => {
return { return {
lang: 'nl', lang: 'de',
site_id: item.id, site_id: item.contentId,
name: item.name name: item.name
} }
}) })
} }
} }
async function loadProgramDetails(item, channel) { function parseCategory(item) {
if (!item.id) return {} return item.genres
const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true&language=${channel.lang}` ? item.genres
const data = await axios .replace('und', ',')
.get(url) .split(',')
.then(r => r.data) .map(i => i.trim())
.catch(console.log) : []
}
return data || {} function parseDirectors(item) {
if (!item.cast || !item.cast.director) return []
return item.cast.director
.replace('und', ',')
.split(',')
.map(i => i.trim())
}
function parseProducers(item) {
if (!item.cast || !item.cast.producer) return []
return item.cast.producer
.replace('und', ',')
.split(',')
.map(i => i.trim())
}
function parseAdapters(item) {
if (!item.cast || !item.cast.adaptor) return []
return item.cast.adaptor
.replace('und', ',')
.split(',')
.map(i => i.trim())
}
function parseUrls(item) {
// currently only a imdb id is returned by the api, thus we can construct the url here
if (!item.externalIds) return []
return JSON.parse(item.externalIds)
.filter(externalId => externalId.type === 'imdb' && externalId.id)
.map(externalId => ({ system: 'imdb', value: `https://www.imdb.com/title/${externalId.id}` }))
}
function parseImage(item) {
if (!Array.isArray(item.pictures) || !item.pictures.length) return null
return item.pictures[0].href
} }
function parseStart(item) { function parseStart(item) {
return dayjs.unix(item.startTime) return dayjs.utc(item.starttime, 'YYYY-MM-DD HH:mm:ss')
} }
function parseStop(item) { function parseStop(item) {
return dayjs.unix(item.endTime) return dayjs.utc(item.endtime, 'YYYY-MM-DD HH:mm:ss')
} }
function parseItems(content, channel) { function parseItems(content) {
if (!content) return []
const data = JSON.parse(content) const data = JSON.parse(content)
if (!data || !Array.isArray(data.entries)) return [] if (!data || !Array.isArray(data.playbilllist)) return []
const channelData = data.entries.find(e => e.channelId === channel.site_id)
if (!channelData) return []
return Array.isArray(channelData.events) ? channelData.events : [] return data.playbilllist
} }
function parseSeason(detail) { async function fetchCookieAndToken() {
if (!detail.seasonNumber) return null // Only fetch the cookies and csrfToken if they are not already set
if (String(detail.seasonNumber).length > 2) return null if (X_CSRFTOKEN && Cookie) {
return detail.seasonNumber return
}
try {
const response = await axios.request({
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/Authenticate',
params: {
SID: 'firstup',
T: 'Windows_chrome_118'
},
method: 'POST',
data: '{"terminalid":"00:00:00:00:00:00","mac":"00:00:00:00:00:00","terminaltype":"WEBTV","utcEnable":1,"timezone":"Etc/GMT0","userType":3,"terminalvendor":"Unknown"}'
})
// Extract the cookies specified in cookiesToExtract
const setCookieHeader = response.headers['set-cookie'] || []
const extractedCookies = []
cookiesToExtract.forEach(cookieName => {
const regex = new RegExp(`${cookieName}=(.+?)(;|$)`)
const match = setCookieHeader.find(header => regex.test(header))
if (match) {
const cookieString = regex.exec(match)[0]
extractedCookies.push(cookieString)
}
})
// check if we recieved a csrfToken only then store the values
if (!response.data.csrfToken) {
console.log('csrfToken not found in the response.')
return
}
X_CSRFTOKEN = response.data.csrfToken
Cookie = extractedCookies.join(' ')
} catch (error) {
console.error(error)
}
} }
function parseEpisode(detail) { async function setHeaders() {
if (!detail.episodeNumber) return null await fetchCookieAndToken()
if (String(detail.episodeNumber).length > 3) return null
return detail.episodeNumber
}
function parseIcon(item) { return { X_CSRFTOKEN, Cookie }
return `${API_IMAGE_ENDPOINT}/intent/${item.id}/posterTile`; }
}
@@ -1,16 +1,13 @@
// credit for this fix goes to klausellus-wallace for his PR on https://github.com/iptv-org/epg/pull/2458 // https://github.com/iptv-org/epg/blob/e4f92bb2a2768dcba3dbbd52b19d78d96bebc31e/sites/web.magentatv.de/web.magentatv.de.config.js
const axios = require('axios') const axios = require('axios')
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat') const customParseFormat = require('dayjs/plugin/customParseFormat')
const fetch = require('node-fetch')
const { upperCase } = require('lodash')
let X_CSRFTOKEN let X_CSRFTOKEN
let COOKIE let Cookie
const cookiesToExtract = ['JSESSIONID', 'CSESSIONID', 'CSRFSESSION'] const cookiesToExtract = ['JSESSIONID', 'CSESSIONID', 'CSRFSESSION']
const extractedCookies = {}
dayjs.extend(utc) dayjs.extend(utc)
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
@@ -21,10 +18,9 @@ module.exports = {
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList', url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList',
request: { request: {
method: 'POST', method: 'POST',
headers: function () { async headers() {
return setHeaders() return await setHeaders()
}, },
data({ channel, date }) { data({ channel, date }) {
return { return {
count: -1, count: -1,
@@ -32,7 +28,8 @@ module.exports = {
offset: 0, offset: 0,
properties: [ properties: [
{ {
include: 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds', include:
'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
name: 'playbill' name: 'playbill'
} }
], ],
@@ -43,8 +40,8 @@ module.exports = {
} }
} }
}, },
parser: function ({ content }) { parser({ content }) {
let programs = [] const programs = []
const items = parseItems(content) const items = parseItems(content)
items.forEach(item => { items.forEach(item => {
programs.push({ programs.push({
@@ -60,7 +57,7 @@ module.exports = {
directors: parseDirectors(item), directors: parseDirectors(item),
producers: parseProducers(item), producers: parseProducers(item),
adapters: parseAdapters(item), adapters: parseAdapters(item),
country: upperCase(item.country), country: item.country?.toUpperCase(),
date: item.producedate, date: item.producedate,
urls: parseUrls(item) urls: parseUrls(item)
}) })
@@ -115,15 +112,15 @@ function parseCategory(item) {
} }
function parseDirectors(item) { function parseDirectors(item) {
if (!item.cast || !item.cast.director) return []; if (!item.cast || !item.cast.director) return []
return item.cast.director return item.cast.director
.replace('und', ',') .replace('und', ',')
.split(',') .split(',')
.map(i => i.trim()); .map(i => i.trim())
} }
function parseProducers(item) { function parseProducers(item) {
if (!item.cast || !item.cast.producer) return []; if (!item.cast || !item.cast.producer) return []
return item.cast.producer return item.cast.producer
.replace('und', ',') .replace('und', ',')
.split(',') .split(',')
@@ -131,7 +128,7 @@ function parseProducers(item) {
} }
function parseAdapters(item) { function parseAdapters(item) {
if (!item.cast || !item.cast.adaptor) return []; if (!item.cast || !item.cast.adaptor) return []
return item.cast.adaptor return item.cast.adaptor
.replace('und', ',') .replace('und', ',')
.split(',') .split(',')
@@ -140,7 +137,7 @@ function parseAdapters(item) {
function parseUrls(item) { function parseUrls(item) {
// currently only a imdb id is returned by the api, thus we can construct the url here // currently only a imdb id is returned by the api, thus we can construct the url here
if (!item.externalIds) return []; if (!item.externalIds) return []
return JSON.parse(item.externalIds) return JSON.parse(item.externalIds)
.filter(externalId => externalId.type === 'imdb' && externalId.id) .filter(externalId => externalId.type === 'imdb' && externalId.id)
.map(externalId => ({ system: 'imdb', value: `https://www.imdb.com/title/${externalId.id}` })) .map(externalId => ({ system: 'imdb', value: `https://www.imdb.com/title/${externalId.id}` }))
@@ -167,66 +164,52 @@ function parseItems(content) {
return data.playbilllist return data.playbilllist
} }
// Function to try to fetch COOKIE and X_CSRFTOKEN async function fetchCookieAndToken() {
function fetchCookieAndToken() { // Only fetch the cookies and csrfToken if they are not already set
return fetch( if (X_CSRFTOKEN && Cookie) {
'https://api.prod.sngtv.magentatv.de/EPG/JSON/Authenticate?SID=firstup&T=Windows_chrome_118', return
{ }
headers: {
accept: 'application/json, text/javascript, */*; q=0.01', try {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', const response = await axios.request({
'sec-fetch-dest': 'empty', url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/Authenticate',
'sec-fetch-mode': 'cors', params: {
'sec-fetch-site': 'same-origin', SID: 'firstup',
'x-requested-with': 'XMLHttpRequest', T: 'Windows_chrome_118'
Referer: 'https://web.magentatv.de/',
'Referrer-Policy': 'strict-origin-when-cross-origin'
}, },
body: '{"terminalid":"00:00:00:00:00:00","mac":"00:00:00:00:00:00","terminaltype":"WEBTV","utcEnable":1,"timezone":"Etc/GMT0","userType":3,"terminalvendor":"Unknown"}', method: 'POST',
method: 'POST' data: '{"terminalid":"00:00:00:00:00:00","mac":"00:00:00:00:00:00","terminaltype":"WEBTV","utcEnable":1,"timezone":"Etc/GMT0","userType":3,"terminalvendor":"Unknown"}',
})
// Extract the cookies specified in cookiesToExtract
const setCookieHeader = response.headers['set-cookie'] || []
const extractedCookies = []
cookiesToExtract.forEach(cookieName => {
const regex = new RegExp(`${cookieName}=(.+?)(;|$)`)
const match = setCookieHeader.find(header => regex.test(header))
if (match) {
const cookieString = regex.exec(match)[0]
extractedCookies.push(cookieString)
}
})
// check if we recieved a csrfToken only then store the values
if (!response.data.csrfToken) {
console.log('csrfToken not found in the response.')
return
} }
)
.then(response => {
// Check if the response status is OK (2xx)
if (!response.ok) {
throw new Error('HTTP request failed')
}
// Extract the set-cookie header X_CSRFTOKEN = response.data.csrfToken
const setCookieHeader = response.headers.raw()['set-cookie'] Cookie = extractedCookies.join(' ')
// Extract the cookies specified in cookiesToExtract } catch(error) {
cookiesToExtract.forEach(cookieName => { console.error(error)
const regex = new RegExp(`${cookieName}=(.+?)(;|$)`) }
const match = setCookieHeader.find(header => regex.test(header))
if (match) {
const cookieValue = regex.exec(match)[1]
extractedCookies[cookieName] = cookieValue
}
})
return response.json()
})
.then(data => {
if (data.csrfToken) {
X_CSRFTOKEN = data.csrfToken
COOKIE = `JSESSIONID=${extractedCookies.JSESSIONID}; CSESSIONID=${extractedCookies.CSESSIONID}; CSRFSESSION=${extractedCookies.CSRFSESSION}; JSESSIONID=${extractedCookies.JSESSIONID};`
} else {
console.log('csrfToken not found in the response.')
}
})
.catch(error => {
console.error(error)
})
} }
function setHeaders() { async function setHeaders() {
return fetchCookieAndToken().then(() => { await fetchCookieAndToken()
return {
X_CSRFTOKEN: X_CSRFTOKEN, return { X_CSRFTOKEN, Cookie }
'Content-Type': 'application/json',
Cookie: COOKIE
}
})
} }
+23
View File
@@ -0,0 +1,23 @@
module.exports = {
apps: [
{
name: 'serve',
script: 'npx serve -- public',
instances: 1,
watch: false,
autorestart: true
},
{
name: 'grab',
script: process.env.SITE
? `npm run grab -- --site=${process.env.SITE} ${
process.env.CLANG ? `--lang=${process.env.CLANG}` : ''
} --output=public/guide.xml`
: `npm run grab -- --gzip --channels=channels.xml --output=public/guide.xml`,
cron_restart: process.env.CRON_SCHEDULE || null,
instances: 1,
watch: false,
autorestart: false
}
]
}
+4 -5
View File
@@ -6,9 +6,10 @@ for arg in "$@"; do
chron-schedule=*) chron_schedule="${arg#*=}" ;; chron-schedule=*) chron_schedule="${arg#*=}" ;;
work-dir=*) work_dir="${arg#*=}" ;; work-dir=*) work_dir="${arg#*=}" ;;
days=*) days="${arg#*=}" ;; days=*) days="${arg#*=}" ;;
delay=*) delay="${arg#*=}" ;;
max_connections=*) max_connections="${arg#*=}" ;; max_connections=*) max_connections="${arg#*=}" ;;
enable_fixes=*) enable_fixes="${arg#*=}" ;; enable_fixes=*) enable_fixes="${arg#*=}" ;;
api_url=*) api_url="${arg#*=}" ;; api_url=*) api_url="${arg#*=}" ;;
esac esac
done done
@@ -16,6 +17,7 @@ echo "chron_schedule : ${chron_schedule}"
cd $work_dir cd $work_dir
echo "working dir : " $(pwd) echo "working dir : " $(pwd)
echo "days : ${days}" echo "days : ${days}"
echo "delay : ${delay}"
echo "max_connections : ${max_connections}" echo "max_connections : ${max_connections}"
echo "enable_fixes : ${enable_fixes}" echo "enable_fixes : ${enable_fixes}"
echo "api url : ${api_url}" echo "api url : ${api_url}"
@@ -25,9 +27,6 @@ if [ "$enable_fixes" = true ] ; then
fi fi
sed -i -E "s/(https:\x2f\x2fiptv-org.github.io\x2fapi$\123filename\125)/$api_url$\123filename\125/g" $work_dir/scripts/core/apiClient.ts sed -i -E "s/(https:\x2f\x2fiptv-org.github.io\x2fapi$\123filename\125)/$api_url$\123filename\125/g" $work_dir/scripts/core/apiClient.ts
pm2 --name epg start npm -- run serve
npm run grab --- --channels=channels.xml --maxConnections=$max_connections --days=$days --gzip
ln -s $work_dir/guide.xml /public/guide.xml ln -s $work_dir/guide.xml /public/guide.xml
ln -s $work_dir/guide.xml.gz /public/guide.xml.gz ln -s $work_dir/guide.xml.gz /public/guide.xml.gz
npm run grab --- --channels=channels.xml --cron="$chron_schedule" --maxConnections=$max_connections --days=$days --gzip pm2-runtime pm2.config.js --name epg --node-args="--no-autorestart --cron-restart="$chron_schedule" --maxConnections=$max_connections --days=$days --delay=$delay"