Update orangetv.orange.es guide.
Test: ```sh npm test --- orangetv.orange.es > test > run-script-os orangetv.orange.es > test:win32 > SET "TZ=Pacific/Nauru" && npx jest --runInBand orangetv.orange.es PASS sites/orangetv.orange.es/orangetv.orange.es.test.js √ can generate valid url (6 ms) √ can parse response (6 ms) √ can handle empty guide (1 ms) Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 0 total Time: 0.701 s, estimated 1 s Ran all test suites matching /orangetv.orange.es/i. ``` Grab: ```sh pm run grab --- --site=orangetv.orange.es > grab > npx tsx scripts/commands/epg/grab.ts --site=orangetv.orange.es starting... config: output: guide.xml maxConnections: 1 gzip: false site: orangetv.orange.es loading channels... found 2 channel(s) run #1: [1/2] orangetv.orange.es (es) - La1.es - Jan 12, 2025 (18 programs) [2/2] orangetv.orange.es (es) - La2.es - Jan 12, 2025 (39 programs) saving to "guide.xml"... done in 00h 00m 18s ``` Signed-off-by: Toha <tohenk@yahoo.com>
This commit is contained in:
7 files changed
+103
-77
No files matched your search
@@ -1 +0,0 @@
|
|||||||
[{"responseElementType": "ProgramList", "channelExternalId": "1010", "programs": [{"startDate": 1733006211000, "endDate": 1733011045000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3425215.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780631624", "prLevel": 5, "id": 14994906154, "description": "Charlie trabaja como director en una escuela de primaria y goza de una placentera existencia junto a sus amigos. A pesar de ello, no es feliz porque cada vez que se enamora pierde la cordura.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Romance", "name": "Romance", "id": 862337287}, {"externalId": "Comedia", "name": "Comedia", "id": 862331198}, {"externalId": "Comedia Romántica", "name": "Comedia Romántica", "id": 1384659250}], "name": "Loco de amor", "flags": 14}, {"startDate": 1733011045000, "endDate": 1733016000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3104917.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780624399", "prLevel": 1, "id": 14993172967, "description": "Cuando Roman Hilbert sube a bordo, inmediatamente nota el parecido entre la profesora de baile Jana Stern y su difunta esposa. Él la invita a venir a su hotel en Mauricio.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Drama", "name": "Drama", "id": 862336010}], "name": "El crucero de los sueños: Mauricio", "flags": 14}, {"startDate": 1733016000000, "endDate": 1733029200000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3108557.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780596261", "prLevel": 1, "id": 14986009612, "description": "Noticias de los servicios informativos del Canal 24 Horas. Producido por Televisión Española, este canal está dedicado íntegramente a ofrecer información de actualidad y es el más antiguo de los canales de este tipo en España.", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Noticias 24H", "flags": 14}, {"startDate": 1733029200000, "endDate": 1733043600000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3108557.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780596259", "prLevel": 1, "id": 14986009972, "description": "Noticias de los servicios informativos del Canal 24 Horas. Producido por Televisión Española, este canal está dedicado íntegramente a ofrecer información de actualidad y es el más antiguo de los canales de este tipo en España.", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Noticias 24H", "flags": 14}]}, {"responseElementType": "ProgramList", "channelExternalId": "1062", "programs": [{"startDate": 1733004195000, "endDate": 1733010789000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3421718.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780625167", "prLevel": 7, "id": 14993123812, "description": "Una periodista de Teherán se sumerge en los barrios con peor reputación de Mashhad para investigar unos feminicidios llevados a cabo por un hombre, quien asegura purificar la ciudad de sus pecados.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Suspense", "name": "Suspense", "id": 862337524}], "name": "Araña sagrada", "flags": 14}, {"startDate": 1733010789000, "endDate": 1733015580000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3425285.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780631844", "prLevel": 1, "id": 14994852532, "description": "TikTok es una plataforma cada vez más potente, acusada como otras redes sociales de recopilar nuestros datos personales. Con una diferencia: es sospechosa de transmitirlos al régimen chino e influir en la opinión pública de todo el mundo.", "seriesName": "", "genres": [{"externalId": "Documental", "name": "Documental", "id": 30089199}, {"externalId": "Científico", "name": "Científico", "id": 9199024681}], "name": "Tik Tok, la sombra china", "flags": 14}, {"startDate": 1733015580000, "endDate": 1733019000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3425292.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780631845", "prLevel": 5, "id": 14994853036, "description": "La tecnología de vanguardia 'hackea' las emociones provocando, a medio plazo, un vacío existencial. Individuos y empresas se lucran secuestrando las emociones y sentimientos de los usuarios.", "seriesName": "", "genres": [{"externalId": "Documental", "name": "Documental", "id": 30089199}, {"externalId": "Científico", "name": "Científico", "id": 9199024681}], "name": "Ya no siento nada", "flags": 14}, {Line truncated
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[{"responseElementType": "ProgramList", "channelExternalId": "1010", "programs": [{"startDate": 1736636100000, "endDate": 1736642400000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_2247567.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780906206", "prLevel": 7, "id": 15071377885, "description": "Cassie tenía un brillante futuro por delante. Sin embargo, un incidente provocó que no pudiese cumplir sus sueños. Con el paso del tiempo, tendrá la oportunidad de enmendar los errores del pasado.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Drama", "name": "Drama", "id": 862336010}, {"externalId": "Suspense", "name": "Suspense", "id": 862337524}], "name": "Una joven prometedora", "flags": 14}, {"startDate": 1736642400000, "endDate": 1736648100000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3522912.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780916568", "prLevel": 1, "id": 15073959700, "description": "César deambula por las calles de Montmarte en París, donde interpreta su música. Un día, se encuentra con Salomé, a quien dejó sin decir palabra un tiempo atrás, y descubre que es padre de una niña.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Comedia", "name": "Comedia", "id": 862331198}], "name": "Una comedia romántica", "flags": 14}, {"startDate": 1736648100000, "endDate": 1736658000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3108557.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780871990", "prLevel": 1, "id": 15058341721, "description": "Noticias de los servicios informativos del Canal 24 Horas", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Noticias 24H", "flags": 14}, {"startDate": 1736658000000, "endDate": 1736674500000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3108557.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780871999", "prLevel": 1, "id": 15058342585, "description": "Noticias de los servicios informativos del Canal 24 Horas", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Noticias 24H", "flags": 14}]}]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[{"responseElementType": "ProgramList", "channelExternalId": "1010", "programs": [{"startDate": 1736658000000, "endDate": 1736674500000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3108557.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780871999", "prLevel": 1, "id": 15058342585, "description": "Noticias de los servicios informativos del Canal 24 Horas", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Noticias 24H", "flags": 14}, {"startDate": 1736674500000, "endDate": 1736676600000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_469238.jpg"}], "seriesSeason": "8", "episodeId": "12", "referenceProgramId": "780872016", "prLevel": 1, "id": 15058342081, "description": "Magacín de salud semanal con la periodista Miriam Moreno con vocación de servicio público. En cada edición ofrece a los espectadores los mejores consejos y cambios en la rutina que pueden servir para llevar una vida más saludable.", "seriesName": "Saber vivir", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Salud", "name": "Salud", "id": 862341634}], "name": "Saber vivir - T8, E12: Saber vivir", "flags": 15}, {"startDate": 1736676600000, "endDate": 1736679900000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3261229.jpg"}], "seriesSeason": "17", "episodeId": "8", "referenceProgramId": "780916571", "prLevel": 4, "id": 15073959340, "description": "El programa viaja hasta Bulgaria para conocer su capital Sofía, una de las ciudades más antiguas de Europa y también de las más desconocidas. El espacio de viajes de La 1 también llegará hasta la ciudad medieval de Veliko Tarnovo y Varna.", "seriesName": "Españoles en el mundo", "genres": [{"externalId": "Documental", "name": "Documental", "id": 30089199}, {"externalId": "Viajes y aventuras", "name": "Viajes y aventuras", "id": 9198977905}], "name": "Españoles en el mundo - T17, E08: Sofia, Bulgaria", "flags": 15}, {"startDate": 1736679900000, "endDate": 1736683200000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3261229.jpg"}], "seriesSeason": "16", "episodeId": "9", "referenceProgramId": "780872010", "prLevel": 4, "id": 15058342225, "description": "El programa cruza el charco para trasladarse a Washington D.C., donde de la mano de seis personas españolas, se descubren lugares como la Casa Blanca, el Capitolio, el Museo de Historia Natural o el Memorial de los Veteranos de Vietnam.", "seriesName": "Españoles en el mundo", "genres": [{"externalId": "Documental", "name": "Documental", "id": 30089199}, {"externalId": "Viajes y aventuras", "name": "Viajes y aventuras", "id": 9198977905}], "name": "Españoles en el mundo - T16, E09: Washington, Distrito Columbia", "flags": 15}, {"startDate": 1736683200000, "endDate": 1736686500000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3256949.jpg"}], "seriesSeason": "12", "episodeId": "4", "referenceProgramId": "780872014", "prLevel": 4, "id": 15058342441, "description": "Cruzamos el Estrecho de Gibraltar para conocer la huella española en los dominios del antiguo Protectorado en Marruecos.", "seriesName": "Españoles en el mundo", "genres": [{"externalId": "Documental", "name": "Documental", "id": 30089199}, {"externalId": "Viajes y aventuras", "name": "Viajes y aventuras", "id": 9198977905}], "name": "Españoles en el mundo - T12, E04: Tánger, Tetuán y Chauen", "flags": 15}, {"startDate": 1736686500000, "endDate": 1736690400000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_415745.jpg"}], "seriesSeason": "2", "episodeId": "4", "referenceProgramId": "780872015", "prLevel": 1, "id": 15058341793, "description": "Anne Igartiburu y Jordi González hacen un repaso a la actualidad de la crónica social, con los nombres propios más importantes de la semana y estando en directo en todos los acontecimientos y eventos que se produzcan.", "seriesName": "D Corazón", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Prensa rosa", "name": "Prensa rosa", "id": 11611838587}], "name": "D Corazón - T2, E04: D Corazón", "flags": 15}, {"startDate": 1736690400000, "endDate": 1736694000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_663318.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780872012", "prLevel": 1, "id": 15058342729, "description": "Informativo de Televisión Española de los fines de semana. Lara Siscar e Igor Gómez se encargan de presentar las últimas noticias de ámbito nacional e internacional surgidas durante el día", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Telediario 1 Fin de Semana", "flags": 14}]}]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[{"responseElementType": "ProgramList", "channelExternalId": "1010", "programs": [{"startDate": 1736690400000, "endDate": 1736694000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_663318.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780872012", "prLevel": 1, "id": 15058342729, "description": "Informativo de Televisión Española de los fines de semana. Lara Siscar e Igor Gómez se encargan de presentar las últimas noticias de ámbito nacional e internacional surgidas durante el día", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Telediario 1 Fin de Semana", "flags": 14}, {"startDate": 1736694000000, "endDate": 1736699700000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_438081.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780916569", "prLevel": 4, "id": 15073960132, "description": "Aparentemente, Ollie Trinke lo tiene todo. Pero cuando su mujer fallece, Ollie se va a vivir con su padre a Nueva Jersey. Un día, en el videoclub, conoce a una joven que rompe todos sus esquemas.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Comedia", "name": "Comedia", "id": 862331198}, {"externalId": "Comedia Romántica", "name": "Comedia Romántica", "id": 1384659250}, {"externalId": "Drama", "name": "Drama", "id": 862336010}], "name": "Una chica de Jersey", "flags": 14}, {"startDate": 1736699700000, "endDate": 1736705100000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_2306072.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780916570", "prLevel": 6, "id": 15073959556, "description": "Diane, abogada brillante, pierde su móvil y recibe una llamada de la persona que lo ha encontrado. Resulta ser el hombre perfecto, salvo por un pequeño problema: mide 1,36 metros.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Aventuras", "name": "Aventuras", "id": 1690076911}, {"externalId": "Comedia", "name": "Comedia", "id": 862331198}, {"externalId": "Romance", "name": "Romance", "id": 862337287}], "name": "Un hombre de altura", "flags": 14}, {"startDate": 1736705100000, "endDate": 1736710500000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_662983.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780916572", "prLevel": 1, "id": 15073960855, "description": "Ella Morgan y su prometido, Jacob, iban hacerse cargo de la plantación de té familiar, pero cuando Jacob muere en un accidente de escalada, Ella se desentiende del negocio. Dos años después, en una visita a sus padres descubre que su padre Mortimer quiere arrendar la plantación, pero su madre, Jane, ha contratado a un experto en marketing, Finn Huxley, para que les ayude a incrementar las ventas y poner a si fin a la crisis que atraviesa la plantación. A petición de su madre Ella decide quedarse unos días y poco a poco acaba enamorándose de Finn.", "seriesName": "", "genres": [{"externalId": "Cine", "name": "Cine", "id": 128839623}, {"externalId": "Drama", "name": "Drama", "id": 862336010}], "name": "Té y amor", "flags": 14}, {"startDate": 1736710500000, "endDate": 1736712000000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_2246597.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780872001", "prLevel": 1, "id": 15058342009, "description": "Jacob Petrus ofrece una original mirada sobre el territorio y sus habitantes a través de la meteorología. La divulgación y la información sobre el terreno conviven con el descubrimiento de la naturaleza y el medio ambiente.", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Entretenimiento", "name": "Entretenimiento", "id": 862338574}], "name": "Aquí la Tierra", "flags": 14}, {"startDate": 1736712000000, "endDate": 1736715900000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_663318.jpg"}], "seriesSeason": "", "episodeId": "", "referenceProgramId": "780872003", "prLevel": 1, "id": 15058342297, "description": "Informativo de Televisión Española de los fines de semana. Lara Siscar e Igor Gómez se encargan de presentar las últimas noticias de ámbito nacional e internacional surgidas durante el día", "seriesName": "", "genres": [{"externalId": "Programa", "name": "Programa", "id": 9169074970}, {"externalId": "Informativo", "name": "Informativo", "id": 862353792}], "name": "Telediario 2 Fin de Semana", "flags": 14}, {"startDate": 1736715900000, "endDate": 1736723100000, "attachments": [{"name": "COVER", "value": "/epg/COVER/COVER_3520028.jpg"}], "seriesSeason": "2", "episodeId": "1", "referenceProgramId": "780906207", "prLevel": 1, "id": 15071379397, "description": "Nervios y emoción en el debut de los 14 pasteleros de la nueva temporada dLine truncated
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
const dayjs = require('dayjs')
|
const dayjs = require('dayjs')
|
||||||
const utc = require('dayjs/plugin/utc')
|
const utc = require('dayjs/plugin/utc')
|
||||||
const axios = require('axios')
|
const doFetch = require('@ntlab/sfetch')
|
||||||
|
const debug = require('debug')('site:orangetv.orange.es')
|
||||||
|
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
|
|
||||||
|
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/Smartphone_Android/1_PRO'
|
||||||
const API_CHANNEL_ENDPOINT =
|
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'
|
'https://pc.orangetv.orange.es/pc/api/rtv/v1/GetChannelList?bouquet_id=1&model_external_id=PC&filter_unsupported_channels=false&client=json'
|
||||||
@@ -14,49 +17,39 @@ module.exports = {
|
|||||||
days: 2,
|
days: 2,
|
||||||
request: {
|
request: {
|
||||||
cache: {
|
cache: {
|
||||||
ttl: 60 * 60 * 1000 // 1 hour
|
ttl: 24 * 60 * 60 * 1000 // 1 day
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
url({ date }) {
|
url({ date, segment = 1 }) {
|
||||||
return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`
|
return `${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_${segment}.json`
|
||||||
},
|
},
|
||||||
async parser({ content, channel, date }) {
|
async parser({ content, channel, date }) {
|
||||||
let programs = []
|
const programs = []
|
||||||
let items = parseItems(content, channel)
|
const items = parseItems(content, channel)
|
||||||
if (!items.length) return programs
|
if (items.length) {
|
||||||
|
const queues = [
|
||||||
const promises = [
|
module.exports.url({ date, segment: 2 }),
|
||||||
axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_1.json`),
|
module.exports.url({ date, segment: 3 })
|
||||||
axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_2.json`),
|
]
|
||||||
axios.get(`${API_PROGRAM_ENDPOINT}/${date.format('YYYYMMDD')}_8h_3.json`)
|
await doFetch(queues, (url, res) => {
|
||||||
]
|
items.push(...parseItems(res, channel))
|
||||||
|
})
|
||||||
await Promise.allSettled(promises)
|
programs.push(
|
||||||
.then(results => {
|
...items.map(item => {
|
||||||
results.forEach(r => {
|
return {
|
||||||
if (r.status === 'fulfilled') {
|
title: item.name,
|
||||||
const parsed = parseItems(r.value.data, channel)
|
sub_title: item.seriesName,
|
||||||
|
description: item.description,
|
||||||
items = items
|
category: parseGenres(item),
|
||||||
.filter((item, index) => items.findIndex(oi => oi.id === item.id) === index)
|
season: item.seriesSeason ? parseInt(item.seriesSeason) : null,
|
||||||
.concat(parsed)
|
episode: item.episodeId ? parseInt(item.episodeId) : null,
|
||||||
|
icon: parseIcon(item),
|
||||||
|
start: dayjs.utc(item.startDate),
|
||||||
|
stop: dayjs.utc(item.endDate)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
)
|
||||||
.catch(console.error)
|
}
|
||||||
|
|
||||||
items.forEach(item => {
|
|
||||||
programs.push({
|
|
||||||
title: item.name,
|
|
||||||
description: item.description,
|
|
||||||
category: parseGenres(item),
|
|
||||||
season: item.seriesSeason || null,
|
|
||||||
episode: item.episodeId || null,
|
|
||||||
icon: parseIcon(item),
|
|
||||||
start: dayjs.utc(item.startDate) || null,
|
|
||||||
stop: dayjs.utc(item.endDate) || null
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return programs
|
return programs
|
||||||
},
|
},
|
||||||
@@ -65,7 +58,8 @@ module.exports = {
|
|||||||
const data = await axios
|
const data = await axios
|
||||||
.get(API_CHANNEL_ENDPOINT)
|
.get(API_CHANNEL_ENDPOINT)
|
||||||
.then(r => r.data)
|
.then(r => r.data)
|
||||||
.catch(console.log)
|
.catch(console.error)
|
||||||
|
|
||||||
return data.response.map(item => {
|
return data.response.map(item => {
|
||||||
return {
|
return {
|
||||||
lang: 'es',
|
lang: 'es',
|
||||||
@@ -77,15 +71,12 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseIcon(item) {
|
function parseIcon(item) {
|
||||||
if (item.attachments.length > 0) {
|
if (item.attachments.length) {
|
||||||
const cover = item.attachments.find(i => i.name === 'COVER' || i.name === 'cover')
|
const cover = item.attachments.find(i => i.name.match(/cover/i))
|
||||||
|
|
||||||
if (cover) {
|
if (cover) {
|
||||||
return `${API_IMAGE_ENDPOINT}${cover.value}`
|
return `${API_IMAGE_ENDPOINT}${cover.value}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseGenres(item) {
|
function parseGenres(item) {
|
||||||
@@ -93,16 +84,16 @@ function parseGenres(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseItems(content, channel) {
|
function parseItems(content, channel) {
|
||||||
|
const result = []
|
||||||
const json =
|
const json =
|
||||||
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
|
||||||
return []
|
.filter(i => i.channelExternalId === channel.site_id)
|
||||||
|
.forEach(i => {
|
||||||
|
result.push(...i.programs)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const channelData = json.find(i => i.channelExternalId == channel.site_id)
|
return result
|
||||||
|
|
||||||
if (!channelData) return []
|
|
||||||
|
|
||||||
return channelData.programs
|
|
||||||
}
|
}
|
||||||
@@ -1,51 +1,82 @@
|
|||||||
const { parser, url } = require('./orangetv.orange.es.config.js')
|
const { parser, url } = require('./orangetv.orange.es.config.js')
|
||||||
|
const path = require('path')
|
||||||
|
const fs = require('fs')
|
||||||
|
const axios = require('axios')
|
||||||
const dayjs = require('dayjs')
|
const dayjs = require('dayjs')
|
||||||
const utc = require('dayjs/plugin/utc')
|
const utc = require('dayjs/plugin/utc')
|
||||||
const customParseFormat = require('dayjs/plugin/customParseFormat')
|
const customParseFormat = require('dayjs/plugin/customParseFormat')
|
||||||
|
|
||||||
dayjs.extend(customParseFormat)
|
dayjs.extend(customParseFormat)
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
const path = require('path')
|
|
||||||
const fs = require('fs')
|
|
||||||
|
|
||||||
const date = dayjs.utc('2024-12-01', 'YYYY-MM-DD').startOf('d')
|
jest.mock('axios')
|
||||||
|
|
||||||
|
const date = dayjs.utc('2025-01-12', 'YYYY-MM-DD').startOf('d')
|
||||||
const channel = {
|
const channel = {
|
||||||
site_id: '1010',
|
site_id: '1010',
|
||||||
xmltv_id: 'La1.es'
|
xmltv_id: 'La1.es'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
axios.get.mockImplementation(url => {
|
||||||
|
const result = {}
|
||||||
|
const urls = {
|
||||||
|
'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/20250112_8h_1.json':
|
||||||
|
'data1.json',
|
||||||
|
'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/20250112_8h_2.json':
|
||||||
|
'data2.json',
|
||||||
|
'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/20250112_8h_3.json':
|
||||||
|
'data3.json',
|
||||||
|
}
|
||||||
|
if (urls[url] !== undefined) {
|
||||||
|
result.data = fs.readFileSync(path.join(__dirname, '__data__', urls[url])).toString()
|
||||||
|
if (!urls[url].startsWith('data1')) {
|
||||||
|
result.data = JSON.parse(result.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(result)
|
||||||
|
})
|
||||||
|
|
||||||
it('can generate valid url', () => {
|
it('can generate valid url', () => {
|
||||||
expect(url({ date })).toBe(
|
expect(url({ date })).toBe(
|
||||||
`https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/${date.format(
|
'https://epg.orangetv.orange.es/epg/Smartphone_Android/1_PRO/20250112_8h_1.json'
|
||||||
'YYYYMMDD'
|
|
||||||
)}_8h_1.json`
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can parse response', async () => {
|
it('can parse response', async () => {
|
||||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/data.json')).toString()
|
const content = fs.readFileSync(path.join(__dirname, '__data__', 'data1.json')).toString()
|
||||||
let results = await parser({ content, channel, date })
|
const results = (await parser({ content, channel, date })).map(p => {
|
||||||
results = results.map(p => {
|
|
||||||
p.start = p.start.toJSON()
|
p.start = p.start.toJSON()
|
||||||
p.stop = p.stop.toJSON()
|
p.stop = p.stop.toJSON()
|
||||||
return p
|
return p
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(results.length).toBe(4)
|
expect(results.length).toBe(18)
|
||||||
|
expect(results[0]).toMatchObject({
|
||||||
var sampleResult = results[0]
|
start: '2025-01-11T22:55:00.000Z',
|
||||||
|
stop: '2025-01-12T00:40:00.000Z',
|
||||||
expect(sampleResult).toMatchObject({
|
title: 'Una joven prometedora',
|
||||||
start: '2024-11-30T22:36:51.000Z',
|
|
||||||
stop: '2024-11-30T23:57:25.000Z',
|
|
||||||
category: ['Cine', 'Romance', 'Comedia', 'Comedia Romántica'],
|
|
||||||
description:
|
description:
|
||||||
'Charlie trabaja como director en una escuela de primaria y goza de una placentera existencia junto a sus amigos. A pesar de ello, no es feliz porque cada vez que se enamora pierde la cordura.',
|
'Cassie tenía un brillante futuro por delante. Sin embargo, un incidente provocó que no pudiese cumplir sus sueños. Con el paso del tiempo, tendrá la oportunidad de enmendar los errores del pasado.',
|
||||||
title: 'Loco de amor'
|
category: ['Cine', 'Drama', 'Suspense'],
|
||||||
|
icon: 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images/epg/COVER/COVER_2247567.jpg'
|
||||||
|
})
|
||||||
|
expect(results[17]).toMatchObject({
|
||||||
|
start: '2025-01-12T21:05:00.000Z',
|
||||||
|
stop: '2025-01-12T23:05:00.000Z',
|
||||||
|
title: 'Bake Off: Famosos al horno - T2, E01: Bake Off: Famosos al horno',
|
||||||
|
sub_title: 'Bake Off: Famosos al horno',
|
||||||
|
description:
|
||||||
|
'Nervios y emoción en el debut de los 14 pasteleros de la nueva temporada de Bake off Famosos al horno. En el primer programa hornearán unas galletas dedicadas a sus mascotas y una tradicional tarta de queso.',
|
||||||
|
category: ['Programa', 'Reality'],
|
||||||
|
icon: 'https://pc.orangetv.orange.es/pc/api/rtv/v1/images/epg/COVER/COVER_3520028.jpg',
|
||||||
|
season: 2,
|
||||||
|
episode: 1
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can handle empty guide', () => {
|
it('can handle empty guide', async () => {
|
||||||
const result = parser({
|
const result = await parser({
|
||||||
date,
|
date,
|
||||||
channel,
|
channel,
|
||||||
content: '{}'
|
content: '{}'
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ https://orangetv.orange.es/epg
|
|||||||
### Download the guide
|
### Download the guide
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run grab -- --site=orangetv.orange.es
|
npm run grab --- --site=orangetv.orange.es
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update channel list
|
### Update channel list
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run channels:parse -- --config=./sites/orangetv.orange.es/orangetv.orange.es.config.js --output=./sites/orangetv.orange.es/orangetv.orange.es.channels.xml
|
npm run channels:parse --- --config=./sites/orangetv.orange.es/orangetv.orange.es.config.js --output=./sites/orangetv.orange.es/orangetv.orange.es.channels.xml
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test
|
### Test
|
||||||
|
|
||||||
npm test -- orangetv.orange.es
|
```sh
|
||||||
|
npm test --- orangetv.orange.es
|
||||||
|
```
|
||||||
|
|
||||||
### Todo
|
### Todo
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user