Compare commits

..

90 Commits

Author SHA1 Message Date
86e66ede1d update readme and update custom fixes
All checks were successful
Build docker container / build (push) Successful in 15m44s
2026-02-24 12:46:24 +01:00
c113fd0bbc update readme
All checks were successful
Build docker container / build (push) Successful in 10m25s
2026-02-18 12:56:29 +01:00
54f8e6b157 update action 2026-02-18 12:54:40 +01:00
be44be878c change action
All checks were successful
Build docker container / build (push) Successful in 7m33s
2026-02-12 10:17:30 +01:00
1700fbe251 update readme
Some checks failed
Build docker container / build (push) Failing after 1m49s
2026-02-12 08:59:35 +01:00
b760bbdf3e update action 2026-02-12 08:58:18 +01:00
8c609f5515 update action 2026-02-09 15:48:15 +01:00
ff31a3b737 update action 2026-02-09 15:32:40 +01:00
123285107d update action
All checks were successful
Build docker container / build (push) Successful in 8m2s
2026-02-09 10:16:06 +01:00
3d13569146 update action 2026-02-09 09:57:40 +01:00
e9bc6f5246 update action
Some checks failed
Build docker container / build (push) Failing after 6m51s
2026-02-09 09:37:49 +01:00
5c662bae69 update docker action + readme
Some checks failed
Build docker container / build (push) Failing after 7m26s
2026-02-09 09:25:34 +01:00
David Claeys
eece21742c update readme
All checks were successful
Build docker container / build (push) Successful in 8m2s
2026-01-08 13:44:06 +01:00
David Claeys
ee126cf60c update readme
All checks were successful
Build docker container / build (push) Successful in 8m51s
2025-12-24 14:25:57 +01:00
David Claeys
db28863295 update readme
All checks were successful
Build docker container / build (push) Successful in 11m38s
2025-11-26 11:26:24 +01:00
David Claeys
223a4ea6b5 update readme
All checks were successful
Build docker container / build (push) Successful in 7m36s
2025-11-19 10:53:46 +01:00
David Claeys
e6ee948355 update readme
All checks were successful
Build docker container / build (push) Successful in 9m23s
2025-10-09 14:18:30 +02:00
David Claeys
2662567576 update readme
All checks were successful
Build docker container / build (push) Successful in 18m38s
2025-09-25 09:36:24 +02:00
David Claeys
309038bb4a update readme + config
All checks were successful
Build docker container / build (push) Successful in 25m21s
2025-07-15 09:24:34 +02:00
David Claeys
3b019df919 update readme
All checks were successful
Build docker container / build (push) Successful in 8m14s
2025-07-07 08:53:11 +02:00
David Claeys
1cf21ddb98 update readme
All checks were successful
Build docker container / build (push) Successful in 8m52s
2025-06-27 11:15:21 +02:00
David Claeys
0aeb48fe2f update readme
All checks were successful
Build docker container / build (push) Successful in 6m37s
2025-06-17 08:10:34 +02:00
David Claeys
70c7ee79b0 update readme
All checks were successful
Build docker container / build (push) Successful in 8m4s
2025-06-02 11:13:55 +02:00
David Claeys
62937901c2 update readme
All checks were successful
Build docker container / build (push) Successful in 6m34s
2025-05-16 08:42:21 +02:00
David Claeys
4e5a2b4d27 update readme
All checks were successful
Build docker container / build (push) Successful in 6m3s
2025-04-23 08:43:25 +02:00
David Claeys
ab9a8d7160 add delay option
All checks were successful
Build docker container / build (push) Successful in 6m12s
2025-04-14 09:15:43 +02:00
David Claeys
e080a976a6 update readme
All checks were successful
Build docker container / build (push) Successful in 13m7s
2025-04-09 10:23:29 +02:00
David Claeys
252a7b23aa bugfixes
Some checks failed
Build docker container / build (push) Failing after 20m44s
2025-04-07 09:02:22 +02:00
David Claeys
0a4d9c4452 update readme
All checks were successful
Build docker container / build (push) Successful in 12m5s
2025-04-04 08:25:49 +02:00
David Claeys
6939823646 update readme
All checks were successful
Build docker container / build (push) Successful in 7m3s
2025-03-27 08:32:17 +01:00
David Claeys
60503e87ed update readme
All checks were successful
Build docker container / build (push) Successful in 7m23s
2025-03-20 10:00:44 +01:00
David Claeys
2f732b6dcc update readme
All checks were successful
Build docker container / build (push) Successful in 6m14s
2025-03-11 08:09:05 +01:00
David Claeys
1f999d1c3c update readme
All checks were successful
Build docker container / build (push) Successful in 4m55s
2025-03-07 09:11:14 +01:00
David Claeys
3f5b36a878 update readme
All checks were successful
Build docker container / build (push) Successful in 5m10s
2025-02-26 08:41:29 +01:00
David Claeys
f1c905f5dd update readme
All checks were successful
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
All checks were successful
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
All checks were successful
Build docker container / build (push) Successful in 5m2s
2025-02-05 09:04:30 +01:00
David Claeys
1521795dd8 update readme
All checks were successful
Build docker container / build (push) Successful in 7m0s
2025-02-03 08:45:34 +01:00
David Claeys
645569dc97 update readme
All checks were successful
Build docker container / build (push) Successful in 4m1s
2025-01-30 10:11:58 +01:00
David Claeys
113b6b678e update readme
All checks were successful
Build docker container / build (push) Successful in 8m42s
2025-01-29 08:44:29 +01:00
David Claeys
512d8257fd update readme
All checks were successful
Build docker container / build (push) Successful in 6m56s
2025-01-27 08:34:53 +01:00
David Claeys
db7680861e update readme
All checks were successful
Build docker container / build (push) Successful in 9m2s
2025-01-23 12:40:25 +01:00
David Claeys
8623771537 change fixes + change readme
All checks were successful
Build docker container / build (push) Successful in 5m7s
2025-01-21 11:54:21 +01:00
David Claeys
4199210593 update readme
All checks were successful
Build docker container / build (push) Successful in 4m16s
2025-01-20 08:14:36 +01:00
David Claeys
3c9432d1f3 update readme
All checks were successful
Build docker container / build (push) Successful in 2m32s
2025-01-17 08:35:13 +01:00
David Claeys
fa76db456f update readme
All checks were successful
Build docker container / build (push) Successful in 2m12s
2025-01-15 08:39:08 +01:00
David Claeys
b434ce505b update readme + fix issue api url
Some checks failed
Build docker container / build (push) Has been cancelled
2025-01-14 10:45:29 +01:00
David Claeys
2d3ffcbd42 update readme
All checks were successful
Build docker container / build (push) Successful in 8m11s
2025-01-14 09:23:45 +01:00
David Claeys
c4c0bf5270 update readme
All checks were successful
Build docker container / build (push) Successful in 2m30s
2025-01-13 11:01:30 +01:00
David Claeys
8736114213 update orangetv.orange.es 2025-01-13 11:00:37 +01:00
David Claeys
075ac41e2a update readme + fix Dockefile
All checks were successful
Build docker container / build (push) Successful in 9m7s
2025-01-09 15:23:28 +01:00
David Claeys
c7dc12f4bb update readme
Some checks failed
Build docker container / build (push) Failing after 2m3s
2025-01-09 14:49:30 +01:00
David Claeys
3a7f23577a update readme
Some checks failed
Build docker container / build (push) Failing after 12m15s
2025-01-06 08:37:52 +01:00
David Claeys
02725264fd update readme 2024-12-31 21:15:59 +01:00
David Claeys
ef25f64dcd orangetv rename + update readme
All checks were successful
Build docker container / build (push) Successful in 2m7s
2024-12-31 18:31:29 +01:00
David Claeys
47e8a82c41 update readme
All checks were successful
Build docker container / build (push) Successful in 2m8s
2024-12-31 08:38:51 +01:00
David Claeys
5be16e5544 update readme
All checks were successful
Build docker container / build (push) Successful in 8m35s
2024-12-27 12:18:43 +01:00
David Claeys
91ad05ab89 update readme
All checks were successful
Build docker container / build (push) Successful in 8m52s
2024-12-24 08:57:04 +01:00
David Claeys
e9116631d8 update organtv.es channels file 2024-12-24 08:55:37 +01:00
David Claeys
330099049a update readme
All checks were successful
Build docker container / build (push) Successful in 2m29s
2024-12-20 08:28:54 +01:00
David Claeys
06dca856ad update readme 2024-12-20 08:28:09 +01:00
David Claeys
b042f5ac8e provider fixes + version update 2024-12-20 08:26:15 +01:00
David Claeys
4ba2fce7cf update dockerfile
All checks were successful
Build docker container / build (push) Successful in 7m33s
2024-12-18 11:27:05 +01:00
David Claeys
3c66cce5dd update readme
All checks were successful
Build docker container / build (push) Successful in 10m17s
2024-12-18 10:18:51 +01:00
David Claeys
50ae72364c update readme + mayor updates 2024-12-18 10:17:15 +01:00
David Claeys
490520775f update readme
All checks were successful
Build docker container / build (push) Successful in 8m55s
2024-12-16 09:12:10 +01:00
David Claeys
8231301a53 update readme
All checks were successful
Build docker container / build (push) Successful in 13m56s
2024-12-12 08:42:22 +01:00
David Claeys
2e8e8fb440 update readme
All checks were successful
Build docker container / build (push) Successful in 14m48s
2024-12-09 08:35:29 +01:00
David Claeys
ff1928a09f update readme
All checks were successful
Build docker container / build (push) Successful in 11m4s
2024-12-07 09:44:47 +01:00
David Claeys
1ff85a3a26 update readme
All checks were successful
Build docker container / build (push) Successful in 8m5s
2024-12-05 09:06:29 +01:00
David Claeys
6b723e1776 update readme
All checks were successful
Build docker container / build (push) Successful in 11m34s
2024-12-04 08:38:48 +01:00
David Claeys
8aacebad42 remove log 2024-12-03 09:54:41 +01:00
David Claeys
d388307b85 update readme
All checks were successful
Build docker container / build (push) Successful in 7m17s
2024-12-03 09:50:42 +01:00
David Claeys
e04ec220e3 update movistarplus channel grabber 2024-12-03 09:48:53 +01:00
David Claeys
6ff94a3848 update readme 2024-12-03 08:27:30 +01:00
David Claeys
1f885bbd1c update readme
All checks were successful
Build docker container / build (push) Successful in 8m36s
2024-12-02 20:04:38 +01:00
David Claeys
e99af0bc2b update readme 2024-12-02 19:47:52 +01:00
David Claeys
2f86d79697 update orangetv channel list 2024-12-02 15:48:54 +01:00
David Claeys
0e72cce51f update orangetv.es custom fix 2024-12-02 14:05:42 +01:00
David Claeys
2b7b095419 update readme
All checks were successful
Build docker container / build (push) Successful in 5m28s
2024-12-01 16:27:23 +01:00
David Claeys
bb828fd0eb update orangetv channel list 2024-12-01 16:26:08 +01:00
David Claeys
d957c4d873 add extra fix and update readme
All checks were successful
Build docker container / build (push) Successful in 2m15s
2024-11-29 13:45:15 +01:00
David Claeys
613da613c4 update readme
All checks were successful
Build docker container / build (push) Successful in 3m24s
2024-11-29 09:08:36 +01:00
David Claeys
9c5e4ad69b update readme
All checks were successful
Build docker container / build (push) Successful in 6m12s
2024-11-28 08:14:05 +01:00
David Claeys
8e448d6c57 update readme
All checks were successful
Build docker container / build (push) Successful in 5m21s
2024-11-27 08:36:24 +01:00
David Claeys
31eb8abddf update readme
All checks were successful
Build docker container / build (push) Successful in 4m46s
2024-11-26 13:43:12 +01:00
David Claeys
6acb07ed4e update readme and fix 2024-11-26 13:41:02 +01:00
David Claeys
02133f0692 update custom fix
All checks were successful
Build docker container / build (push) Successful in 4m26s
2024-11-26 13:03:55 +01:00
12 changed files with 604 additions and 263 deletions

