summaryrefslogtreecommitdiff
path: root/includes/process.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/process.js')
-rw-r--r--includes/process.js230
1 files changed, 215 insertions, 15 deletions
diff --git a/includes/process.js b/includes/process.js
index 0a1798f..88a477b 100644
--- a/includes/process.js
+++ b/includes/process.js
@@ -4,22 +4,44 @@ const path = require('path');
const uuid = require('crypto').randomUUID;
const substitutes = [
- ["illenium", "ILLENIUM"]
+ ["illenium", "ILLENIUM"],
+ ["SueCo", "Sueco"],
+ ["Illenium", "ILLENIUM"],
+ ["Princewhateverer", "PrinceWhateverer"],
+ ["Kennyoung", "kennyoung"],
+ ["4EverfreeBrony", "4everfreebrony"],
+ ["4Everfreebrony", "4everfreebrony"]
];
+if (!fs.existsSync("../assets/content/_")) fs.mkdirSync("../assets/content/_");
+if (!fs.existsSync("../assets/content/songs.json")) fs.writeFileSync("../assets/content/songs.json", "{}");
+if (!fs.existsSync("../assets/content/albums.json")) fs.writeFileSync("../assets/content/albums.json", "{}");
+
const songs = require('../assets/content/songs.json');
const albums = require('../assets/content/albums.json');
function scandir(dir) {
+ let count = 0;
+
+ function updateScandirDisplay() {
+ process.stdout.clearLine(null);
+ process.stdout.cursorTo(0);
+ process.stdout.write("Scanning... " + count);
+ }
+
return new Promise((res, rej) => {
const walk = (dir, done) => {
let results = [];
fs.readdir(dir, function(err, list) {
+ count++;
+ updateScandirDisplay();
if (err) return done(err);
let pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file) {
+ count++;
+ updateScandirDisplay();
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
@@ -48,25 +70,77 @@ function scandir(dir) {
function substitute(text) {
for (let sub of substitutes) {
- if (text.trim() === sub[0].trim()) {
- return sub[1].trim();
- }
+ text = text.replaceAll(sub[0], sub[1]);
+ }
+
+ return text;
+}
+
+function timeToString(time) {
+ if (!isNaN(parseInt(time))) {
+ time = new Date(time).getTime();
}
+
+ let periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
+
+ let lengths = ["60", "60", "24", "7", "4.35", "12", "100"];
+
+ let now = new Date().getTime();
+
+ let difference = time / 1000;
+ let period;
+
+ let j;
+
+ for (j = 0; difference >= lengths[j] && j < lengths.length - 1; j++) {
+ difference /= lengths[j];
+ }
+
+ difference = Math.round(difference);
+
+ period = periods[j];
+
+ return `${difference} ${period}${difference > 1 ? "s" : ""}`;
}
(async () => {
- for (let file of (await scandir("../assets/content/_")).filter(i => i.endsWith(".flac"))) {
+ let timePerOp = [];
+ let list = (await scandir("../assets/content/_")).filter(i => i.endsWith(".flac"));
+ process.stdout.write(" files found, " + list.length + " to process\n");
+ let index = 0;
+
+ function updateETA() {
+ if (timePerOp.length > 5) {
+ process.stdout.write("(" + timeToString((list.length - index) * (timePerOp.reduce((a, b) => a + b) / timePerOp.length)) + ")");
+ } else {
+ process.stdout.write("");
+ }
+ }
+
+ for (let file of list) {
+ let start = new Date().getTime();
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(file);
+ updateETA();
let id = uuid();
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Gathering metadata...");
+ updateETA();
let metadata = JSON.parse(cp.execFileSync("ffprobe", ["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file]).toString());
+ if (!metadata['format']['tags']) continue;
songs[id] = {
- title: substitute(metadata['format']['tags']['TITLE'] ?? path.basename(file, ".flac")),
+ title: substitute(metadata['format']['tags']['TITLE'] ?? metadata['format']['tags']['title'] ?? path.basename(file, ".flac")),
length: parseInt(metadata['format']['duration']),
- album: substitute(metadata['format']['tags']['ALBUM'] ?? "Unknown album"),
- artist: substitute(metadata['format']['tags']['ARTIST'] ?? "Unknown artist"),
- albumArtist: substitute(metadata['format']['tags']['album_artist'] ?? metadata['format']['tags']['ARTIST'] ?? "Unknown artist"),
- date: parseInt(metadata['format']['tags']['DATE']) ?? 0,
+ album: substitute(metadata['format']['tags']['ALBUM'] ?? metadata['format']['tags']['album'] ?? "Unknown album"),
+ artist: (substitute(metadata['format']['tags']['ARTIST'] ?? metadata['format']['tags']['artist'] ?? "Unknown artist")).replaceAll(";", ", ").replaceAll(" & ", ", ").replaceAll("&", ", ").replaceAll(", and ", ", "),
+ albumArtist: (substitute(metadata['format']['tags']['album_artist'] ?? metadata['format']['tags']['ARTIST'] ?? metadata['format']['tags']['artist'] ?? "Unknown artist")).replaceAll(";", ", ").replaceAll("&", ", ").replaceAll(", and ", ", "),
+ date: parseInt(((metadata['format']['tags']['DATE'] ?? metadata['format']['tags']['date']).split("-")[0]).substring(0, 4)) ?? 0,
track: parseInt(metadata['format']['tags']['track']) ?? 0,
+ disc: parseInt(metadata['format']['tags']['disc']) ?? 1,
+ copyright: metadata['format']['tags']['COPYRIGHT'] ?? metadata['format']['tags']['copyright'] ?? "",
size: parseInt(metadata['format']['size']),
bitRate: parseInt(metadata['format']['bit_rate']),
bitDepth: parseInt(metadata['streams'][0]['bits_per_raw_sample']),
@@ -75,37 +149,163 @@ function substitute(text) {
channels: parseInt(metadata['streams'][0]['channels']),
}
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Writing songs list...");
+ updateETA();
fs.writeFileSync("../assets/content/songs.json", JSON.stringify(songs));
- cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "-b:a", "256k", "../assets/content/" + id + ".m4a"]);
- cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "../assets/content/" + id + ".flac"]);
- cp.execFileSync("ffmpeg", ["-i", file, "-an", "../assets/content/" + id + ".jpg"]);
+
+ if (fs.existsSync("/opt/mist")) {
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Encoding AAC version...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "-b:a", "256k", "/opt/mist/aac/" + id + ".m4a"], { stdio: "ignore" });
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Encoding FLAC version...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "-c:a", "copy", "/opt/mist/flac/" + id + ".flac"], { stdio: "ignore" });
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Extracting album art...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-an", "/opt/mist/jpeg/" + id + ".jpg"], { stdio: "ignore" });
+ } else {
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Encoding AAC version...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "-b:a", "256k", "../assets/content/" + id + ".m4a"], { stdio: "ignore" });
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Encoding FLAC version...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-map", "0", "-map", "-0:v?", "-c:a", "copy", "../assets/content/" + id + ".flac"], { stdio: "ignore" });
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Extracting album art...");
+ updateETA();
+ cp.execFileSync("ffmpeg", ["-i", file, "-an", "../assets/content/" + id + ".jpg"], { stdio: "ignore" });
+ }
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Removing original file...");
+ updateETA();
fs.unlinkSync(file);
+
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log(" Done: " + id);
+ updateETA();
+
+ timePerOp.push(new Date().getTime() - start);
+ index++;
}
+ process.stdout.clearLine(null); process.stdout.cursorTo(0);
+ console.log("Collecting albums...");
+
for (let song of Object.keys(songs)) {
if (Object.values(albums).filter(i => i.title === songs[song].album).length > 0) {
Object.values(albums).filter(i => i.title === songs[song].album)[0].tracks.push(song);
Object.values(albums).filter(i => i.title === songs[song].album)[0].hiRes = Object.values(albums).filter(i => i.title === songs[song].album)[0].hiRes || songs[song].hiRes;
} else {
let albumID = uuid();
- fs.copyFileSync("../assets/content/" + song + ".jpg", "../assets/content/" + albumID + ".jpg")
+
+ if (fs.existsSync("/opt/mist")) {
+ fs.copyFileSync("/opt/mist/jpeg/" + song + ".jpg", "/opt/mist/jpeg/" + albumID + ".jpg")
+ } else {
+ fs.copyFileSync("../assets/content/" + song + ".jpg", "../assets/content/" + albumID + ".jpg")
+ }
albums[albumID] = {
title: songs[song].album,
artist: songs[song].albumArtist,
date: songs[song].date,
hiRes: songs[song].hiRes,
+ copyright: songs[song].copyright,
tracks: [song]
}
}
}
+ console.log("Cleaning up...");
+
+ for (let songID of Object.keys(songs)) {
+ if (fs.existsSync("/opt/mist")) {
+ if (!fs.existsSync("/opt/mist/flac/" + songID + ".flac") || !fs.existsSync("/opt/mist/aac/" + songID + ".m4a") || !fs.existsSync("/opt/mist/jpeg/" + songID + ".jpg")) {
+ delete songs[songID];
+ }
+ } else {
+ if (!fs.existsSync("../assets/content/" + songID + ".flac") || !fs.existsSync("../assets/content/" + songID + ".m4a") || !fs.existsSync("../assets/content/" + songID + ".jpg")) {
+ delete songs[songID];
+ }
+ }
+ }
+
+ let idList = [...Object.keys(songs), ...Object.keys(albums)];
+
+ if (fs.existsSync("/opt/mist")) {
+ for (let file of fs.readdirSync("/opt/mist/flac")) {
+ if (fs.lstatSync("/opt/mist/flac/" + file).isFile()) {
+ let id = path.basename(file, path.extname(file));
+
+ if (!idList.includes(id) && !file.endsWith(".json")) {
+ fs.unlinkSync("/opt/mist/flac/" + file);
+ if (fs.existsSync("../assets/content/" + file)) fs.unlinkSync("../assets/content/" + file);
+ } else {
+ if (!fs.existsSync("../assets/content/" + file)) fs.symlinkSync("/opt/mist/flac/" + file, "../assets/content/" + file);
+ }
+ }
+ }
+
+ for (let file of fs.readdirSync("/opt/mist/aac")) {
+ if (fs.lstatSync("/opt/mist/aac/" + file).isFile()) {
+ let id = path.basename(file, path.extname(file));
+
+ if (!idList.includes(id) && !file.endsWith(".json")) {
+ fs.unlinkSync("/opt/mist/aac/" + file);
+ if (fs.existsSync("../assets/content/" + file)) fs.unlinkSync("../assets/content/" + file);
+ } else {
+ if (!fs.existsSync("../assets/content/" + file)) fs.symlinkSync("/opt/mist/aac/" + file, "../assets/content/" + file);
+ }
+ }
+ }
+
+ for (let file of fs.readdirSync("/opt/mist/jpeg")) {
+ if (fs.lstatSync("/opt/mist/jpeg/" + file).isFile()) {
+ let id = path.basename(file, path.extname(file));
+
+ if (!idList.includes(id) && !file.endsWith(".json")) {
+ fs.unlinkSync("/opt/mist/jpeg/" + file);
+ if (fs.existsSync("../assets/content/" + file)) fs.unlinkSync("../assets/content/" + file);
+ } else {
+ if (!fs.existsSync("../assets/content/" + file)) fs.symlinkSync("/opt/mist/jpeg/" + file, "../assets/content/" + file);
+ }
+ }
+ }
+ } else {
+ for (let file of fs.readdirSync("../assets/content")) {
+ if (fs.lstatSync("../assets/content/" + file).isFile()) {
+ let id = path.basename(file, path.extname(file));
+
+ if (!idList.includes(id) && !file.endsWith(".json")) {
+ fs.unlinkSync("../assets/content/" + file);
+ }
+ }
+ }
+ }
+
+ console.log("Adding tracks to albums...");
+
for (let albumID of Object.keys(albums)) {
let album = albums[albumID];
- album["tracks"] = album["tracks"].sort((a, b) => {
+ album["tracks"] = [...new Set(album["tracks"])].filter(i => songs[i]).sort((a, b) => {
return songs[a]['track'] - songs[b]['track'];
});
}
+ console.log("Writing metadata...");
+
+ fs.writeFileSync("../assets/content/songs.json", JSON.stringify(songs));
fs.writeFileSync("../assets/content/albums.json", JSON.stringify(albums));
+
+ console.log("Done!");
})() \ No newline at end of file