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);