View File

@@ -21,6 +21,64 @@ jobs:
echo "Docker installation not found. Docker will be installed"
curl -fsSL https://get.docker.com | sh
fi
- name: Install npm dependencies
run: |
echo "Installing fetch"
install_node=$false
if ! command -v node &> /dev/null; then
echo "No version of NodeJS detected"
install_node=true
else
node_version=$(node -v)
node_version=${node_version:1} # Remove 'v' at the beginning
node_version=${node_version%\.*} # Remove trailing ".*".
node_version=${node_version%\.*} # Remove trailing ".*".
node_version=$(($node_version)) # Convert the NodeJS version number from a string to an integer.
if [ $node_version -lt 24 ]; then
echo "node version : " $node_version
echo $"removing outdated npm version"
install_node=true
apt-get remove nodejs npm
apt-get purge nodejs
rm -rf /usr/local/bin/npm
rm -rf /usr/local/share/man/man1/node*
rm -rf /usr/local/lib/dtrace/node.d
rm -rf ~/.npm
rm -rf ~/.node-gyp
rm -rf /opt/local/bin/node
rm -rf opt/local/include/node
rm -rf /opt/local/lib/node_modules
rm -rf /usr/local/lib/node*
rm -rf /usr/local/include/node*
rm -rf /usr/local/bin/node*
fi
fi
if $install_node; then
NODE_MAJOR=24
echo "Installing node ${NODE_MAJOR}"
if test -f /etc/apt/keyrings/nodesource.gpg; then
rm /etc/apt/keyrings/nodesource.gpg
fi
if test -f /etc/apt/sources.list.d/nodesource.list; then
rm /etc/apt/sources.list.d/nodesource.list
fi
apt-get update
apt-get install -y -q ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
apt-get update
apt-get install -y -q nodejs
npm install npm --global
fi
echo "node version : " $(node -v)
package='node-fetch'
if [ `npm list -g | grep -c $package` -eq 0 ]; then
npm install -g $package
fi
- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v3
- name: Login to Gitea container registry
@@ -32,18 +90,29 @@ jobs:
- name: Login to DockerHub container registry
uses: https://github.com/docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME}}
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
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: |
davidquinonescl/epg-info
git.claeyscloud.com/david/epg-info
tags: |
type=semver,pattern={{raw}}
type=sha
- name: Update docker Hub Description
uses: https://github.com/peter-evans/dockerhub-description@v5
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
repository: davidquinonescl/epg-info
- name: Build and push
uses: https://github.com/docker/build-push-action@v5
with:
@@ -51,4 +120,3 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -24,6 +24,11 @@ jobs:
id: meta
uses: docker/metadata-action@v5
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
tags: |
type=semver,pattern={{raw}}

