Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
1a73bc2b25 | |||
f15b5c36da | |||
ac6aed6aa4 | |||
c0905a30f0 | |||
8555fae94a | |||
a4575ccf18 | |||
abc9f19ac3 | |||
5e40ec15af | |||
aa9ddceb06 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
github: davidclaeysquinones
|
9
LICENSE
Normal file
9
LICENSE
Normal file
@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 David Claeys
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
30
README.md
30
README.md
@ -72,29 +72,35 @@ services:
|
||||
|
||||
This image is bound to the content of the [iptv-org/epg](https://github.com/iptv-org/epg) repository. In the underlying list you can see to which commit each version of the docker image is bound.
|
||||
|
||||
Normally when a change is made in the source repository the documention is updated and a new tag is created in this repository. This is completely normal since the source repository is only cloned during the build process of the docker image.
|
||||
Normally when a change is made in the source repository the documentation is updated and a new tag is created in this repository. This is completely normal since the source repository is only cloned during the build process of the docker image.
|
||||
|
||||
Sometimes a new version of this image will be bound to the same source commit. This will happen when improvements are made to the image.
|
||||
|
||||
- 1.0.0
|
||||
- 1.0.0
|
||||
[08-01-2024](https://github.com/iptv-org/epg/commit/793c74ca397504fc2afc8fbfa998e0b8e4ca45d9)
|
||||
- 1.0.1
|
||||
- 1.0.1
|
||||
[08-14-2024](https://github.com/iptv-org/epg/commit/270e85cfae6f0f691c2e6ab7ce511d60fd687565)
|
||||
- 1.0.2
|
||||
- 1.0.2
|
||||
[09-07-2024](https://github.com/iptv-org/epg/commit/4e3b06a86e225cdd1b9362a683e6770fb68ff28f)
|
||||
- 1.0.3
|
||||
- 1.0.3
|
||||
[09-14-2024](https://github.com/iptv-org/epg/commit/c69f3c93b1123ddf0fecc62c7067fced59ae4e99)
|
||||
- 1.0.4
|
||||
- 1.0.4
|
||||
[09-30-2024](https://github.com/iptv-org/epg/commit/d90c7a54b941238cb92391b33d80a75e746d3002)
|
||||
- 1.0.5
|
||||
- 1.0.5
|
||||
[10-02-2024](https://github.com/iptv-org/epg/commit/713dbf60a1cb9623ffcab6ab370ee9a78b32102b)
|
||||
- 1.0.6
|
||||
- 1.0.6
|
||||
[10-02-2024](https://github.com/iptv-org/epg/commit/713dbf60a1cb9623ffcab6ab370ee9a78b32102b)<br>Adds possibility to enable custom fixes
|
||||
- 1.0.7
|
||||
- 1.0.7
|
||||
[10-02-2024](https://github.com/iptv-org/epg/commit/713dbf60a1cb9623ffcab6ab370ee9a78b32102b)<br>Adds improvement to the docker image size
|
||||
- 1.0.8
|
||||
- 1.0.8
|
||||
[10-10-2024](https://github.com/iptv-org/epg/commit/2241bc261fd37b8b16e036a0b61167030a5ce2e6)
|
||||
- 1.0.9
|
||||
- 1.0.9
|
||||
[10-12-2024](https://github.com/iptv-org/epg/commit/fd382db08da7a96150928b8dcfef115e29e661d3)
|
||||
- 1.0.10
|
||||
[10-14-2024](https://github.com/iptv-org/epg/commit/a3e7661f95103cbee4bcb78bd483396680e9abfc)
|
||||
[10-14-2024 12:50](https://github.com/iptv-org/epg/commit/a3e7661f95103cbee4bcb78bd483396680e9abfc)
|
||||
- 1.0.11
|
||||
[10-14-2024 17:34](https://github.com/iptv-org/epg/commit/7610f7b9f5cc1ccab8d17f3408a95d31b36ace7c)
|
||||
- 1.0.12
|
||||
[10-14-2024](https://github.com/iptv-org/epg/commit/7610f7b9f5cc1ccab8d17f3408a95d31b36ace7c)<br>Fix Pickx.be url
|
||||
- 1.0.13
|
||||
[10-14-2024](https://github.com/iptv-org/epg/commit/7610f7b9f5cc1ccab8d17f3408a95d31b36ace7c)<br>Add custom fix for web.magentatv.de
|
@ -1,3 +1,5 @@
|
||||
// credit for this fix goes to davidclaeysquinones for his PR on https://github.com/iptv-org/epg/pull/2440
|
||||
|
||||
const { DateTime } = require('luxon')
|
||||
|
||||
const API_PROD_ENDPOINT = 'https://www.movistarplus.es/programacion-tv'
|
||||
|
@ -1,3 +1,5 @@
|
||||
// credit for this fix goes to davidclaeysquinones for his PR on https://github.com/iptv-org/epg/pull/2430
|
||||
|
||||
const axios = require('axios')
|
||||
const dayjs = require('dayjs')
|
||||
const utc = require('dayjs/plugin/utc')
|
||||
@ -151,9 +153,10 @@ function fetchApiVersion() {
|
||||
//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-0e58be3938175b6b900dfb5233bd5cfc0bcf915b633fe57b935f7ce8dbe5f6eb';
|
||||
const versionUrl = 'https://www.pickx.be//api/s-600b22979b1e1e1dc91773795eed4a630dea2f9452aa1aab9a2947f4c89b901d';
|
||||
|
||||
|
||||
const response = await axios.get(versionUrl, {
|
||||
|
@ -1,3 +1,5 @@
|
||||
// credit for this fix goes to davidclaeysquinones for his PR on https://github.com/iptv-org/epg/pull/2429
|
||||
|
||||
const axios = require('axios')
|
||||
const dayjs = require('dayjs')
|
||||
|
||||
|
232
fixes/web.magentatv.de/web.magentatv.de.config.js
Normal file
232
fixes/web.magentatv.de/web.magentatv.de.config.js
Normal file
@ -0,0 +1,232 @@
|
||||
// credit for this fix goes to klausellus-wallace for his PR on https://github.com/iptv-org/epg/pull/2458
|
||||
|
||||
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
|
||||
const cookiesToExtract = ['JSESSIONID', 'CSESSIONID', 'CSRFSESSION']
|
||||
const extractedCookies = {}
|
||||
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
module.exports = {
|
||||
site: 'web.magentatv.de',
|
||||
days: 2,
|
||||
url: 'https://api.prod.sngtv.magentatv.de/EPG/JSON/PlayBillList',
|
||||
request: {
|
||||
method: 'POST',
|
||||
headers: function () {
|
||||
return setHeaders()
|
||||
},
|
||||
|
||||
data({ channel, date }) {
|
||||
return {
|
||||
count: -1,
|
||||
isFillProgram: 1,
|
||||
offset: 0,
|
||||
properties: [
|
||||
{
|
||||
include: 'endtime,genres,id,name,starttime,channelid,pictures,introduce,subName,seasonNum,subNum,cast,country,producedate,externalIds',
|
||||
name: 'playbill'
|
||||
}
|
||||
],
|
||||
type: 2,
|
||||
begintime: date.format('YYYYMMDD000000'),
|
||||
channelid: channel.site_id,
|
||||
endtime: date.add(1, 'd').format('YYYYMMDD000000')
|
||||
}
|
||||
}
|
||||
},
|
||||
parser: function ({ content }) {
|
||||
let programs = []
|
||||
const items = parseItems(content)
|
||||
items.forEach(item => {
|
||||
programs.push({
|
||||
title: item.name,
|
||||
description: item.introduce,
|
||||
image: 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: upperCase(item.country),
|
||||
date: item.producedate,
|
||||
urls: parseUrls(item)
|
||||
})
|
||||
})
|
||||
return programs
|
||||
},
|
||||
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
|
||||
.post(url, body, params)
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
|
||||
return data.channellist.map(item => {
|
||||
return {
|
||||
lang: 'de',
|
||||
site_id: item.contentId,
|
||||
name: item.name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function parseCategory(item) {
|
||||
return item.genres
|
||||
? item.genres
|
||||
.replace('und', ',')
|
||||
.split(',')
|
||||
.map(i => i.trim())
|
||||
: []
|
||||
}
|
||||
|
||||
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) {
|
||||
return dayjs.utc(item.starttime, 'YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
function parseStop(item) {
|
||||
return dayjs.utc(item.endtime, 'YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
function parseItems(content) {
|
||||
const data = JSON.parse(content)
|
||||
if (!data || !Array.isArray(data.playbilllist)) return []
|
||||
|
||||
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'
|
||||
},
|
||||
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()
|
||||
})
|
||||
.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() {
|
||||
return fetchCookieAndToken().then(() => {
|
||||
return {
|
||||
X_CSRFTOKEN: X_CSRFTOKEN,
|
||||
'Content-Type': 'application/json',
|
||||
Cookie: COOKIE
|
||||
}
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user