Update starhubtvplus.com guide.

Test:

```sh
npm test -- starhubtvplus.com

> test
> run-script-os starhubtvplus.com

> test:win32
> SET "TZ=Pacific/Nauru" && npx jest --runInBand starhubtvplus.com

 PASS  sites/starhubtvplus.com/starhubtvplus.com.test.js
  √ can generate valid url (3 ms)
  √ can parse response (3 ms)
  √ can handle empty guide (1 ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.337 s
Ran all test suites matching /starhubtvplus.com/i.
```

Grab:

```sh
npm run grab -- --site=starhubtvplus.com --lang=en

> grab
> npx tsx scripts/commands/epg/grab.ts --site=starhubtvplus.com --lang=en

starting...
config:
  output: guide.xml
  maxConnections: 1
  gzip: false
  site: starhubtvplus.com
  lang: en
loading channels...
  found 116 channel(s)
run #1:
  [1/232] starhubtvplus.com (en) - 7c0ee1eb-5f74-4f5a-a338-69eb125badb4 - Dec 4, 2024 (26 programs)
  [2/232] starhubtvplus.com (en) - 7c0ee1eb-5f74-4f5a-a338-69eb125badb4 - Dec 5, 2024 (26 programs)
  ...
  [231/232] starhubtvplus.com (en) - 210ba103-0d19-4b26-bb9f-36d531d7471f - Dec 5, 2024 (39 programs)
  [232/232] starhubtvplus.com (en) - 210ba103-0d19-4b26-bb9f-36d531d7471f - Dec 4, 2024 (39 programs)
  saving to "guide.xml"...
  done in 00h 00m 22s
```

Signed-off-by: Toha <tohenk@yahoo.com>
This commit is contained in:
Toha
2024-12-04 20:56:00 +07:00
parent 864e0ac2c4
commit 4c706f49a4
7 changed files with 359 additions and 242 deletions
@@ -1,86 +1,92 @@
const axios = require('axios')
const dayjs = require('dayjs')
const APP_KEY = '5ee2ef931de1c4001b2e7fa3_5ee2ec25a0e845001c1783dc'
const SESSION_KEY = '01G2QG0N3RWDNCBA1S5MK1MD2K17CE4431A2'
const languages = { en: 'en_US', zh: 'zh' }
module.exports = {
site: 'starhubtvplus.com',
days: 2,
request: {
headers: {
'x-application-key': APP_KEY,
'x-application-session': SESSION_KEY
},
cache: {
ttl: 60 * 60 * 1000 // 1h
}
url({ date, channel }) {
return `https://waf-starhub-metadata-api-p001.ifs.vubiquity.com/v3.1/epg/schedules?locale=${
languages[channel.lang]
}&locale_default=${
languages[channel.lang]
}&device=1&in_channel_id=${
channel.site_id
}&gt_end=${
date.unix()
}&lt_start=${
date.add(1, 'd').unix()
}&limit=100&page=1`
},
url: function ({ date }) {
const variables = JSON.stringify({
category: '',
dateFrom: date.format('YYYY-MM-DD'),
dateTo: date.add(1, 'd').format('YYYY-MM-DD')
})
const query =
'query webFilteredEpg($category: String, $dateFrom: DateWithoutTime, $dateTo: DateWithoutTime!) { nagraEpg(category: $category) { items { id: tvChannel image name: longName programs: programsByDate(dateFrom: $dateFrom, dateTo: $dateTo) { id title description Categories startTime endTime }}}}'
const params = `operationName=webFilteredEpg&variables=${encodeURIComponent(
variables
)}&query=${encodeURIComponent(query)}`
return `https://api.starhubtvplus.com/epg?${params}`
},
parser: function ({ content, channel }) {
let programs = []
const items = parseItems(content, channel)
items.forEach(item => {
programs.push({
title: item.title,
description: item.description,
category: item.Categories,
start: parseStart(item),
stop: parseStop(item)
})
})
return programs
},
async channels() {
const items = await axios
.get(
'https://api.starhubtvplus.com/epg?operationName=webFilteredEpg&variables=%7B%22category%22%3A%22%22,%22dateFrom%22%3A%222022-05-10%22,%22dateTo%22%3A%222022-05-11%22%7D&query=query%20webFilteredEpg(%24category%3A%20String)%20%7B%20nagraEpg(category%3A%20%24category)%20%7B%20items%20%7B%20id%3A%20tvChannel%20image%20name%3A%20longName%20%7D%7D%7D',
{
headers: {
'x-application-key': APP_KEY,
'x-application-session': SESSION_KEY
}
async parser({ content, date, channel }) {
const programs = []
if (content) {
let res = JSON.parse(content)
while (res) {
if (res.resources) {
programs.push(...res.resources)
}
)
.then(r => r.data.data.nagraEpg.items)
.catch(console.log)
if (res.page && res.page.current < res.page.total) {
res = await axios
.get(module.exports.url({ date, channel }).replace(/page=(\d+)/, `page=${res.page.current + 1}`))
.then(r => r.data)
.catch(console.error)
} else {
res = null
}
}
}
const season = s => {
if (s) {
const [ , , n ] = s.match(/(S|Season )(\d+)/) || [null, null, null]
if (n) {
return parseInt(n)
}
}
}
return items.map(item => ({
lang: 'en',
site_id: item.id,
name: item.name.replace('_DASH', '')
return programs.map(item => {
return {
title: item.title,
subTitle: item.serie_title,
description: item.description,
category: item.genres,
image: item.pictures?.map(img => img.url),
season: season(item.serie_title),
episode: item.episode_number,
rating: item.rating,
start: dayjs(item.start * 1000),
stop: dayjs(item.end * 1000)
}
})
},
async channels({ lang = 'en' }) {
const resources = []
let page = 1
while (true) {
const items = await axios
.get(`https://waf-starhub-metadata-api-p001.ifs.vubiquity.com/v3.1/epg/channels?locale=${
languages[lang]
}&locale_default=${
languages[lang]
}&device=1&limit=50&page=${page}`)
.then(r => r.data)
.catch(console.error)
if (items.resources) {
resources.push(...items.resources)
}
if (items.page && page < items.page.total) {
page++
} else {
break
}
}
return resources.map(ch => ({
lang,
site_id: ch.id,
name: ch.title
}))
}
}
function parseStart(item) {
return dayjs(item.startTime)
}
function parseStop(item) {
return dayjs(item.endTime)
}
function parseItems(content, channel) {
const data = JSON.parse(content)
if (!data || !data.data || !data.data.nagraEpg || !Array.isArray(data.data.nagraEpg.items))
return []
const ch = data.data.nagraEpg.items.find(ch => ch.id == channel.site_id)
return ch && Array.isArray(ch.programs) ? ch.programs : []
}