Merge pull request #2907 from corrreia/more-data-meo.pt

More data meo.pt
This commit is contained in:
PopeyeTheSai10r
2025-11-03 17:38:53 -08:00
committed by GitHub
2 changed files with 90 additions and 11 deletions

View File

@@ -20,21 +20,50 @@ module.exports = {
} }
} }
}, },
parser({ content }) { async parser({ content }) {
const axios = require('axios')
let programs = [] let programs = []
const items = parseItems(content) const items = parseItems(content)
items.forEach(item => { if (!items.length) return programs
// simple per-run in-memory cache
const detailsCache = new Map()
for (const item of items) {
const start = parseStart(item) const start = parseStart(item)
let stop = parseStop(item) let stop = parseStop(item)
if (stop < start) { if (stop < start) {
stop = stop.plus({ days: 1 }) stop = stop.plus({ days: 1 })
} }
programs.push({
title: item.name, let description = ''
let image = ''
const programID = item.uniqueId || null
if (programID) {
let details = detailsCache.get(programID)
if (!details) {
details = await fetchProgramDetails(programID, axios).catch(() => null)
if (details) detailsCache.set(programID, details)
}
if (details) {
description = details.description || description
image = details.image || image
}
}
const prog = {
title: item.name || 'Sem título',
start, start,
stop stop
}) }
}) if (description) prog.description = description
if (image) {
prog.icon = { src: image }
prog.image = image
}
programs.push(prog)
}
return programs return programs
}, },
@@ -43,12 +72,15 @@ module.exports = {
const data = await axios const data = await axios
.post('https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getGridAnon', null, { .post('https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getGridAnon', null, {
headers: { headers: {
Origin: 'https://www.meo.pt' Origin: 'https://www.meo.pt',
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; en-US Trident/4.0)'
} }
}) })
.then(r => r.data) .then(r => r.data)
.catch(console.log) .catch(console.log)
// channel logo at data.d.channels.logo
return data.d.channels return data.d.channels
.map(item => { .map(item => {
return { return {
@@ -80,3 +112,42 @@ function parseItems(content) {
return Array.isArray(programs) ? programs : [] return Array.isArray(programs) ? programs : []
} }
async function fetchProgramDetails(programID, axiosInstance) {
try {
const response = await axiosInstance.post(
'https://authservice.apps.meo.pt/Services/GridTv/GridTvMng.svc/getProgramDetails',
{
service: 'programdetail',
programID: String(programID),
accountID: ''
},
{
headers: {
Origin: 'https://www.meo.pt',
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; en-US Trident/4.0)'
},
timeout: 10000
}
)
const data = response.data
// Response structure has program data directly in data.d
const program = data?.d
if (!program || typeof program !== 'object') return null
// Build image URL using MEO's image handler
let image = null
if (program.progName && program.channelSigla) {
const encodedTitle = encodeURIComponent(program.progName)
image = `https://proxycache.online.meo.pt/eemstb/ImageHandler.ashx?evTitle=${encodedTitle}&chCallLetter=${program.channelSigla}&profile=16_9&width=600`
}
const description = program.description || null
return { description, image }
} catch {
// Silent fail returning null so parser continues
return null
}
}

View File

@@ -7,6 +7,10 @@ const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
dayjs.extend(utc) dayjs.extend(utc)
const axios = require('axios')
jest.mock('axios')
const date = dayjs.utc('2022-12-02', 'YYYY-MM-DD').startOf('d') const date = dayjs.utc('2022-12-02', 'YYYY-MM-DD').startOf('d')
const channel = { const channel = {
site_id: 'RTPM', site_id: 'RTPM',
@@ -39,9 +43,13 @@ it('can generate valid request method', () => {
}) })
}) })
it('can parse response', () => { it('can parse response', async () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json')) const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
let results = parser({ content }).map(p => {
axios.post.mockResolvedValue({ data: {} })
let results = await parser({ content })
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
@@ -54,7 +62,7 @@ it('can parse response', () => {
}) })
}) })
it('can handle empty guide', () => { it('can handle empty guide', async () => {
const result = parser({ content: '', channel, date }) const result = await parser({ content: '', channel, date })
expect(result).toMatchObject([]) expect(result).toMatchObject([])
}) })