1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
const fs = require('fs');
const cp = require('child_process');
const path = require('path');
const crypto = require('crypto');
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()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
}
walk(dir, (err, data) => {
if (err) {
rej(err);
} else {
res(data);
}
})
});
}
(async () => {
let list = (await scandir("../assets/content/_")).filter(i => i.endsWith(".flac"));
process.stdout.write(" files found\n");
let index = 0;
console.log("Checking for corrupted files...");
for (let file of list) {
process.stdout.cursorTo(0);
process.stdout.write(index + "/" + list.length);
let metadata = JSON.parse(cp.execFileSync("ffprobe", ["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file]).toString());
if (!metadata['format']['tags']) {
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log(file + ": is corrupted or has no metadata");
}
index++;
}
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log("Checking for missing album art...");
index = 0;
for (let id of Object.keys(songs)) {
process.stdout.cursorTo(0);
process.stdout.write(index + "/" + (Object.keys(songs).length + Object.keys(albums).length));
if (fs.existsSync("../assets/content/" + id + ".jpg")) {
if (crypto.createHash("md5").update(fs.readFileSync("../assets/content/" + id + ".jpg")).digest("hex") === "fd89a584ae426e72801f2a4c2653ae7a") {
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log(songs[id].title + " (" + id + "): using placeholder album art");
}
} else {
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log(songs[id].title + " (" + id + "): no album art file");
}
index++;
}
for (let id of Object.keys(albums)) {
process.stdout.cursorTo(0);
process.stdout.write(index + "/" + (Object.keys(songs).length + Object.keys(albums).length));
if (fs.existsSync("../assets/content/" + id + ".jpg")) {
if (crypto.createHash("md5").update(fs.readFileSync("../assets/content/" + id + ".jpg")).digest("hex") === "fd89a584ae426e72801f2a4c2653ae7a") {
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log(albums[id].title + " (" + id + "): using placeholder album art");
}
} else {
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log(albums[id].title + " (" + id + "): no album art file");
}
index++;
}
process.stdout.clearLine(null);
process.stdout.cursorTo(0);
console.log("Done.");
})();
|