horizon.tv update
Over the last couple of years, Vodafone Germany have been replacing their Horizon cable TV boxes with GigaTV. They have now turned off the horizon.tv backend. The Slovakian services uses a slightly different URL is still working. I've removed the German channels xml and re-named the Slovakian one. Removed the check for DE/SK endpoint and changed to a single SK endpoint. Format is the same as virginmedia.com so I've added a call to get the programme details, which gives us description / category / season / episode / actors / directors / date. Increased from 2 to 3 days and added a cache as URL doesn't change based on channel. Refreshed channel list. There were a few additional and a few to delete. Mapped most of the missing channels and amend the language codes. There are still a small number of un-mapped channels which I wasn't sure about.
This commit is contained in:
@@ -1,26 +1,28 @@
|
||||
const axios = require('axios')
|
||||
const dayjs = require('dayjs')
|
||||
|
||||
const API_ENDPOINT = `https://legacy-static.oesp.horizon.tv/oesp/v4`
|
||||
const API_ENDPOINT = `https://legacy-static.oesp.horizon.tv/oesp/v4/SK/slk/web`
|
||||
|
||||
module.exports = {
|
||||
site: 'horizon.tv',
|
||||
days: 2,
|
||||
url: function ({ date, channel }) {
|
||||
const [country, lang] = channel.site_id.split('#')
|
||||
|
||||
return `${API_ENDPOINT}/${country}/${lang}/web/programschedules/${date.format('YYYYMMDD')}/1`
|
||||
days: 3,
|
||||
request: {
|
||||
cache: {
|
||||
ttl: 60 * 60 * 1000 // 1 hour
|
||||
}
|
||||
},
|
||||
url: function ({ date }) {
|
||||
return `${API_ENDPOINT}/programschedules/${date.format('YYYYMMDD')}/1`
|
||||
},
|
||||
async parser({ content, channel, date }) {
|
||||
const [country, lang] = channel.site_id.split('#')
|
||||
let programs = []
|
||||
let items = parseItems(content, channel)
|
||||
if (!items.length) return programs
|
||||
const d = date.format('YYYYMMDD')
|
||||
const promises = [
|
||||
axios.get(`${API_ENDPOINT}/${country}/${lang}/web/programschedules/${d}/2`),
|
||||
axios.get(`${API_ENDPOINT}/${country}/${lang}/web/programschedules/${d}/3`),
|
||||
axios.get(`${API_ENDPOINT}/${country}/${lang}/web/programschedules/${d}/4`)
|
||||
axios.get(`${API_ENDPOINT}/programschedules/${d}/2`),
|
||||
axios.get(`${API_ENDPOINT}/programschedules/${d}/3`),
|
||||
axios.get(`${API_ENDPOINT}/programschedules/${d}/4`)
|
||||
]
|
||||
await Promise.allSettled(promises)
|
||||
.then(results => {
|
||||
@@ -31,33 +33,50 @@ module.exports = {
|
||||
})
|
||||
})
|
||||
.catch(console.error)
|
||||
items.forEach(item => {
|
||||
for (let item of items) {
|
||||
const detail = await loadProgramDetails(item)
|
||||
programs.push({
|
||||
title: item.t,
|
||||
description: parseDescription(detail),
|
||||
category: parseCategory(detail),
|
||||
season: parseSeason(detail),
|
||||
episode: parseEpisode(detail),
|
||||
actors: parseActors(detail),
|
||||
directors: parseDirectors(detail),
|
||||
date: parseYear(detail),
|
||||
start: parseStart(item),
|
||||
stop: parseStop(item)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return programs
|
||||
},
|
||||
async channels({ country, lang }) {
|
||||
const langs = { deu: 'de', slk: 'sk' }
|
||||
async channels() {
|
||||
const data = await axios
|
||||
.get(`https://legacy-dynamic.oesp.horizon.tv/oesp/v4/${country}/${lang}/web/channels`)
|
||||
.get(`${API_ENDPOINT}/channels`)
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
|
||||
return data.channels.map(item => {
|
||||
return {
|
||||
lang: langs[lang],
|
||||
site_id: `${country}#${lang}#${item.stationSchedules[0].station.id}`,
|
||||
lang: 'sk',
|
||||
site_id: item.id.replace('lgi-obolite-sk-prod-master:5-', ''),
|
||||
name: item.title
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function loadProgramDetails(item) {
|
||||
if (!item.i) return {}
|
||||
const url = `${API_ENDPOINT}/listings/${item.i}`
|
||||
const data = await axios
|
||||
.get(url)
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
return data || {}
|
||||
}
|
||||
|
||||
function parseStart(item) {
|
||||
return dayjs(item.s)
|
||||
}
|
||||
@@ -67,10 +86,60 @@ function parseStop(item) {
|
||||
}
|
||||
|
||||
function parseItems(content, channel) {
|
||||
const [_, __, channelId] = channel.site_id.split('#')
|
||||
const data = typeof content === 'string' ? JSON.parse(content) : content
|
||||
if (!content) return []
|
||||
const data = (typeof content === 'string') ? JSON.parse(content) : content
|
||||
if (!data || !Array.isArray(data.entries)) return []
|
||||
const entity = data.entries.find(e => e.o === channelId)
|
||||
|
||||
const entity = data.entries.find(e => e.o === `lgi-obolite-sk-prod-master:${channel.site_id}`)
|
||||
return entity ? entity.l : []
|
||||
}
|
||||
|
||||
function parseDescription(detail) {
|
||||
if (!detail) return []
|
||||
if (!detail.program) return []
|
||||
return detail.program.longDescription || null
|
||||
}
|
||||
|
||||
function parseCategory(detail) {
|
||||
if (!detail) return []
|
||||
if (!detail.program) return []
|
||||
if (!detail.program.categories) return []
|
||||
let categories = []
|
||||
detail.program.categories.forEach(category => {
|
||||
categories.push(category.title)
|
||||
})
|
||||
return categories
|
||||
}
|
||||
|
||||
function parseSeason(detail) {
|
||||
if (!detail) return null
|
||||
if (!detail.program) return null
|
||||
if (!detail.program.seriesNumber) return null
|
||||
if (String(detail.program.seriesNumber).length > 2) return null
|
||||
return detail.program.seriesNumber
|
||||
}
|
||||
|
||||
function parseEpisode(detail) {
|
||||
if (!detail) return null
|
||||
if (!detail.program) return null
|
||||
if (!detail.program.seriesEpisodeNumber) return null
|
||||
if (String(detail.program.seriesEpisodeNumber).length > 3) return null
|
||||
return detail.program.seriesEpisodeNumber
|
||||
}
|
||||
|
||||
function parseDirectors(detail) {
|
||||
if (!detail) return []
|
||||
if (!detail.program) return []
|
||||
return detail.program.directors || []
|
||||
}
|
||||
|
||||
function parseActors(detail) {
|
||||
if (!detail) return []
|
||||
if (!detail.program) return []
|
||||
return detail.program.cast || []
|
||||
}
|
||||
|
||||
function parseYear(detail) {
|
||||
if (!detail) return null
|
||||
if (!detail.program) return null
|
||||
return detail.program.year || null
|
||||
}
|
||||
Reference in New Issue
Block a user