1
0
Fork 0

support schedule

This commit is contained in:
boyska 2022-01-30 02:23:11 +01:00
parent d524cbbace
commit 5bfe52c235
3 changed files with 136 additions and 5 deletions

117
calendar.js Normal file
View file

@ -0,0 +1,117 @@
const ICAL = require('ical.js')
const shows = require('./shows.js')
class RadioSchedule {
constructor (calendar, radio) {
this.calendar = calendar // ICAL.Calendar
this.radio = radio // radiomanifest.Radio
}
getEvents() {
return this.calendar.getAllSubcomponents('vevent');
}
getNowEvent(now) {
var ev_now = this.getEvents().filter(function(vevent) {
const ev = new ICAL.Event(vevent)
return isNow(ev, now)
})
if(ev_now.length === 0)
return null
if(ev_now.length > 1)
console.log("More than one event right now?!")
return ev_now[0]
}
getNowShow(now) {
var ev = this.getNowEvent(now)
if (ev === null) return null
if (this.radio !== undefined) {
const showid = RadioSchedule.veventGetShowID(ev)
var show = this.radio.getShowByName(showid)
if (show === null || show === undefined) {
return new shows.RadioShow(RadioSchedule.veventGetSummary(ev))
}
return show;
}
return new shows.RadioShow(RadioSchedule.veventGetSummary(ev))
}
getNextEvent(now) {
// XXX
}
getNextShow(now) {
// XXX
}
static veventGetSummary(vevent) {
return vevent.getFirstProperty('summary').getFirstValue()
}
static veventGetShowID(vevent) {
return RadioSchedule.veventGetSummary(vevent) // XXX: X-Show-ID
}
}
function isNow(vEvent, now) {
if (now === undefined) {
now = ICAL.Time.now()
}
if (vEvent.isRecurring()) {
return isNowRecurring(vEvent, now)
}
return (now < vEvent.endDate) && (now > event.startDate);
}
function isNowRecurring(vEvent, now) {
var expand = vEvent.iterator(vEvent.startDate)
var next, next_end;
while ((next = expand.next())) {
next_end = next.clone()
next_end.addDuration(vEvent.duration)
if (next_end > now) {
break;
}
}
return (now < next_end && now > next);
}
async function get(manifest) {
if (manifest.scheduleURL) {
let resp = null
try {
resp = await fetch(manifest.scheduleURL)
} catch (e) {
true
}
if (resp !== null) {
try {
text = await resp.text()
return parse(text)
} catch (e) {
console.error('Error while parsing schedule', e)
throw e
}
}
}
}
function parse(text) {
var jcalData = ICAL.parse(text);
var vcalendar = new ICAL.Component(jcalData);
return new RadioSchedule(vcalendar)
}
module.exports = {
get: get,
parse: parse,
RadioSchedule: RadioSchedule,
}

View file

@ -31,6 +31,7 @@
"webpack-cli": "^4.9.1"
},
"dependencies": {
"ical.js": "^1.5.0",
"isomorphic-unfetch": "^3.1.0"
}
}

View file

@ -1,5 +1,6 @@
const fetch = require('isomorphic-unfetch')
const shows = require('./shows.js')
const calendar = require('./calendar.js')
function getStreaminfoUrl (siteurl) {
return siteurl + '/streaminfo.json' // XXX: improve this logic
@ -15,13 +16,14 @@ function getAttribute(el, attr, default_value) {
}
class Radio {
constructor (sources, schedule, showsURL, feed) {
constructor (sources, scheduleURL, showsURL, feed) {
this.streaming = new RadioStreaming(sources)
this.schedule = schedule
this.scheduleURL = scheduleURL
this.showsURL = showsURL
this.feed = feed
this.name = ''
this.shows = []
this.schedule = null
}
getStreaming () {
@ -36,10 +38,12 @@ class Radio {
return this.shows
}
getShowByName (showName) {
if (this.shows === undefined) return null
return this.shows.find(s => s.name === showName)
}
getSchedule () {
return this.schedule
}
getShowAtTime () {
@ -62,9 +66,9 @@ class Radio {
res = doc.evaluate('/radio-manifest/schedule', doc)
const scheduleEl = res.iterateNext()
let schedule = null
let scheduleURL = null
if (scheduleEl !== null) {
schedule = scheduleEl.getAttribute('src')
scheduleURL = scheduleEl.getAttribute('src')
}
res = xml.evaluate('/radio-manifest/shows', xml)
@ -81,7 +85,7 @@ class Radio {
feed = feedEl.getAttribute('src')
}
const manifest = new Radio(sources, schedule, showsURL, feed)
const manifest = new Radio(sources, scheduleURL, showsURL, feed)
return manifest
}
}
@ -150,6 +154,15 @@ async function get (siteurl, options) {
console.error("Error while fetching shows file", e)
}
try {
manifest.schedule = await calendar.get(manifest)
if (manifest.schedule !== undefined)
manifest.schedule.radio = manifest
} catch (e) {
console.error("Error while fetching shows file", e)
}
resp = null
try {
resp = await fetch(getStreaminfoUrl(siteurl))