2025-09-28 17:55:05 +03:00
const axios = require ( 'axios' )
const dayjs = require ( 'dayjs' )
const utc = require ( 'dayjs/plugin/utc' )
const parseDuration = require ( 'parse-duration' ). default
dayjs . extend ( utc )
module . exports = {
site : 'freeview.co.uk' ,
days : 2 ,
url ({ date , channel }) {
const [ networkId ] = channel . site_id . split ( '#' )
const startTimestamp = date . startOf ( 'd' ). unix ()
return `https://www.freeview.co.uk/api/tv-guide?nid= ${ networkId } &start= ${ startTimestamp } `
},
2025-10-31 11:00:28 +00:00
async parser ({ content , channel }) {
2025-09-28 17:55:05 +03:00
let programs = []
let items = parseItems ( content , channel )
2025-10-31 11:00:28 +00:00
for ( const item of items ) {
2025-09-28 17:55:05 +03:00
const start = parseStart ( item )
const duration = parseDuration ( item . duration )
const stop = start . add ( duration , 'ms' )
2025-10-31 11:00:28 +00:00
const details = await loadProgramDetails ( item )
const synopsis = details ? . synopsis
2025-09-28 17:55:05 +03:00
programs . push ({
title : item . main_title ,
subtitle : item . secondary_title ,
2025-10-31 11:00:28 +00:00
description : synopsis ? . long || synopsis ? . medium || synopsis ? . short || null ,
2025-09-28 17:55:05 +03:00
image : parseImage ( item ),
start ,
stop
})
2025-10-31 11:00:28 +00:00
}
2025-09-28 17:55:05 +03:00
return programs
},
async channels () {
const startTimestamp = dayjs . utc (). startOf ( 'd' ). unix ()
2026-04-22 16:16:53 +01:00
let channels = []
for ( let networkId = 64257 ; networkId <= 64425 ; networkId ++ ) { // loop through all valid networkIds starting from 64257 (Greater London) to 64425 (Belfast) to ensure we can get all the channels available on freeview
console . log ( networkId )
const data = await axios
. get ( `https://www.freeview.co.uk/api/tv-guide?nid= ${ networkId } &start= ${ startTimestamp } ` )
. then ( r => r . data )
. catch ( console . log )
2025-09-28 17:55:05 +03:00
2026-04-22 16:16:53 +01:00
channels = channels . concat ( data . data . programs . map ( item => ({
lang : 'en' ,
site_id : ` ${ networkId } # ${ item . service_id } ` ,
name : item . title
})))
}
const uniqueServiceIds = Array . from ( new Set ( channels . map ( c => c . site_id . split ( '#' )[ 1 ])))
return uniqueServiceIds . map ( serviceId => {
return channels . find ( c => c . site_id . split ( '#' )[ 1 ] === serviceId )
})
2025-09-28 17:55:05 +03:00
}
}
function parseImage ( item ) {
return item . image_url ? ` ${ item . image_url } ?w=800` : null
}
function parseStart ( item ) {
return dayjs ( item . start_time )
}
function parseItems ( content , channel ) {
try {
const data = JSON . parse ( content )
const programs = data ? . data ? . programs
if ( ! Array . isArray ( programs )) return []
const [, channelId ] = channel . site_id . split ( '#' )
const channelData = programs . find ( p => p . service_id === channelId )
const channelPrograms = channelData ? . events
if ( ! Array . isArray ( channelPrograms )) return []
return channelPrograms
} catch {
return []
}
}
2025-10-31 11:00:28 +00:00
async function loadProgramDetails ( item ) {
const url = `https://www.freeview.co.uk/api/program?pid= ${ item . program_id } &start_time= ${ item . start_time } &duration= ${ item . duration } `
const data = await axios
. get ( url )
. then ( r => {
const programs = r ? . data ? . data ? . programs
return Array . isArray ( programs ) && programs . length > 0 ? programs [ 0 ] : {}
})
. catch ( console . log )
return data || {}
2026-04-22 16:16:53 +01:00
}