Files
epg/sites/nowplayer.now.com/nowplayer.now.com.config.js
T
2026-07-23 09:25:03 +07:00

128 lines
4.0 KiB
JavaScript

const axios = require('axios')
const cheerio = require('cheerio')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const doFetch = require('@ntlab/sfetch')
dayjs.extend(utc)
const eventIds = {}
const cookies = {}
const caches = {}
module.exports = {
site: 'nowplayer.now.com',
days: 2,
url({ channel, date }) {
const diff = date.diff(dayjs.utc().startOf('d'), 'd') + 1
return `https://nowplayer.now.com/tvguide/epglist?channelIdList[]=${channel.site_id}&day=${diff}`
},
request: {
cache: {
ttl: 24 * 60 * 60 * 1000 // 1 day
},
headers({ channel }) {
return {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 OPR/132.0.0.0',
'cookie': Object.entries({ ...cookies, LANG: channel.lang})
.map(a => `${a[0]}=${a[1]}`)
.join('; ')
}
}
},
async parser({ content, channel, headers }) {
const programs = []
parseCookies(headers)
const items = parseItems(content)
if (items.length) {
if (eventIds[channel.lang] === undefined) {
eventIds[channel.lang] = []
}
const queues = items
.filter(item => item.vimProgramId && !eventIds[channel.lang].includes(item.vimProgramId))
.map(item => {
const url = `https://nowplayer.now.com/tvguide/epgprogramdetail?programId=${item.vimProgramId}`
if (caches[url] !== undefined) {
item.detail = caches[url]
} else {
return {
url,
params: { headers: module.exports.request.headers({ channel }) },
item
}
}
})
.filter(Boolean)
const worker = process.env.EPG_DETAILED_GUIDE_WORKER || 10
const delay = process.env.EPG_DETAILED_GUIDE_DELAY || 500
await doFetch(queues, { worker }, async (queue, res, headers) => {
parseCookies(headers)
queue.item.detail = res
caches[queue.url] = res
await new Promise(resolve => setTimeout(resolve, delay))
})
items.forEach(item => {
eventIds[channel.lang].push(item.vimProgramId)
programs.push({
title: (channel.lang === 'zh' ? item.detail?.chiProgName : item.detail?.progName) || item.name,
description: channel.lang === 'zh' ? item.detail?.chiSynopsis : item.detail?.synopsis,
categories: [item.detail?.genre, item.detail?.subGenre].filter(Boolean),
actor: item.detail?.actor?.split(',').map(a => a.trim()),
director: item.detail?.director?.split(',').map(a => a.trim()),
year: item.detail?.firstReleaseYear?.toString(),
start: getDate(item.start),
stop: getDate(item.end)
})
})
}
return programs
},
async channels({ lang }) {
const html = await axios
.get('https://nowplayer.now.com/channels', { headers: { Accept: 'text/html' } })
.then(r => r.data)
.catch(console.log)
const channels = []
const $ = cheerio.load(html)
$('body > div.container > .tv-guide-s-g > div > div').each((i, el) => {
channels.push({
lang,
site_id: $(el).find('.guide-g-play > p.channel').text().replace('CH', ''),
name: $(el).find('.thumbnail > a > span.image > p').text()
})
})
return channels
}
}
function parseItems(content) {
const data = JSON.parse(content)
if (!data || !Array.isArray(data)) return []
return Array.isArray(data[0]) ? data[0] : []
}
function parseCookies(headers) {
if (headers && Array.isArray(headers['set-cookie'])) {
headers['set-cookie']
.map(cookie => cookie.split(';')[0].trim())
.forEach(cookie => {
const [k, v] = [
cookie.substr(0, cookie.indexOf('=')),
cookie.substr(cookie.indexOf('=') + 1),
]
cookies[k] = v
})
}
}
function getDate(dt) {
return dayjs.utc(dt)
}