radiomanifest.js/shows.js
2023-09-14 00:07:13 +01:00

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,
};