persist playlists

This commit is contained in:
Lamp 2023-10-17 21:16:46 -07:00
parent b4abb629b7
commit 2df4e24d04
2 changed files with 44 additions and 40 deletions

@ -12,14 +12,6 @@ var server = app.listen(process.env.PORT || 8080, process.env.ADDR);
app.use(morgan(`:date[iso] :remote-addr :method :url ":req[user-agent]" :referrer`));
app.get("/playlist", async (req, res) => {
var channel = req.query.channel || "default";
if (/[^a-z0-9-~]/.test(channel)) {
return res.sendStatus(400);
}
res.send(await getPlaylist(channel));
});
app.get("/channels", async (req, res) => {
res.send(await getChannels());
});
@ -31,23 +23,28 @@ app.get("/newchannel", async (req, res, next) => {
var number = req.query.number;
if (number < 1 || number > 1000) return res.sendStatus(400);
var code = `${search.replaceAll(' ', '-')}~${number}`;
var file = `channels/${code}.json`;
try {
await fs.access(file);
return res.sendStatus(409);
} catch(error) {
if (error.code != "ENOENT") next(error);
await fs.mkdir(`public/channels/${code}`);
} catch (error) {
if (error.code == "EEXIST") {
res.redirect("/"+code);
} else {
next(error);
}
return;
}
execFile("python3", ["getvideos.py", search, number, file], (error, stdout, stderr) => {
execFile("python3", ["getvideos.py", search, number, `public/channels/${code}/dump.json`], (error, stdout, stderr) => {
if (error) next(error);
//res.type("text").send(code);
res.redirect("/"+code);
console.log({stdout, stderr});
generatePlaylist(channel).then(() => {
res.redirect("/"+code);
});
});
});
app.use(/^\/([a-z0-9-~]+)$/, (req, res, next) => {
var channel = req.params[0];
fs.access(`channels/${channel}.json`).then(() => {
fs.access(`public/channels/${channel}`).then(() => {
//req.url = "/index.html"; //??
res.sendFile("index.html", {root: "public"});
}).catch(() => {
@ -60,40 +57,47 @@ app.use(express.static("public"));
var playlists = {};
async function getPlaylist(channel = "default") {
var playlist = playlists[channel];
if (!playlist || Date.now() > playlist.timestamp + playlist.totalDuration*1000) {
playlist = await generatePlaylist(channel);
playlists[channel] = playlist;
}
return playlist;
}
async function generatePlaylist(channel = "default") {
var videos = JSON.parse(await fs.readFile(`channels/${channel}.json`, "utf8")).entries;
videos = videos.map(v => ({
async function generatePlaylist(channel) {
var dump = JSON.parse(await fs.readFile(`public/channels/${channel}/dump.json`, "utf8"));
var videos = dump.entries.map(v => ({
id: v.id,
duration: v.duration,
title: v.title
}));
shuffle(videos);
return {
var playlist = {
videos,
timestamp: Date.now(),
totalDuration: videos.reduce((td, v) => td + v.duration, 0)
}
};
await fs.writeFile(`public/channels/${channel}/playlist.json`, JSON.stringify(playlist));
var expiresIn = playlist.timestamp + playlist.totalDuration*1000 - Date.now();
setTimeout(generatePlaylist, expiresIn);
console.log(`generated new playlist for ${channel} expires in ${expiresIn/1000}s`);
}
(async function () {
var channelDirs = await fs.readdir("public/channels");
for (var channel of channelDirs) {
try {
try {
var playlist = JSON.parse(await fs.readFile(`public/channels/${channel}/playlist.json`, "utf8"));
} catch (error) {
if (error.code != "ENOENT") console.error(error.stack);
}
if (!playlist || Date.now() > playlist.timestamp + playlist.totalDuration*1000) {
await generatePlaylist(channel);
}
} catch (error) {
console.error(error.stack);
}
}
})();
async function getChannels() {
var channels = await fs.readdir("channels");
var channels = await fs.readdir("public/channels");
channels = channels.map(c => {
c = c.replace(".json", "");
var n = [...wss.clients].reduce((num, ws) => ws.channel == c ? num + 1 : num, 0);
return [c, n];
});

@ -235,7 +235,7 @@
async function nowPlaying() {
if (!playlist || Date.now() > playlist.timestamp + playlist.totalDuration*1000) {
playlist = await fetch("playlist?channel=" + channel).then(res => res.json());
playlist = await fetch(`channels/${channel}/playlist.json`).then(res => res.json());
}
for (var i = 0, pastDurations = 0; i < playlist.videos.length; i++) {
var video = playlist.videos[i];