Spaces:
No application file
No application file
| const cron = require('node-cron'); | |
| const db = require('./db'); | |
| let currentSourceId = null; | |
| let manualOverride = false; | |
| const getLocalNow = () => { | |
| const tz = process.env.TIMEZONE || 'Indian/Antananarivo'; | |
| try { return new Date(new Date().toLocaleString('en-US', { timeZone: tz })); } | |
| catch { return new Date(); } | |
| }; | |
| const computeCurrent = () => { | |
| if (manualOverride) return currentSourceId; | |
| const schedule = db.read('schedule'); | |
| if (!schedule.length) return null; | |
| const now = getLocalNow(); | |
| const day = now.getDay(); | |
| const cur = now.getHours() * 60 + now.getMinutes(); | |
| const entry = schedule.find(e => { | |
| if (!Array.isArray(e.days) || !e.days.includes(day)) return false; | |
| const start = e.startHour * 60 + (e.startMin || 0); | |
| const end = e.endHour * 60 + (e.endMin || 0); | |
| return cur >= start && cur < end; | |
| }); | |
| return entry ? entry.sourceId : null; | |
| }; | |
| // Retourne l'URL source active — appelée à chaque requête playlist | |
| const getCurrentUrl = () => { | |
| const id = computeCurrent(); | |
| if (!id) return null; | |
| const sources = db.read('sources'); | |
| const src = sources.find(s => s.id === id); | |
| return src ? src.url : null; | |
| }; | |
| const getCurrentInfo = () => { | |
| const id = computeCurrent(); | |
| if (!id) return null; | |
| const src = db.read('sources').find(s => s.id === id); | |
| if (!src) return null; | |
| return { sourceId: id, name: src.name }; | |
| }; | |
| const tick = () => { | |
| const id = computeCurrent(); | |
| if (id !== currentSourceId) { | |
| const now = getLocalNow(); | |
| console.log(`[scheduler] ${now.toTimeString().slice(0,5)} — ${currentSourceId||'aucun'} → ${id||'aucun'}`); | |
| currentSourceId = id; | |
| } | |
| }; | |
| const start = () => { | |
| tick(); | |
| cron.schedule('* * * * *', tick); | |
| const tz = process.env.TIMEZONE || 'Indian/Antananarivo'; | |
| console.log(`[scheduler] Démarré — ${tz} — ${getLocalNow().toTimeString().slice(0,8)}`); | |
| }; | |
| const reload = () => { if (!manualOverride) tick(); }; | |
| const setManual = (sourceId) => { | |
| if (!sourceId) { | |
| manualOverride = false; | |
| currentSourceId = computeCurrent(); | |
| console.log('[scheduler] Retour planning auto →', currentSourceId || 'aucun'); | |
| } else { | |
| manualOverride = true; | |
| currentSourceId = sourceId; | |
| console.log('[scheduler] Manuel →', sourceId); | |
| } | |
| }; | |
| const getCurrent = () => currentSourceId; | |
| const isManual = () => manualOverride; | |
| module.exports = { start, reload, getCurrent, getCurrentUrl, getCurrentInfo, setManual, isManual, getLocalNow }; | |