2024-05-15 17:57:16 +00:00
|
|
|
// TODO: Make this concurrent instead of serial
|
|
|
|
|
|
|
|
import { join, extname } from "node:path";
|
|
|
|
import { pipeline } from "node:stream/promises";
|
|
|
|
import { Readable } from "node:stream";
|
|
|
|
import * as ndjson from "ndjson";
|
|
|
|
import { readdir, writeFile, stat } from "node:fs/promises";
|
|
|
|
import { createWriteStream } from "node:fs";
|
2024-05-15 19:17:01 +00:00
|
|
|
import { parseSm } from "../lib/stepcharts/parseSm";
|
|
|
|
import { parseSimfile } from "../lib/stepcharts/parseSimfile";
|
2024-05-15 17:57:16 +00:00
|
|
|
|
|
|
|
const rootDir = process.env.STEPCHARTS_DIR ?? "/tmp/stepcharts";
|
|
|
|
const stepchartsDir = join(rootDir, "prodStepcharts");
|
|
|
|
const outFile = process.env.OUT_FILE ?? "data/stepData.ndjson";
|
|
|
|
|
|
|
|
async function* mixToSongs(
|
|
|
|
mixDirs: string[],
|
|
|
|
): AsyncGenerator<[string, string], void, unknown> {
|
|
|
|
for (const mix of mixDirs) {
|
|
|
|
const mixDir = join(stepchartsDir, mix);
|
|
|
|
const files = await readdir(mixDir);
|
|
|
|
for (const song of files) {
|
|
|
|
yield [mix, song];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function* processSong(gen: AsyncGenerator<[string, string]>) {
|
|
|
|
for await (const [mix, song] of gen) {
|
2024-05-16 01:04:15 +00:00
|
|
|
const totalPath = join(stepchartsDir, mix, song);
|
|
|
|
const meta = await stat(totalPath);
|
|
|
|
if (!meta.isDirectory()) continue;
|
|
|
|
|
2024-05-15 17:57:16 +00:00
|
|
|
try {
|
|
|
|
const parsed = await parseSimfile(stepchartsDir, mix, song);
|
2024-05-16 01:04:15 +00:00
|
|
|
for (const [name, chart] of Object.entries(parsed.charts)) {
|
|
|
|
yield {
|
|
|
|
difficulty: name,
|
|
|
|
artist: parsed.artist,
|
|
|
|
title: parsed.title.titleName,
|
|
|
|
titleRomanized: parsed.title.translitTitleName,
|
|
|
|
bannerFilename: parsed.bannerFilename,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// yield parsed;
|
2024-05-15 17:57:16 +00:00
|
|
|
} catch (e) {
|
|
|
|
console.error("failed on", mix, song, ":", e.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const mixDirs = await readdir(stepchartsDir);
|
|
|
|
const songIter = mixToSongs(mixDirs);
|
|
|
|
const outIter = processSong(songIter);
|
|
|
|
|
|
|
|
const writer = createWriteStream(outFile);
|
|
|
|
for await (const songObj of outIter) {
|
|
|
|
writer.write(JSON.stringify(songObj));
|
|
|
|
writer.write("\n");
|
|
|
|
}
|
2024-05-16 01:04:15 +00:00
|
|
|
|
|
|
|
console.log("Done.");
|