View File

@@ -1,9 +1,10 @@
FROM node:21-alpine
FROM node:22-alpine
ARG GIT_REPO=https://github.com/iptv-org/epg.git
ARG GIT_BRANCH=master
ENV CRON_SCHEDULE="0 0,12 * * *"
ENV API_URL="https://iptv-org.github.io/api"
ENV DAYS=14
ENV DELAY=0
ENV MAX_CONNECTIONS=10
ENV ENABLE_FIXES=false
ARG BIN_FOLDER=/bin
@@ -23,7 +24,8 @@ RUN apk update \
&& mkdir $(echo "${BIN_FOLDER}/${EPG_FOLDER}") -p \
&& git -C $(echo "${BIN_FOLDER}") clone --depth 1 -b $(echo "${GIT_BRANCH} ${GIT_REPO}") \
&& cd $WORKDIR && npm install && npm update \
&& rm .eslintrc.json \
&& rm -rf .sites \
&& rm -rf .husky \
&& rm -rf .github \
&& rm -rf .git \
&& rm .gitignore \
@@ -41,14 +43,20 @@ RUN apk update \
&& rm -rf node_modules/**/.github \
&& rm -rf node_modules/**/docs \
&& rm -rf node_modules/**/LICENSE \
&& rm -rf node_modules/**/license \
&& rm -rf node_modules/**/**.md \
&& rm -rf node_modules/**/**/LICENSE \
&& rm -rf node_modules/**/**/license \
&& rm -rf node_modules/**/**/.github \
&& rm -rf node_modules/**/**/**.md \
&& ln -s /config/channels.xml $(echo "${WORKDIR}/channels.xml") \
&& mkdir /public
COPY start.sh $WORKDIR
COPY serve.json $WORKDIR
COPY pm2.config.js $WORKDIR
RUN chmod +x "$START_SCRIPT" \
&& apk del git curl \
&& rm -rf /var/cache/apk/*
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

144
README.md
View File

@@ -11,7 +11,7 @@ A public mirror is available at https://github.com/davidclaeysquinones/epg-info-
[pm2](https://www.npmjs.com/package/pm2)<br>
[serve](https://www.npmjs.com/package/serve)<br>
The image is based on `node:21-alpine` in order to be more lightweight.
The image is based on `node:22-alpine` in order to be more lightweight.
The `pm2` and `serve` packages are used in order to run the application in the container.
## Docker image
@@ -38,12 +38,13 @@ If you have suggestions or a problem with them please submit an issue.
This the list of the provided custom fixes :
| Provider | Author | Status |
|------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| movistarplus.es | [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2440) pending approval |
| pickx.be | [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2430) merged since commit [d159110](https://github.com/iptv-org/epg/commit/d15911006e163262c0c7f267deae28160c0d7a8f) |
| 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) |
| web.magentatv.de | [klausellus-wallace](https://github.com/klausellus-wallace) | [PR](https://github.com/iptv-org/epg/pull/2458) pending approval |
| Provider | Author(s) | Status |
|--------------------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| movistarplus.es | [davidclaeysquinones](https://github.com/davidclaeysquinones) | [PR](https://github.com/iptv-org/epg/pull/2440) pending approval |
| 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) |
| 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) |
| 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) |
| 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) |
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>
@@ -55,6 +56,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 * * *` |
| 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 |
| 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` |
@@ -121,3 +123,131 @@ Sometimes a new version of this image will be bound to the same source commit. T
[10-14-2024](https://github.com/iptv-org/epg/commit/7610f7b9f5cc1ccab8d17f3408a95d31b36ace7c)<br>Change fix for movistarplus.es in order to work with new API
- 1.0.15
[11-26-2024](https://github.com/iptv-org/epg/commit/d15911006e163262c0c7f267deae28160c0d7a8f)<br>Add option to customize channel endpoint
- 1.0.16
[11-26-2024](https://github.com/iptv-org/epg/commit/d15911006e163262c0c7f267deae28160c0d7a8f)<br>Fix icons for movistarplus.es
- 1.0.17
[11-26-2024](https://github.com/iptv-org/epg/commit/d15911006e163262c0c7f267deae28160c0d7a8f)<br>Update fix for pickx.be
- 1.0.18
[11-27-2024 01:51](https://github.com/iptv-org/epg/commit/78dad4cfb4fc16f078c3b44b5534779c7c645b6b)
- 1.0.19
[11-27-2024 15:43](https://github.com/iptv-org/epg/commit/e5f0850b3b2e35ed394f00ac68b699eaabc4f0e4)
- 1.0.20
[11-28-2024](https://github.com/iptv-org/epg/commit/da18b70ddb1c3950e5a315411fd9aeaf60b6092c)
- 1.0.21
[11-28-2024](https://github.com/iptv-org/epg/commit/da18b70ddb1c3950e5a315411fd9aeaf60b6092c)<br>Add orangetv.es
- 1.0.22
[11-30-2024](https://github.com/iptv-org/epg/commit/1883338c0aee9909ac4567312b25701d10a765f2)
- 1.0.23
[12-02-2024](https://github.com/iptv-org/epg/commit/296d6162ecbeb1b3c3e392845187d30624d50aa2)
- 1.0.24
[12-02-2024](https://github.com/iptv-org/epg/commit/296d6162ecbeb1b3c3e392845187d30624d50aa2)<br>Fix for movistarplus.es channel grabber
- 1.0.25
[12-04-2024](https://github.com/iptv-org/epg/commit/864e0ac2c4761d926b203a85a382a4bdc87fbc17)
- 1.0.26
[12-05-2024](https://github.com/iptv-org/epg/commit/581441834af6f089c3930ad2d7ff1de2c701a6d9)
- 1.0.27
[12-07-2024](https://github.com/iptv-org/epg/commit/ce4f3e69358385d1fb8e79df8129c63d6314a802)
- 1.0.28
[12-08-2024](https://github.com/iptv-org/epg/commit/f9c8fc1b2dd63465564aba0c720096574980c58f)
- 1.0.29
[12-11-2024](https://github.com/iptv-org/epg/commit/581f5e0ca94bd6d05c33f53951df078d702b2510)
- 1.0.30
[12-16-2024](https://github.com/iptv-org/epg/commit/b9bbd32d354315eb292e3b82da09785e575a9781)
- 1.0.31
[12-17-2024](https://github.com/iptv-org/epg/commit/7237a62d94c5691f7f467b334f846efce93b08ff)<br>Fix for Pickx.be + mayor program updates
- 1.0.32
[12-20-2024](https://github.com/iptv-org/epg/commit/f00d53cb7be3cd7f6625897709cab005fe1b3dc4)
- 1.0.33
[12-21-2024](https://github.com/iptv-org/epg/commit/c108aa586e25d2e8914baeca6c05cc6755718665)
- 1.0.34
[12-27-2024](https://github.com/iptv-org/epg/commit/141fc210c4b7109e8ba09299d4f49c451ae0db4e)
- 1.0.35
[12-31-2024 06:25](https://github.com/iptv-org/epg/commit/7e7efaa48717d6b96f6d05aa9cf73271750d788b)
- 1.0.36
[12-31-2024 17:32](https://github.com/iptv-org/epg/commit/5ffe285c1e5882e905c5aaee672849f6f89e5cf3)
- 1.0.37
[01-09-2025](https://github.com/iptv-org/epg/commit/8e39af2a4d7c15f442a3e686144278e97151d46e)
- 1.0.38
[01-13-2025](https://github.com/iptv-org/epg/commit/9a565f16f4016e49d17b762477e0f6d29bb0f970)
- 1.0.39
[01-14-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608)
- 1.0.40
[01-14-2025](https://github.com/iptv-org/epg/commit/76df1541d8b0b90533ea74dcbb7815c27425b608)<br> Fixes issue with api url
- 1.0.41
[01-15-2025](https://github.com/iptv-org/epg/commit/65331dff1c6728c3012e314e51d40da85d2d7f3c)
- 1.0.42
[01-15-2025](https://github.com/iptv-org/epg/commit/5958c77c65a652285da64ad8a77d137306ca46d7)
- 1.0.43
[01-20-2025](https://github.com/iptv-org/epg/commit/7b2cfba7f5d4df8c01ff74a7c26d7695cb750244)
- 1.0.44
[01-21-2025](https://github.com/iptv-org/epg/commit/b69d61af5e46cea4f7dcb15a00d897397c23defa)
- 1.0.45
[01-23-2025](https://github.com/iptv-org/epg/commit/bc4b7fcfd51325cc597ccce13821f355dd0fbc72)
- 1.0.46
[01-27-2025](https://github.com/iptv-org/epg/commit/a45a346ec83cae3863b8d0e1cbe7abd99d6fef36)
- 1.0.47
[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

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<!--This is a sample of a channel you can add look at https://github.com/iptv-org/epg/tree/master/sites for the complete list-->
<channel site="movistarplus.es" lang="es" xmltv_id="24Horas.es" site_id="24H">24 Horas</channel>
<channel site="pickx.be" lang="nl" xmltv_id="Een.be" site_id="UID50037">VRT 1</channel>
<!--<channel site="movistarplus.es" lang="es" xmltv_id="24Horas.es" site_id="24H">24 Horas</channel>-->
</channels>

View File

@@ -1,73 +1,146 @@
const { DateTime } = require('luxon')
//https://github.com/iptv-org/epg/blob/master/sites/movistarplus.es/movistarplus.es.config.js
const API_PROGRAM_ENDPOINT = 'https://comunicacion.movistarplus.es'
const API_IMAGE_ENDPOINT = 'https://www.movistarplus.es/recorte/n/caratulaH/';
const axios = require('axios')
const cheerio = require('cheerio')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone')
dayjs.extend(utc)
dayjs.extend(timezone)
module.exports = {
site: 'movistarplus.es',
days: 2,
url: function ({ channel, date }) {
return `${API_PROGRAM_ENDPOINT}/wp-admin/admin-ajax.php`
url({ channel, date }) {
return `https://www.movistarplus.es/programacion-tv/${channel.site_id}/${date.format('YYYY-MM-DD')}`
},
request: {
method: 'POST',
headers: {
Origin: API_PROGRAM_ENDPOINT,
Referer: `${API_PROGRAM_ENDPOINT}/programacion/`,
"Content-Type" : 'application/x-www-form-urlencoded; charset=UTF-8',
},
data: function ({ channel, date }) {
return {
action: 'getProgramation',
day: date.format('YYYY-MM-DD'),
"channels[]": channel.site_id,
};
'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
},
parser({ content, channel, date }) {
async parser({ content, date }) {
let programs = []
let items = parseItems(content, channel);
if (!items.length) return programs;
const $ = cheerio.load(content)
items.forEach(item => {
let startTime = DateTime.fromFormat(
`${item.f_evento_rejilla}`,
'yyyy-MM-dd HH:mm:ss',
{ zone: 'Europe/Madrid' }
).toUTC();
const programDivs = $('div[id^="ele-"]').toArray()
let stopTime = DateTime.fromFormat(
`${item.f_fin_evento_rejilla}`,
'yyyy-MM-dd HH:mm:ss',
{ zone: 'Europe/Madrid' }
).toUTC()
for (let i = 0; i < programDivs.length; i++) {
const el = $(programDivs[i])
// Adjust stop time if it's on the next day
if (stopTime < startTime) {
stopTime = stopTime.plus({ days: 1 });
const title = el.find('li.title').text().trim()
if (!title) continue
const timeText = el.find('li.time').text().trim()
if (!timeText) continue
const [hours, minutes] = timeText.split(':').map(h => parseInt(h, 10))
// Parse time in Spain timezone (Europe/Madrid)
let startDate = dayjs.tz(
`${date.format('YYYY-MM-DD')} ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`,
'YYYY-MM-DD HH:mm',
'Europe/Madrid'
)
// If the time is in early morning (before 5 AM), it's the next day
if (hours < 5) {
startDate = startDate.add(1, 'day')
}
// Calculate end time from next program's start time
let endDate
if (i < programDivs.length - 1) {
const nextEl = $(programDivs[i + 1])
const nextTimeText = nextEl.find('li.time').text().trim()
if (nextTimeText) {
const [nextHours, nextMinutes] = nextTimeText.split(':').map(h => parseInt(h, 10))
endDate = dayjs.tz(
`${date.format('YYYY-MM-DD')} ${nextHours.toString().padStart(2, '0')}:${nextMinutes.toString().padStart(2, '0')}`,
'YYYY-MM-DD HH:mm',
'Europe/Madrid'
)
// If the next time is in early morning (before 5 AM), it's the next day
if (nextHours < 5) {
endDate = endDate.add(1, 'day')
}
// If end time is still before or same as start time, add another day
if (endDate.isBefore(startDate) || endDate.isSame(startDate)) {
endDate = endDate.add(1, 'day')
}
}
}
// If no end time, use start of next day
if (!endDate) {
endDate = startDate.add(1, 'day').startOf('day')
}
const programLink = el.find('a').attr('href')
let description = null
if (programLink) {
description = await getProgramDescription(programLink).catch(() => null)
}
programs.push({
title: item.des_evento_rejilla,
icon: parseIcon(item, channel),
category: item.des_genero,
start: startTime,
stop: stopTime,
title,
description,
start: startDate,
stop: endDate
})
})
}
return programs
},
async channels() {
const html = await axios
.get('https://www.movistarplus.es/programacion-tv', {
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'
}
})
.then(r => r.data)
.catch(console.log)
const $ = cheerio.load(html)
let scheme = $('script:contains(ItemList)').html()
scheme = JSON.parse(scheme)
return scheme.itemListElement.map(el => {
const urlParts = el.item.url.split('/')
const site_id = urlParts.pop().toLowerCase()
return {
lang: 'es',
name: el.item.name,
site_id
}
})
}
}
function parseIcon(item, channel) {
return `${API_IMAGE_ENDPOINT}/M${channel.site_id}P${item.cod_evento_rejilla}`;
}
async function getProgramDescription(programUrl) {
const response = await axios.get(programUrl, {
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',
Referer: 'https://www.movistarplus.es/programacion-tv/'
}
})
function parseItems(content, channel) {
const json = typeof content === 'string' ? JSON.parse(content) : content;
const data = json.channelsProgram;
const $ = cheerio.load(response.data)
const description = $('.show-content .text p').first().text().trim() || null
if (data.length !== 1) return [];
return data[0];
return description
}

View File

@@ -0,0 +1,104 @@
//https://github.com/iptv-org/epg/blob/master/sites/orangetv.orange.es/orangetv.orange.es.config.js
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const doFetch = require('@ntlab/sfetch')
const debug = require('debug')('site:orangetv.orange.es')
dayjs.extend(utc)
doFetch.setDebugger(debug)
const API_PROGRAM_ENDPOINT = 'https://epg.orangetv.orange.es/epg/Smartphone_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'
module.exports = {
site: 'orangetv.orange.es',
days: 2,
request: {
cache: {
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: function({ date, segment = 1 }) {
return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_${segment}.json`
},
async parser({ content, channel, date }) {
const programs = []
const items = parseItems(content, channel)
if (items.length) {
const queues = [
module.exports.url({ date, segment: 2 }),
module.exports.url({ date, segment: 3 })
]
await doFetch(queues, (url, res) => {
items.push(...parseItems(res, channel))
})
programs.push(
...items.map(item => {
return {
title: item.name,
sub_title: item.seriesName,
description: item.description,
category: parseGenres(item),
season: item.seriesSeason ? parseInt(item.seriesSeason) : null,
episode: item.episodeId ? parseInt(item.episodeId) : null,
icon: parseIcon(item),
start: dayjs.utc(item.startDate),
stop: dayjs.utc(item.endDate)
}
})
)
}
return programs
},
async channels() {
const axios = require('axios')
const data = await axios
.get(API_CHANNEL_ENDPOINT)
.then(r => r.data)
.catch(console.error)
return data.response.map(item => {
return {
lang: 'es',
name: item.name,
site_id: item.externalChannelId
}
})
}
}
function parseIcon(item) {
if (item.attachments.length) {
const cover = item.attachments.find(i => i.name.match(/cover/i))
if (cover) {
return `${API_IMAGE_ENDPOINT}${cover.value}`
}
}
}
function parseGenres(item) {
return item.genres.map(i => i.name)
}
function parseItems(content, channel) {
const result = []
const json =
typeof content === 'string' ? JSON.parse(content) : Array.isArray(content) ? content : []
if (Array.isArray(json)) {
json
.filter(i => i.channelExternalId === channel.site_id)
.forEach(i => {
result.push(...i.programs)
})
}
return result
}

View File

@@ -1,34 +1,18 @@
// 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/blob/e4f92bb2a2768dcba3dbbd52b19d78d96bebc31e/sites/pickx.be/pickx.be.config.js
const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
let apiVersion
let isApiVersionFetched = false
;(async () => {
try {
await fetchApiVersion()
isApiVersionFetched = true
} catch (error) {
console.error('Error during script initialization:', error)
}
})()
dayjs.extend(utc)
module.exports = {
site: 'pickx.be',
days: 2,
apiVersion: function () {
return apiVersion
},
fetchApiVersion: fetchApiVersion, // Export fetchApiVersion
url: async function ({ channel, date }) {
while (!isApiVersionFetched) {
await new Promise(resolve => setTimeout(resolve, 100)) // Wait for 100 milliseconds
async url({ 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`
@@ -52,25 +36,27 @@ module.exports = {
? item.program.translatedCategory[channel.lang]
: item.program.category.split('.')[1],
image: item.program.posterFileName
? `https://experience-cache.proximustv.be/posterserver/poster/EPG/w-166_h-110/${item.program.posterFileName}`
? `https://experience-cache.cdi.streaming.proximustv.be/posterserver/poster/EPG/${item.program.posterFileName}`
: null,
season: item.program.seasonNumber,
episode: item.program.episodeNumber,
actors: item.program.actors,
director: item.program.director ? [item.program.director] : null,
start: dayjs.utc(item.programScheduleStart),
stop: dayjs.utc(item.programScheduleEnd)
start: dayjs(item.programScheduleStart),
stop: dayjs(item.programScheduleEnd)
})
})
}
return programs
},
async channels({ lang = '' }) {
async channels() {
let channels = []
const query = {
operationName: 'getChannels',
variables: {
language: lang,
language: 'fr',
queryParams: {},
id: '0',
params: {
@@ -78,94 +64,60 @@ module.exports = {
}
},
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
}
}`
channels(language: $language, queryParams: $queryParams, id: $id, params: $params) {
id
name
language
radio
}
}`
}
const result = await axios
.post('https://api.proximusmwc.be/tiams/v2/graphql', query)
const data = await axios
.post('https://api.proximusmwc.be/tiams/v3/graphql', query)
.then(r => r.data)
.catch(console.error)
return (
result?.data?.channels
.filter(
channel =>
!channel.radio && (!lang || channel.language === (lang === 'de' ? 'ger' : lang))
)
.map(channel => {
return {
lang: channel.language === 'ger' ? 'de' : channel.language,
site_id: channel.id,
name: channel.name
}
}) || []
)
data.data.channels.forEach(channel => {
let lang = channel.language || 'fr'
if (channel.language === 'ger') lang = 'de'
channels.push({
lang,
site_id: channel.id,
name: channel.name
})
})
return channels
}
}
function fetchApiVersion() {
return new Promise(async (resolve, reject) => {
async function fetchApiVersion() {
const hashUrl = 'https://www.pickx.be/nl/televisie/tv-gids'
const hashData = await axios
.get(hashUrl)
.then(r => {
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}`
const response = await axios.get(versionUrl, {
headers: {
Origin: 'https://www.pickx.be',
Referer: 'https://www.pickx.be/'
}
})
return new Promise((resolve, reject) => {
try {
// https://px-epg.azureedge.net/version is deprecated
// probably the version url will be changed around over time
//history of used version urls
//const versionUrl = 'https://www.pickx.be/api/s-3b36540f3cef64510112f3f95c2c0cdca321997ed2b1042ad778523235e155eb'
//const versionUrl = 'https://www.pickx.be/api/s-671f172425e1bc74cd0440fd67aaa6cbe68b582f3f401186c2f46ae97e80516b'
//const versionUrl = 'https://www.pickx.be/api/s-a6b4b4fefaa20e438523a6167e63b8504d96b9df8303473349763c4418cffe30'
//const versionUrl = 'https://www.pickx.be/api/s-8546c5fd136241d42aab714d2fe3ccc5671fd899035efae07cd0b8f4eb23994e'
//const versionUrl = 'https://www.pickx.be/api/s-64464ad9a3bc117af5dca620027216ecade6a51c230135a0f134c0ee042ff407';
//const versionUrl = 'https://www.pickx.be/api/s-626d8fdabfb1d44e5a614cd69f4b45d6843fdb63566fc80ea4f97f40e4ea3152';
//const versionUrl = 'https://www.pickx.be/api/s-cefaf96e249e53648c4895c279e7a621233c50b4357d62b0bdf6bff45f31b5c0';
//const versionUrl = 'https://www.pickx.be/api/s-7fa35253080e9665f9c7d9d85e707d6fb1d1bf07ede11965e859fcb57c723949';
//const versionUrl = 'https://www.pickx.be/api/s-0e58be3938175b6b900dfb5233bd5cfc0bcf915b633fe57b935f7ce8dbe5f6eb';
//the new strategy to break the provider is to leave old version url's available and to return invalid results on those endpoints
const versionUrl = 'https://www.pickx.be//api/s-600b22979b1e1e1dc91773795eed4a630dea2f9452aa1aab9a2947f4c89b901d';
const response = await axios.get(versionUrl, {
headers: {
Origin: 'https://www.pickx.be',
Referer: 'https://www.pickx.be/'
}
})
if (response.status === 200) {
apiVersion = response.data.version
resolve()
@@ -174,7 +126,7 @@ function fetchApiVersion() {
reject(`Failed to fetch API version. Status: ${response.status}`)
}
} catch (error) {
console.error('Error fetching API version:', error.message)
console.error('Error during fetchApiVersion:', error)
reject(error)
}
})

View File

@@ -1,11 +1,11 @@
// 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/e4f92bb2a2768dcba3dbbd52b19d78d96bebc31e/sites/telenet.tv/telenet.tv.config.js
const axios = require('axios')
const dayjs = require('dayjs')
const API_STATIC_ENDPOINT = 'https://static.spark.telenet.tv/eng/web/epg-service-lite/be'
const API_PROD_ENDPOINT = 'https://spark-prod-be.gnp.cloud.telenet.tv/eng/web/linear-service/v2'
const API_IMAGE_ENDPOINT = 'https://staticqbr-prod-be.gnp.cloud.telenet.tv/image-service';
const API_IMAGE_ENDPOINT = 'https://staticqbr-prod-be.gnp.cloud.telenet.tv/image-service'
module.exports = {
site: 'telenet.tv',
@@ -16,7 +16,7 @@ module.exports = {
}
},
url: function ({ date, channel }) {
return `${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDDHHmmss')}`
return `${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}000000`
},
async parser({ content, channel, date }) {
let programs = []
@@ -24,25 +24,19 @@ module.exports = {
if (!items.length) return programs
const promises = [
axios.get(
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date
.add(6, 'h')
.format('YYYYMMDDHHmmss')}`,
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}060000`,
{
responseType: 'arraybuffer'
}
),
axios.get(
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date
.add(12, 'h')
.format('YYYYMMDDHHmmss')}`,
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}120000`,
{
responseType: 'arraybuffer'
}
),
axios.get(
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date
.add(18, 'h')
.format('YYYYMMDDHHmmss')}`,
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}180000`,
{
responseType: 'arraybuffer'
}
@@ -65,6 +59,7 @@ module.exports = {
const detail = await loadProgramDetails(item, channel)
programs.push({
title: item.title,
subTitle: detail.episodeName,
icon: parseIcon(item),
description: detail.longDescription,
category: detail.genres,
@@ -96,7 +91,7 @@ module.exports = {
async function loadProgramDetails(item, channel) {
if (!item.id) return {}
const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true&language=${channel.lang}`
const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true&language=${channel.lang}`
const data = await axios
.get(url)
.then(r => r.data)
@@ -136,5 +131,5 @@ function parseEpisode(detail) {
}
function parseIcon(item) {
return `${API_IMAGE_ENDPOINT}/intent/${item.id}/posterTile`;
return `${API_IMAGE_ENDPOINT}/intent/${item.id}/posterTile`
}

View File

@@ -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 dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
const fetch = require('node-fetch')
const { upperCase } = require('lodash')
let X_CSRFTOKEN
let COOKIE
let Cookie
const cookiesToExtract = ['JSESSIONID', 'CSESSIONID', 'CSRFSESSION']
const extractedCookies = {}
dayjs.extend(utc)
dayjs.extend(customParseFormat)
@@ -21,10 +18,9 @@ module.exports = {
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList',
request: {
method: 'POST',
headers: function () {
return setHeaders()
async headers() {
return await setHeaders()
},
data({ channel, date }) {
return {
count: -1,
@@ -32,7 +28,8 @@ module.exports = {
offset: 0,
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'
}
],
@@ -43,8 +40,8 @@ module.exports = {
}
}
},
parser: function ({ content }) {
let programs = []
parser({ content }) {
const programs = []
const items = parseItems(content)
items.forEach(item => {
programs.push({
@@ -60,7 +57,7 @@ module.exports = {
directors: parseDirectors(item),
producers: parseProducers(item),
adapters: parseAdapters(item),
country: upperCase(item.country),
country: item.country?.toUpperCase(),
date: item.producedate,
urls: parseUrls(item)
})
@@ -115,15 +112,15 @@ function parseCategory(item) {
}
function parseDirectors(item) {
if (!item.cast || !item.cast.director) return [];
if (!item.cast || !item.cast.director) return []
return item.cast.director
.replace('und', ',')
.split(',')
.map(i => i.trim());
.map(i => i.trim())
}
function parseProducers(item) {
if (!item.cast || !item.cast.producer) return [];
if (!item.cast || !item.cast.producer) return []
return item.cast.producer
.replace('und', ',')
.split(',')
@@ -131,7 +128,7 @@ function parseProducers(item) {
}
function parseAdapters(item) {
if (!item.cast || !item.cast.adaptor) return [];
if (!item.cast || !item.cast.adaptor) return []
return item.cast.adaptor
.replace('und', ',')
.split(',')
@@ -140,7 +137,7 @@ function parseAdapters(item) {
function parseUrls(item) {
// 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)
.filter(externalId => externalId.type === 'imdb' && externalId.id)
.map(externalId => ({ system: 'imdb', value: `https://www.imdb.com/title/${externalId.id}` }))
@@ -167,66 +164,52 @@ function parseItems(content) {
return data.playbilllist
}
// Function to try to fetch COOKIE and X_CSRFTOKEN
function fetchCookieAndToken() {
return fetch(
'https://api.prod.sngtv.magentatv.de/EPG/JSON/Authenticate?SID=firstup&T=Windows_chrome_118',
{
headers: {
accept: 'application/json, text/javascript, */*; q=0.01',
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'x-requested-with': 'XMLHttpRequest',
Referer: 'https://web.magentatv.de/',
'Referrer-Policy': 'strict-origin-when-cross-origin'
async function fetchCookieAndToken() {
// Only fetch the cookies and csrfToken if they are not already set
if (X_CSRFTOKEN && Cookie) {
return
}
try {
const response = await axios.request({
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/Authenticate',
params: {
SID: 'firstup',
T: 'Windows_chrome_118'
},
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'
}
)
.then(response => {
// Check if the response status is OK (2xx)
if (!response.ok) {
throw new Error('HTTP request failed')
}
// Extract the set-cookie header
const setCookieHeader = response.headers.raw()['set-cookie']
// Extract the cookies specified in cookiesToExtract
cookiesToExtract.forEach(cookieName => {
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()
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"}',
})
.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.')
// 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)
}
})
.catch(error => {
console.error(error)
})
// 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 setHeaders() {
return fetchCookieAndToken().then(() => {
return {
X_CSRFTOKEN: X_CSRFTOKEN,
'Content-Type': 'application/json',
Cookie: COOKIE
}
})
async function setHeaders() {
await fetchCookieAndToken()
return { X_CSRFTOKEN, Cookie }
}

23
pm2.config.js Normal file
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
}
]
}

