1
0
Fork 0

support RadioShows

This commit is contained in:
boyska 2022-01-30 00:26:07 +01:00
parent 29d74c1b93
commit 0085d53bf1
2 changed files with 122 additions and 7 deletions

View file

@ -14,12 +14,13 @@ function getAttribute(el, attr, default_value) {
}
class Radio {
constructor (sources, schedule, shows, feed) {
constructor (sources, schedule, showsURL, feed) {
this.streaming = new RadioStreaming(sources)
this.schedule = schedule
this.shows = shows
this.showsURL = showsURL
this.feed = feed
this.name = ''
this.shows = []
}
getStreaming () {
@ -30,7 +31,11 @@ class Radio {
this.name = name
}
getShows() {
return this.shows
}
getShowByName (showName) {
return this.shows.find(s => s.name === showName)
}
getSchedule () {
@ -63,9 +68,9 @@ class Radio {
res = xml.evaluate('/radio-manifest/shows', xml)
const showsEl = res.iterateNext()
let shows = null
let showsURL = null
if (showsEl !== null) {
shows = showsEl.getAttribute('src')
showsURL = showsEl.getAttribute('src')
}
res = xml.evaluate('/radio-manifest/feed', xml)
@ -75,7 +80,7 @@ class Radio {
feed = feedEl.getAttribute('src')
}
const manifest = new Radio(sources, schedule, shows, feed)
const manifest = new Radio(sources, schedule, showsURL, feed)
return manifest
}
}
@ -138,6 +143,12 @@ async function get (siteurl, options) {
const dom = parser.parseFromString(text, 'text/xml')
const manifest = Radio.fromDOM(dom)
try {
manifest.shows = await getShows(manifest)
} catch (e) {
console.error("Error while fetching shows file", e)
}
resp = null
try {
resp = await fetch(getStreaminfoUrl(siteurl))
@ -163,10 +174,33 @@ async function get (siteurl, options) {
}
}
// XXX: in base alle options fai fetch anche di altra roba
return manifest
}
async function getShows(manifest) {
if (manifest.showsURL) {
let resp = null
try {
resp = await fetch(manifest.showsURL)
} catch (e) {
true
}
if (resp !== null) {
try {
text = await resp.text()
const parser = new DOMParser()
const showsDom = parser.parseFromString(text, 'text/xml')
return parseRadioShows(showsDom)
} catch (e) {
console.error('Error while parsing shows file', e)
throw e
}
}
}
}
function parseM3U (body) {
return body.split('\n').filter((line) => {
if (line.startsWith('#')) {
@ -181,6 +215,61 @@ function parseM3U (body) {
})
}
class RadioShow {
constructor(name, description, website, feed, schedule, radio_calendar) {
this.name = name
this.description = description
this.website = website
this.feed = feed
this.schedule = schedule
this.radio_calendar = radio_calendar
}
getName() {
return this.name
}
getWebsite() {
return this.website
}
getFeed() {
return this.feed
}
getSchedule() {
return this.schedule
}
}
function showsNamespaceResolver(prefix) {
const prefixes = {
show: 'https://radiomanifest.degenerazione.xyz/shows/',
}
return prefixes[prefix] || null
}
function parseRadioShows(xml) {
const doc = xml.cloneNode(true)
const bookmarks = doc.evaluate('//bookmark', doc, showsNamespaceResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
const shows = []
for (let i = 0; i < bookmarks.snapshotLength; i++) {
const bm = bookmarks.snapshotItem(i)
const name = doc.evaluate('./info/metadata/show:name', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
const website = doc.evaluate('./info/metadata/show:website', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
const feed = doc.evaluate('./info/metadata/show:feed', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
const schedule = doc.evaluate('./info/metadata/show:schedule', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
let description = doc.evaluate('./info/metadata/show:description', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
if(description === '') {
description = doc.evaluate('./description', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue
}
const show = new RadioShow(name || null, description, website || null, feed || null, schedule || null)
shows.push(show)
}
return shows
}
module.exports = {
get: get,
objs: {
@ -189,6 +278,7 @@ module.exports = {
},
parsers: {
M3U: parseM3U,
radioManifest: Radio.fromDOM
radioManifest: Radio.fromDOM,
shows: parseRadioShows,
}
}

View file

@ -0,0 +1,25 @@
const radiomanifest = require('../radiomanifest.js')
const chai = require('chai')
chai.use(require('chai-as-promised'))
const assert = chai.assert
const exampleName = 'full-ondarossa'
const expect = chai.expect
const url = 'https://radiomanifest.degenerazione.xyz/v0.2/examples/' + exampleName + '/'
describe('examples/' + exampleName, () => {
describe('shows', () => {
it('shoud find many shows', async () => {
const rm = await radiomanifest.get(url)
assert.isAbove(rm.getShows().length, 1)
})
it('one of which is called "Entropia Massima"', async () => {
const rm = await radiomanifest.get(url)
const show = rm.getShowByName("Entropia Massima")
assert.equal(show.getName(), "Entropia Massima")
assert.equal(show.getWebsite(), "http://www.ondarossa.info/trx/entropia-massima")
assert.equal(show.getSchedule(), null)
})
})
})