epg/sites/astro.com.my/astro.com.my.config.js
2023-10-15 14:08:23 +03:00

123 lines
3.2 KiB
JavaScript

const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
const API_ENDPOINT = 'https://contenthub-api.eco.astro.com.my'
module.exports = {
site: 'astro.com.my',
days: 2,
url: function ({ channel }) {
return `${API_ENDPOINT}/channel/${channel.site_id}.json`
},
async parser({ content, date }) {
const programs = []
const items = parseItems(content, date)
for (let item of items) {
const start = dayjs.utc(item.datetimeInUtc)
const duration = parseDuration(item.duration)
const stop = start.add(duration, 's')
const details = await loadProgramDetails(item)
programs.push({
title: details.title,
sub_title: item.subtitles,
description: details.longSynopsis || details.shortSynopsis,
actors: parseList(details.cast),
directors: parseList(details.director),
icon: details.imageUrl,
rating: parseRating(details),
categories: parseCategories(details),
episode: parseEpisode(item),
season: parseSeason(details),
start: start,
stop: stop
})
}
return programs
}
}
function parseEpisode(item) {
const [, number] = item.title.match(/Ep(\d+)$/) || [null, null]
return number ? parseInt(number) : null
}
function parseSeason(details) {
const [, season] = details.title ? details.title.match(/ S(\d+)/) || [null, null] : [null, null]
return season ? parseInt(season) : null
}
function parseList(list) {
return typeof list === 'string' ? list.split(',') : []
}
function parseRating(details) {
return details.certification
? {
system: 'LPF',
value: details.certification
}
: null
}
function parseItems(content, date) {
try {
const data = JSON.parse(content)
const schedules = data.response.schedule
return schedules[date.format('YYYY-MM-DD')] || []
} catch (e) {
return []
}
}
function parseDuration(duration) {
const match = duration.match(/(\d{2}):(\d{2}):(\d{2})/)
const hours = parseInt(match[1])
const minutes = parseInt(match[2])
const seconds = parseInt(match[3])
return hours * 3600 + minutes * 60 + seconds
}
function parseCategories(details) {
const genres = {
'filter/2': 'Action',
'filter/4': 'Anime',
'filter/12': 'Cartoons',
'filter/16': 'Comedy',
'filter/19': 'Crime',
'filter/24': 'Drama',
'filter/25': 'Educational',
'filter/36': 'Horror',
'filter/39': 'Live Action',
'filter/55': 'Pre-school',
'filter/56': 'Reality',
'filter/60': 'Romance',
'filter/68': 'Talk Show',
'filter/69': 'Thriller',
'filter/72': 'Variety',
'filter/75': 'Series',
'filter/100': 'Others (Children)'
}
return Array.isArray(details.subFilter)
? details.subFilter.map(g => genres[g.toLowerCase()]).filter(Boolean)
: []
}
async function loadProgramDetails(item) {
const url = `${API_ENDPOINT}/api/v1/linear-detail?siTrafficKey=${item.siTrafficKey}`
const data = await axios
.get(url)
.then(r => r.data)
.catch(error => console.log(error.message))
if (!data) return {}
return data.response || {}
}