View File

@@ -6,9 +6,10 @@ for arg in "$@"; do
chron-schedule=*) chron_schedule="${arg#*=}" ;;
work-dir=*) work_dir="${arg#*=}" ;;
days=*) days="${arg#*=}" ;;
delay=*) delay="${arg#*=}" ;;
max_connections=*) max_connections="${arg#*=}" ;;
enable_fixes=*) enable_fixes="${arg#*=}" ;;
api_url=*) api_url="${arg#*=}" ;;
api_url=*) api_url="${arg#*=}" ;;
esac
done
@@ -16,6 +17,7 @@ echo "chron_schedule : ${chron_schedule}"
cd $work_dir
echo "working dir : " $(pwd)
echo "days : ${days}"
echo "delay : ${delay}"
echo "max_connections : ${max_connections}"
echo "enable_fixes : ${enable_fixes}"
echo "api url : ${api_url}"
@@ -24,10 +26,7 @@ if [ "$enable_fixes" = true ] ; then
cp -R /fixes/* /bin/epg/sites/
fi
sed -i -E "s/(https:\x2f\x2fiptv-org.github.io\x2fapi)/$api_url/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
sed -i -E "s/(https:\x2f\x2fiptv-org.github.io\x2fapi$\123filename\125)/$api_url$\123filename\125/g" $work_dir/scripts/core/apiClient.ts
ln -s $work_dir/guide.xml /public/guide.xml
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"