143 lines
3.1 KiB
JavaScript
143 lines
3.1 KiB
JavaScript
/**
|
|
* Represents a single show. This show could be defined in the shows.xml file, or could be inferred from the
|
|
* schedule.
|
|
*/
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @return {Array<RadioShow>}
|
|
*/
|
|
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 = bm.getAttribute("href");
|
|
}
|
|
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 {
|
|
const 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;
|
|
}
|
|
|
|
export default {
|
|
get: getShows,
|
|
parse: parseRadioShows,
|
|
RadioShow: RadioShow,
|
|
};
|