diff --git a/radiomanifest.js b/radiomanifest.js index 67b77b3..94058a2 100644 --- a/radiomanifest.js +++ b/radiomanifest.js @@ -1,4 +1,5 @@ const fetch = require('isomorphic-unfetch') +const shows = require('./shows.js') function getStreaminfoUrl (siteurl) { return siteurl + '/streaminfo.json' // XXX: improve this logic @@ -144,7 +145,7 @@ async function get (siteurl, options) { const manifest = Radio.fromDOM(dom) try { - manifest.shows = await getShows(manifest) + manifest.shows = await shows.get(manifest) } catch (e) { console.error("Error while fetching shows file", e) } @@ -177,28 +178,6 @@ async function get (siteurl, options) { 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) { @@ -215,66 +194,6 @@ 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) - - let name = doc.evaluate('./info/metadata/show:name', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue - if (name === '') { - name = doc.evaluate('./title', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue - } - let website = doc.evaluate('./info/metadata/show:website', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue - if (website === '') { - website = getAttribute(bm, 'href', null) - } - 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('./desc', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue - } - - const show = new RadioShow(name, description || null, website || null, feed || null, schedule || null) - shows.push(show) - } - - return shows -} module.exports = { get: get, @@ -285,6 +204,6 @@ module.exports = { parsers: { M3U: parseM3U, radioManifest: Radio.fromDOM, - shows: parseRadioShows, + shows: shows.parse, } } diff --git a/shows.js b/shows.js new file mode 100644 index 0000000..461a282 --- /dev/null +++ b/shows.js @@ -0,0 +1,89 @@ +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 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) + + let name = doc.evaluate('./info/metadata/show:name', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue + if (name === '') { + name = doc.evaluate('./title', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue + } + let website = doc.evaluate('./info/metadata/show:website', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue + if (website === '') { + website = getAttribute(bm, 'href', null) + } + 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('./desc', bm, showsNamespaceResolver, XPathResult.STRING_TYPE).stringValue + } + + const show = new RadioShow(name, description || null, website || null, feed || null, schedule || null) + shows.push(show) + } + + return shows +} + +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 showsNamespaceResolver(prefix) { + const prefixes = { + show: 'https://radiomanifest.degenerazione.xyz/shows/', + } + return prefixes[prefix] || null +} + + +module.exports = { + get: getShows, + parse: parseRadioShows, + RadioShow: RadioShow, +}