diff --git a/sites/tvpassport.com/tvpassport.com.config.js b/sites/tvpassport.com/tvpassport.com.config.js index 5a1c0e42d..7751c2890 100644 --- a/sites/tvpassport.com/tvpassport.com.config.js +++ b/sites/tvpassport.com/tvpassport.com.config.js @@ -11,29 +11,24 @@ dayjs.extend(utc) dayjs.extend(timezone) dayjs.extend(customParseFormat) +const headers = {} + module.exports = { site: 'tvpassport.com', days: 3, - url({ channel, date }) { - return `https://www.tvpassport.com/tv-listings/stations/${channel.site_id}/${date.format( - 'YYYY-MM-DD' - )}` + async url({ channel, date }) { + return await getSiteUrl(channel, date.format('YYYY-MM-DD')) }, - async request() { - return { - timeout: 30000, - headers: { - Cookie: await getCookie() - } - } + request: { + timeout: 30000, + headers }, - parser: function ({ content }) { - let programs = [] - const currentTimezone = parseCurrentTimezone(content) - const items = parseItems(content) - for (let item of items) { - const $item = cheerio.load(item) - const start = parseStart($item, currentTimezone) + parser({ content }) { + const programs = [] + const [$, tz, items] = parseItems(content) + for (const item of items) { + const $item = $(item) + const start = parseStart($item, tz) const duration = parseDuration($item) const stop = start.add(duration, 'm') let title = parseTitle($item) @@ -85,7 +80,7 @@ module.exports = { await doFetch(queue, async (url, res) => { if (!res) return - const [, site_id] = url.match(/\/tv-listings\/stations\/(.*)$/) + const site_id = getSiteId(url) console.log(`[${i}/${total}]`, url) @@ -109,63 +104,88 @@ module.exports = { } } -async function getCookie() { - const res = await axios.get('https://www.tvpassport.com/tv-listings') - const setCookie = res.headers['set-cookie'] - if (!setCookie || setCookie.length === 0) return '' - const cookies = setCookie.map(cookie => cookie.split(';')[0]) - return cookies.join('; ') +async function getSiteUrl(channel, date) { + const f = () => + `https://www.tvpassport.com/tv-listings/stations/${channel.site_id}/${date}` + let url = f() + const res = await axios.head(url, { headers }) + .then(res => saveCookies(res)) + .then(res => res?.request?.res?.responseUrl) + .catch(console.error) + if (res && res !== url) { + channel.site_id = getSiteId(res) + url = f() + } + + return url +} + +function getSiteId(url) { + const [, site_id] = url.match(/\/tv-listings\/stations\/(.*)$/) + + return site_id +} + +function saveCookies(res) { + if (res.headers && Array.isArray(res.headers['set-cookie'])) { + const cookies = [] + cookies.push(...res.headers['set-cookie'] + .map(cookie => cookie.split(';')[0].trim())) + headers.Cookie = cookies.length ? cookies.join('; ') : null + } + + return res } function parseDescription($item) { - return $item('*').data('description') + return $item.data('description') } function parseImage($item) { - const showpicture = $item('*').data('showpicture') + const showpicture = $item.data('showpicture') const url = new URL(showpicture, 'https://cdn.tvpassport.com/image/show/960x540/') return url.href } function parseTitle($item) { - return $item('*').data('showname').toString() + return $item.data('showname').toString() } function parseSubTitle($item) { - return $item('*').data('episodetitle')?.toString() || null + return $item.data('episodetitle')?.toString() || null } function parseYear($item) { - return $item('*').data('year')?.toString() || null + return $item.data('year')?.toString() || null } function parseCategory($item) { - const showtype = $item('*').data('showtype') + const showtype = $item.data('showtype') return showtype ? showtype.split(', ') : [] } function parseActors($item) { - const cast = $item('*').data('cast') + const cast = $item.data('cast') return cast ? cast.split(', ') : [] } function parseDirector($item) { - const director = $item('*').data('director') + const director = $item.data('director') return director ? director.split(', ') : [] } function parseGuest($item) { - const guest = $item('*').data('guest') + const guest = $item.data('guest') return guest ? guest.split(', ') : [] } function parseRating($item) { - const rating = $item('*').data('rating') + const rating = $item.data('rating') return rating ? { @@ -176,28 +196,24 @@ function parseRating($item) { } function parseStart($item, currentTimezone) { - const time = $item('*').data('st') + const time = $item.data('st') return dayjs.tz(time, 'YYYY-MM-DD HH:mm:ss', currentTimezone) } function parseDuration($item) { - const duration = $item('*').data('duration') + const duration = $item.data('duration') return parseInt(duration) } function parseItems(content) { - if (!content) return [] + if (!content) return [null, null, []] const $ = cheerio.load(content) - return $('.station-listings .list-group-item').toArray() + return [ + $, + $('#timezone_selector').val() || 'America/New_York', + $('.station-listings .list-group-item').toArray() + ] } - -function parseCurrentTimezone(content) { - if (!content) return 'America/New_York' - const $ = cheerio.load(content) - - return $('#timezone_selector').val() -} - diff --git a/sites/tvpassport.com/tvpassport.com.test.js b/sites/tvpassport.com/tvpassport.com.test.js index ca12019bd..e31e311ac 100644 --- a/sites/tvpassport.com/tvpassport.com.test.js +++ b/sites/tvpassport.com/tvpassport.com.test.js @@ -1,20 +1,28 @@ const { parser, url } = require('./tvpassport.com.config.js') +const axios = require('axios') const fs = require('fs') const path = require('path') const dayjs = require('dayjs') const utc = require('dayjs/plugin/utc') const customParseFormat = require('dayjs/plugin/customParseFormat') + dayjs.extend(customParseFormat) dayjs.extend(utc) +jest.mock('axios') + const date = dayjs.utc('2022-10-04', 'YYYY-MM-DD').startOf('d') const channel = { site_id: 'youtoo-america-network/5463', xmltv_id: 'YTATV.us' } -it('can generate valid url', () => { - expect(url({ channel, date })).toBe( +axios.head.mockImplementation(() => { + return Promise.resolve({}) +}) + +it('can generate valid url', async () => { + expect(await url({ channel, date })).toBe( 'https://www.tvpassport.com/tv-listings/stations/youtoo-america-network/5463/2022-10-04' ) })