update custom fixes to latest code
This commit is contained in:
1 parent
3876463747
commit
bcfd38cb19
3 files changed
+277
-206
No files matched your search
@@ -1,19 +1,18 @@
|
|||||||
//https://github.com/iptv-org/epg/blob/master/sites/movistarplus.es/movistarplus.es.config.js
|
//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 utc = require('dayjs/plugin/utc')
|
|
||||||
const timezone = require('dayjs/plugin/timezone')
|
const timezone = require('dayjs/plugin/timezone')
|
||||||
|
const utc = require('dayjs/plugin/utc')
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
dayjs.extend(timezone)
|
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('YYYY-MM-DD')}`
|
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`
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -25,122 +24,97 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
maxRedirects: 5
|
maxRedirects: 5
|
||||||
},
|
},
|
||||||
async parser({ content, date }) {
|
async parser({ content }) {
|
||||||
let programs = []
|
let programs = []
|
||||||
const $ = cheerio.load(content)
|
let items = await parseItems(content)
|
||||||
|
if (!items.length) return programs
|
||||||
const programDivs = $('div[id^="ele-"]').toArray()
|
|
||||||
|
|
||||||
for (let i = 0; i < programDivs.length; i++) {
|
|
||||||
const el = $(programDivs[i])
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
items.forEach(el => {
|
||||||
programs.push({
|
programs.push({
|
||||||
title,
|
title: el.title,
|
||||||
description,
|
description: el.description,
|
||||||
start: startDate,
|
icon: el.icon,
|
||||||
stop: endDate
|
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(
|
||||||
headers: {
|
'https://ottcache.dof6.com/movistarplus/webplayer/OTT/contents/channels?mdrm=true&tlsstream=true&demarcation=18&version=8'
|
||||||
'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)
|
.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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getProgramDescription(programUrl) {
|
function parseImages(images) {
|
||||||
const response = await axios.get(programUrl, {
|
return images.filter(image => image.id === 'watch2tgr-end').map(image => image.uri)
|
||||||
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',
|
async function parseItems(content) {
|
||||||
Referer: 'https://www.movistarplus.es/programacion-tv/'
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
)
|
||||||
const $ = cheerio.load(response.data)
|
} catch {
|
||||||
const description = $('.show-content .text p').first().text().trim() || null
|
return []
|
||||||
|
}
|
||||||
return description
|
|
||||||
}
|
}
|
||||||
@@ -9,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',
|
||||||
@@ -25,20 +27,31 @@ module.exports = {
|
|||||||
'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'
|
'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 }) {
|
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 {
|
||||||
@@ -75,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))
|
||||||
@@ -94,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)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,135 +1,215 @@
|
|||||||
//https://github.com/iptv-org/epg/blob/e4f92bb2a2768dcba3dbbd52b19d78d96bebc31e/sites/telenet.tv/telenet.tv.config.js
|
//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()
|
||||||
|
},
|
||||||
|
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')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
url: function ({ date, channel }) {
|
parser({ content }) {
|
||||||
return `${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}000000`
|
const programs = []
|
||||||
},
|
const items = parseItems(content)
|
||||||
async parser({ content, channel, date }) {
|
items.forEach(item => {
|
||||||
let programs = []
|
|
||||||
let items = parseItems(content, channel)
|
|
||||||
if (!items.length) return programs
|
|
||||||
const promises = [
|
|
||||||
axios.get(
|
|
||||||
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}060000`,
|
|
||||||
{
|
|
||||||
responseType: 'arraybuffer'
|
|
||||||
}
|
|
||||||
),
|
|
||||||
axios.get(
|
|
||||||
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}120000`,
|
|
||||||
{
|
|
||||||
responseType: 'arraybuffer'
|
|
||||||
}
|
|
||||||
),
|
|
||||||
axios.get(
|
|
||||||
`${API_STATIC_ENDPOINT}/${channel.lang}/events/segments/${date.format('YYYYMMDD')}180000`,
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(console.error)
|
|
||||||
|
|
||||||
for (let item of items) {
|
|
||||||
const detail = await loadProgramDetails(item, channel)
|
|
||||||
programs.push({
|
programs.push({
|
||||||
title: item.title,
|
title: item.name,
|
||||||
subTitle: detail.episodeName,
|
description: item.introduce,
|
||||||
icon: parseIcon(item),
|
image: parseImage(item),
|
||||||
description: detail.longDescription,
|
icon: parseImage(item),
|
||||||
category: detail.genres,
|
category: parseCategory(item),
|
||||||
actors: detail.actors,
|
|
||||||
season: parseSeason(detail),
|
|
||||||
episode: parseEpisode(detail),
|
|
||||||
start: parseStart(item),
|
start: parseStart(item),
|
||||||
stop: parseStop(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`
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user