mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 00:50:09 -04:00
Merge pull request #2231 from GenericMale/fix-magentatv.at
Fix magentatv.at
This commit is contained in:
commit
a50649775f
11 changed files with 126 additions and 92 deletions
File diff suppressed because one or more lines are too long
1
sites/magentatv.at/__data__/content_0300.json
Normal file
1
sites/magentatv.at/__data__/content_0300.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
sites/magentatv.at/__data__/content_0900.json
Normal file
1
sites/magentatv.at/__data__/content_0900.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
sites/magentatv.at/__data__/content_1500.json
Normal file
1
sites/magentatv.at/__data__/content_1500.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
sites/magentatv.at/__data__/content_2100.json
Normal file
1
sites/magentatv.at/__data__/content_2100.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
{"imageVersion":"1cjcfg","eventId":"crid:~~2F~~2Fgn.tv~~2F2236391~~2FEP019388320252,imi:af4af994f29354e64878101c0612b17999d0c1a3","channelId":"13TH_STREET_HD","title":"Law & Order: Special Victims Unit","startTime":1667087700,"endTime":1667094000,"mergedId":"184536|de","minimumAge":"16","replayTvMinAge":16,"seriesId":"crid:~~2F~~2Fgn.tv~~2F7896816~~2FSH019388320000","parentSeriesId":"crid:~~2F~~2Fbds.tv~~2F14625541","episodeName":"Mutterinstinkt","seasonNumber":6,"episodeNumber":1,"shortDescription":"Patty Branson wird von einem Jungen in einem Park angegriffen und von diesem verfolgt. Der Junge wurde von Michelle Osborne engagiert, die vorgibt, die leibliche Mutter des Mädchens zu sein. Doch ist dies tatsächlich die Wahrheit?","longDescription":"Patty Branson wird von einem Jungen in einem Park angegriffen und von diesem verfolgt. Der Junge wurde von Michelle Osborne engagiert, die vorgibt, die leibliche Mutter des Mädchens zu sein. Doch ist dies tatsächlich die Wahrheit?","actors":["Christopher Meloni","Mariska Hargitay","Richard Belzer","Dann Florek","Ice-T","BD Wong","Diane Neal","Tamara Tunie","Abigail Breslin","Lea Thompson"],"directors":["Arthur W. Forney"],"producers":["Dick Wolf","Ted Kotcheff","Neal Baer"],"audioLanguages":[{"lang":"de"}],"productionDate":"2004","countryOfOrigin":"US","genres":["Drama-Serie","Krimi Drama","Action","Thriller"],"seriesPremiereAirings":true}
|
||||
{"id":"gn.tv-24101298-EP048489190016","name":"So Help Me Todd","episodes_count":null,"seasons_count":0,"poster_image_url":"https://tv-at-prod.yo-digital.com/prod/images/1422/800/p24101298_e_h8_ae.jpg","is_live":true,"show_type":"TVShow","release_year":2023,"end_year":null,"ratings":"12","is_adult":false,"trailer":[],"details":{"description":"Ava ist 17 und eine geniale Hackerin. Jetzt steht die Teenagerin vor Gericht, weil sie sich illegal Zugang zum Verteidigungsministerium verschafft hat. Todd soll das IT-Genie überwachen.","metadata":[{"name":"Genres","value":"Kriminaldrama","type":"GENRES"}]},"locale":"","last_updated":"1699163343000","seasons":[],"roles":[{"role_name":"Schauspieler","person_id":"74131","person_name":"Marcia Gay Harden","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/74131_v9_bb.jpg"},{"role_name":"Schauspieler","person_id":"517088","person_name":"Skylar Astin","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/517088_v9_bc.jpg"},{"role_name":"Schauspieler","person_id":"1210251","person_name":"Madeline Wise","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/1210251_v9_aa.jpg"},{"role_name":"Schauspieler","person_id":"703443","person_name":"Tristen J. Winger","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/703443_v9_aa.jpg"},{"role_name":"Schauspieler","person_id":"1200248","person_name":"Inga Schlingmann","image_url":null},{"role_name":"Schauspieler","person_id":"230208","person_name":"Rosa Evangelina Arredondo","image_url":null},{"role_name":"Schauspieler","person_id":"37735","person_name":"Laila Robins","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/37735_v9_bc.jpg"},{"role_name":"Produzent","person_id":"290831","person_name":"Scott Prendergast","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/290831_v9_aa.jpg"},{"role_name":"Produzent","person_id":"195655","person_name":"Liz Kruger","image_url":null},{"role_name":"Produzent","person_id":"491285","person_name":"Elizabeth Klaviter","image_url":null},{"role_name":"Produzent","person_id":"287585","person_name":"Dr. Phil McGraw","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/287585_v9_bb.jpg"},{"role_name":"Produzent","person_id":"299674","person_name":"Jay McGraw","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/299674_v9_bb.jpg"},{"role_name":"Produzent","person_id":"497742","person_name":"Julia Eisenman","image_url":null},{"role_name":"Produzent","person_id":"1117587","person_name":"Amy York Rubin","image_url":null},{"role_name":"Drehbuchautor","person_id":"1242913","person_name":"Steven Paul Martinez","image_url":null},{"role_name":"Regisseur","person_id":"530202","person_name":"Jay Karas","image_url":"https://tv-at-prod.yo-digital.com/prod/images/cast/548/728/530202_v9_ba.jpg"}],"cache_ttl":null,"data_source":"CTS"}
|
||||
|
|
|
@ -1,44 +1,38 @@
|
|||
const axios = require('axios')
|
||||
const crypto = require('crypto')
|
||||
const dayjs = require('dayjs')
|
||||
|
||||
const API_STATIC_ENDPOINT = 'https://static.spark.magentatv.at/deu/web/epg-service-lite/at'
|
||||
const API_PROD_ENDPOINT = 'https://prod.spark.magentatv.at/deu/web/linear-service/v2'
|
||||
const API_ENDPOINT = 'https://tv-at-prod.yo-digital.com/at-bifrost'
|
||||
|
||||
const headers = {
|
||||
'Device-Id': crypto.randomUUID(),
|
||||
'app_key': 'CTnKA63ruKM0JM1doxAXwwyQLLmQiEiy',
|
||||
'app_version': '02.0.830',
|
||||
'X-User-Agent': 'web|web|Firefox-120|02.0.830|1',
|
||||
'x-request-tracking-id': crypto.randomUUID()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
site: 'magentatv.at',
|
||||
days: 2,
|
||||
request: {
|
||||
headers,
|
||||
cache: {
|
||||
ttl: 60 * 60 * 1000 // 1 hour
|
||||
}
|
||||
},
|
||||
url: function ({ date }) {
|
||||
return `${API_STATIC_ENDPOINT}/de/events/segments/${date.format('YYYYMMDDHHmmss')}`
|
||||
url: function ({ channel, date }) {
|
||||
return `${API_ENDPOINT}/epg/channel/schedules/v2?station_ids=${channel.site_id}&date=${date.format('YYYY-MM-DD')}&hour_offset=${date.format('H')}&hour_range=3&natco_code=at`
|
||||
},
|
||||
async parser({ content, channel, date }) {
|
||||
let programs = []
|
||||
let items = parseItems(content, channel)
|
||||
if (!content) return programs
|
||||
|
||||
let items = parseItems(JSON.parse(content), channel)
|
||||
if (!items.length) return programs
|
||||
const promises = [
|
||||
axios.get(
|
||||
`${API_STATIC_ENDPOINT}/de/events/segments/${date.add(6, 'h').format('YYYYMMDDHHmmss')}`,
|
||||
{
|
||||
responseType: 'arraybuffer'
|
||||
}
|
||||
),
|
||||
axios.get(
|
||||
`${API_STATIC_ENDPOINT}/de/events/segments/${date.add(12, 'h').format('YYYYMMDDHHmmss')}`,
|
||||
{
|
||||
responseType: 'arraybuffer'
|
||||
}
|
||||
),
|
||||
axios.get(
|
||||
`${API_STATIC_ENDPOINT}/de/events/segments/${date.add(18, 'h').format('YYYYMMDDHHmmss')}`,
|
||||
{
|
||||
responseType: 'arraybuffer'
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
const promises = [3, 6, 9, 12, 15, 18, 21].map(i =>
|
||||
axios.get(`${API_ENDPOINT}/epg/channel/schedules/v2?station_ids=${channel.site_id}&date=${date.format('YYYY-MM-DD')}&hour_offset=${i}&hour_range=3&natco_code=at`, {headers}))
|
||||
|
||||
await Promise.allSettled(promises)
|
||||
.then(results => {
|
||||
|
@ -55,16 +49,16 @@ module.exports = {
|
|||
for (let item of items) {
|
||||
const detail = await loadProgramDetails(item)
|
||||
programs.push({
|
||||
title: item.title,
|
||||
sub_title: detail.episodeName,
|
||||
description: detail.longDescription,
|
||||
date: detail.productionDate,
|
||||
category: detail.genres,
|
||||
actors: detail.actors,
|
||||
directors: detail.directors,
|
||||
producers: detail.producers,
|
||||
season: parseSeason(detail),
|
||||
episode: parseEpisode(detail),
|
||||
title: item.description,
|
||||
description: parseDescription(detail),
|
||||
date: parseDate(item),
|
||||
category: parseCategory(item),
|
||||
icon: detail.poster_image_url,
|
||||
actors: parseRoles(detail, 'Schauspieler'),
|
||||
directors: parseRoles(detail, 'Regisseur'),
|
||||
producers: parseRoles(detail, 'Produzent'),
|
||||
season: parseSeason(item),
|
||||
episode: parseEpisode(item),
|
||||
start: parseStart(item),
|
||||
stop: parseStop(item)
|
||||
})
|
||||
|
@ -74,57 +68,74 @@ module.exports = {
|
|||
},
|
||||
async channels() {
|
||||
const data = await axios
|
||||
.get(`${API_PROD_ENDPOINT}/channels?cityId=65535&language=de&productClass=Orion-DASH`)
|
||||
.get(`${API_ENDPOINT}/epg/channel?natco_code=at`, {headers})
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
|
||||
return data.channels.map(item => {
|
||||
return {
|
||||
lang: 'de',
|
||||
site_id: item.id,
|
||||
name: item.name
|
||||
site_id: item.station_id,
|
||||
name: item.title
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function loadProgramDetails(item) {
|
||||
if (!item.id) return {}
|
||||
const url = `${API_PROD_ENDPOINT}/replayEvent/${item.id}?returnLinearContent=true`
|
||||
if (!item.program_id) return {}
|
||||
const url = `${API_ENDPOINT}/details/series/${item.program_id}?natco_code=at`
|
||||
const data = await axios
|
||||
.get(url)
|
||||
.get(url, {headers})
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
|
||||
return data || {}
|
||||
}
|
||||
|
||||
function parseDate(item) {
|
||||
return item && item.release_year ? item.release_year.toString() : null
|
||||
}
|
||||
|
||||
function parseStart(item) {
|
||||
return dayjs.unix(item.startTime)
|
||||
return dayjs(item.start_time)
|
||||
}
|
||||
|
||||
function parseStop(item) {
|
||||
return dayjs.unix(item.endTime)
|
||||
return dayjs(item.end_time)
|
||||
}
|
||||
|
||||
function parseItems(content, channel) {
|
||||
if (!content) return []
|
||||
const data = JSON.parse(content)
|
||||
if (!data || !Array.isArray(data.entries)) return []
|
||||
const channelData = data.entries.find(e => e.channelId === channel.site_id)
|
||||
function parseItems(data, channel) {
|
||||
if (!data || !data.channels) return []
|
||||
const channelData = data.channels[channel.site_id]
|
||||
if (!channelData) return []
|
||||
|
||||
return Array.isArray(channelData.events) ? channelData.events : []
|
||||
return channelData
|
||||
}
|
||||
|
||||
function parseSeason(detail) {
|
||||
if (!detail.seasonNumber) return null
|
||||
if (String(detail.seasonNumber).length > 2) return null
|
||||
return detail.seasonNumber
|
||||
function parseCategory(item) {
|
||||
if (!item.genres) return null
|
||||
return item.genres.map(genre => genre.id)
|
||||
}
|
||||
|
||||
function parseEpisode(detail) {
|
||||
if (!detail.episodeNumber) return null
|
||||
if (String(detail.episodeNumber).length > 3) return null
|
||||
return detail.episodeNumber
|
||||
function parseSeason(item) {
|
||||
if(item.season_display_number === 'Folgen') return null
|
||||
return item.season_number
|
||||
}
|
||||
|
||||
function parseEpisode(item) {
|
||||
if(item.episode_number) return parseInt(item.episode_number)
|
||||
if(item.season_display_number === 'Folgen') return item.season_number
|
||||
return null
|
||||
}
|
||||
|
||||
function parseDescription(item) {
|
||||
if (!item.details) return null
|
||||
return item.details.description
|
||||
}
|
||||
|
||||
function parseRoles(item, role_name) {
|
||||
if (!item.roles) return null
|
||||
return item.roles
|
||||
.filter(role => role.role_name === role_name)
|
||||
.map(role => role.person_name)
|
||||
}
|
||||
|
|
|
@ -11,41 +11,56 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
|
|||
dayjs.extend(customParseFormat)
|
||||
dayjs.extend(utc)
|
||||
|
||||
const API_STATIC_ENDPOINT = 'https://static.spark.magentatv.at/deu/web/epg-service-lite/at'
|
||||
const API_PROD_ENDPOINT = 'https://prod.spark.magentatv.at/deu/web/linear-service/v2'
|
||||
const API_ENDPOINT = 'https://tv-at-prod.yo-digital.com/at-bifrost'
|
||||
|
||||
jest.mock('axios')
|
||||
|
||||
const date = dayjs.utc('2022-10-30', 'YYYY-MM-DD').startOf('d')
|
||||
const channel = {
|
||||
site_id: '13TH_STREET_HD',
|
||||
site_id: '206969383991',
|
||||
xmltv_id: '13thStreet.de',
|
||||
lang: 'de'
|
||||
}
|
||||
|
||||
it('can generate valid url', () => {
|
||||
expect(url({ date })).toBe(`${API_STATIC_ENDPOINT}/de/events/segments/20221030000000`)
|
||||
expect(url({ date, channel })).toBe(`${API_ENDPOINT}/epg/channel/schedules/v2?station_ids=206969383991&date=2022-10-30&hour_offset=0&hour_range=3&natco_code=at`)
|
||||
})
|
||||
|
||||
it('can parse response', async () => {
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content_0000.json'))
|
||||
|
||||
axios.get.mockImplementation(url => {
|
||||
if (url === `${API_STATIC_ENDPOINT}/de/events/segments/20221030060000`) {
|
||||
if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=0&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_0300.json'))
|
||||
})
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=3&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_0600.json'))
|
||||
})
|
||||
} else if (url === `${API_STATIC_ENDPOINT}/de/events/segments/20221030120000`) {
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=6&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_0900.json'))
|
||||
})
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=9&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_1200.json'))
|
||||
})
|
||||
} else if (url === `${API_STATIC_ENDPOINT}/de/events/segments/20221030180000`) {
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=12&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_1500.json'))
|
||||
})
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=15&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_1800.json'))
|
||||
})
|
||||
} else if (url === `${API_ENDPOINT}/epg/channel/schedules/v2?date=2023-11-15&hour_offset=18&hour_range=3&station_ids=206969383991&natco_code=at`) {
|
||||
return Promise.resolve({
|
||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_2100.json'))
|
||||
})
|
||||
} else if (
|
||||
url ===
|
||||
`${API_PROD_ENDPOINT}/replayEvent/crid:~~2F~~2Fgn.tv~~2F2236391~~2FEP019388320252,imi:af4af994f29354e64878101c0612b17999d0c1a3?returnLinearContent=true`
|
||||
`${API_ENDPOINT}/details/series/gn.tv-24101298-EP048489190016?natco_code=at`
|
||||
) {
|
||||
return Promise.resolve({
|
||||
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program.json')))
|
||||
|
@ -63,30 +78,34 @@ it('can parse response', async () => {
|
|||
})
|
||||
|
||||
expect(results[0]).toMatchObject({
|
||||
start: '2022-10-29T23:55:00.000Z',
|
||||
stop: '2022-10-30T01:40:00.000Z',
|
||||
title: 'Law & Order: Special Victims Unit',
|
||||
sub_title: 'Mutterinstinkt',
|
||||
start: '2023-11-14T23:20:00.000Z',
|
||||
stop: '2023-11-15T00:05:00.000Z',
|
||||
title: 'So Help Me Todd',
|
||||
description:
|
||||
'Patty Branson wird von einem Jungen in einem Park angegriffen und von diesem verfolgt. Der Junge wurde von Michelle Osborne engagiert, die vorgibt, die leibliche Mutter des Mädchens zu sein. Doch ist dies tatsächlich die Wahrheit?',
|
||||
date: '2004',
|
||||
category: ['Drama-Serie', 'Krimi Drama', 'Action', 'Thriller'],
|
||||
'Ava ist 17 und eine geniale Hackerin. Jetzt steht die Teenagerin vor Gericht, weil sie sich illegal Zugang zum Verteidigungsministerium verschafft hat. Todd soll das IT-Genie überwachen.',
|
||||
date: '2023',
|
||||
category: ['Kriminaldrama'],
|
||||
actors: [
|
||||
'Christopher Meloni',
|
||||
'Mariska Hargitay',
|
||||
'Richard Belzer',
|
||||
'Dann Florek',
|
||||
'Ice-T',
|
||||
'BD Wong',
|
||||
'Diane Neal',
|
||||
'Tamara Tunie',
|
||||
'Abigail Breslin',
|
||||
'Lea Thompson'
|
||||
'Marcia Gay Harden',
|
||||
'Skylar Astin',
|
||||
'Madeline Wise',
|
||||
'Tristen J. Winger',
|
||||
'Inga Schlingmann',
|
||||
'Rosa Evangelina Arredondo',
|
||||
'Laila Robins'
|
||||
],
|
||||
directors: ['Arthur W. Forney'],
|
||||
producers: ['Dick Wolf', 'Ted Kotcheff', 'Neal Baer'],
|
||||
season: 6,
|
||||
episode: 1
|
||||
directors: ['Jay Karas'],
|
||||
producers: [
|
||||
'Scott Prendergast',
|
||||
'Liz Kruger',
|
||||
'Elizabeth Klaviter',
|
||||
'Dr. Phil McGraw',
|
||||
'Jay McGraw',
|
||||
'Julia Eisenman',
|
||||
'Amy York Rubin'
|
||||
],
|
||||
season: 1,
|
||||
episode: 15
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue