diff --git a/index.js b/index.js index 36d04fc..483872c 100644 --- a/index.js +++ b/index.js @@ -159,26 +159,33 @@ app.get('/epg.xml', async (req, res) => { xml += ` \n`; }); - // Programme entries for live channels + // Programme entries — live channels show stream info, offline show "Off Air" + const now = new Date(); + const pad = n => String(n).padStart(2, '0'); + const toXmltvDate = (d) => + `${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())} +0000`; + + // Start of today (UTC) and end of today for Off Air block + const dayStart = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())); + const dayEnd = new Date(dayStart.getTime() + 24 * 60 * 60 * 1000); + results.forEach(r => { if (r.status !== 'fulfilled') return; const { ch, content } = r.value; - if (!content || content.status !== 'OPEN') return; + const isLive = content && content.status === 'OPEN'; - const openDate = content.openDate - ? content.openDate.replace(/[-: ]/g, '').substring(0, 14) + ' +0900' - : null; - // Assume a 6-hour window for the programme end (no real end time available) - const endDate = content.openDate - ? (() => { - const d = new Date(content.openDate); - d.setHours(d.getHours() + 6); - const pad = n => String(n).padStart(2, '0'); - return `${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())} +0900`; - })() - : null; + if (isLive) { + const openDate = content.openDate + ? content.openDate.replace(/[-: ]/g, '').substring(0, 14) + ' +0900' + : toXmltvDate(now); + const endDate = content.openDate + ? (() => { + const d = new Date(content.openDate); + d.setHours(d.getHours() + 6); + return `${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())} +0900`; + })() + : toXmltvDate(dayEnd); - if (openDate && endDate) { xml += ` \n`; xml += ` ${escapeXml(content.liveTitle || ch.name)}\n`; if (content.liveCategoryValue || content.liveCategory) { @@ -188,9 +195,16 @@ app.get('/epg.xml', async (req, res) => { xml += ` \n`; } xml += ` \n`; + } else { + // Offline — fill today with an "Off Air" block + xml += ` \n`; + xml += ` Off Air\n`; + xml += ` ${escapeXml(ch.name)} is not currently live.\n`; + xml += ` \n`; } }); + xml += '\n'; res.header('Content-Type', 'application/xml'); res.send(xml);