forked from boyska/radiomanifest.js
support RadioShows
This commit is contained in:
parent
29d74c1b93
commit
0085d53bf1
2 changed files with 122 additions and 7 deletions
104
radiomanifest.js
104
radiomanifest.js
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
25
test/example-full-ondarossa.test.js
Normal file
25
test/example-full-ondarossa.test.js
Normal 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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in a new issue