Skip to content

Commit

Permalink
Better error-proofing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Landerson352 committed Jan 13, 2019
1 parent 9a170bd commit 15f8947
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 64 deletions.
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -5,11 +5,13 @@
"main": "single-saberize.js",
"scripts": {
"build": "pkg single-saberize.js --targets=win --out-path=dist",
"process": "node single-saberize.js --path=../CustomSongs"
"test": "node single-saberize.js --path=../CustomSongs",
"debug": "node single-saberize.js --path=../CustomSongs --log=verbose"
},
"author": "Lincoln Anderson",
"license": "MIT",
"dependencies": {
"chalk": "^2.4.2",
"lodash": "^4.17.11",
"ncp": "^2.0.0",
"pkg": "^4.3.7",
Expand Down
166 changes: 104 additions & 62 deletions single-saberize.js
@@ -1,4 +1,6 @@
const chalk = require('chalk');
const each = require('lodash/each');
const isEmpty = require('lodash/isEmpty');
const filter = require('lodash/filter');
const fs = require('fs');
const ncp = require('ncp').ncp;
Expand All @@ -10,6 +12,8 @@ const argv = require('yargs').argv;
const DUPLICATED_FOLDER_PREFIX = '__SingleSaber__ ';
const SONG_FOLDER = argv.path || path.join(path.dirname(process.execPath), 'CustomSongs');

let songCount = 0;

// const OPPOSING_DIRECTIONS = [
// 1,
// 0,
Expand All @@ -21,21 +25,42 @@ const SONG_FOLDER = argv.path || path.join(path.dirname(process.execPath), 'Cust
// 5,
// ];

const isDirectory = source => fs.lstatSync(source).isDirectory()
const getDirectories = source =>
fs.readdirSync(source).map(name => path.join(source, name)).filter(isDirectory)

const debug = (message) => {
// if(argv.log === 'verbose') {
console.log(chalk.gray(message));
// }
};
const success = (message) => {
// if(argv.log === 'verbose') {
console.log(chalk.blue(message));
// }
};
const error = (message) => {
// if(argv.log === 'verbose') {
console.log(chalk.red(message));
// }
};

const processSongsInFolder = (folder) => {
fs.readdir(folder, function(err, items) {
const songFolders = filter(items, function(item) {
return !startsWith(item, '.') && !startsWith(item, DUPLICATED_FOLDER_PREFIX);
});
console.log(`Processing ${songFolders.length} custom songs...`);
songCount = songFolders.length;
debug(`Processing ${songFolders.length} custom songs...`);
each(songFolders, (item) => {
if(!startsWith(item, '.') && !startsWith(item, DUPLICATED_FOLDER_PREFIX)) {
const newSongFolder = `${DUPLICATED_FOLDER_PREFIX}${item}`;
const newSongFolderPath = path.join(folder, newSongFolder);
ncp(path.join(folder, item), newSongFolderPath, function (err) {
if (err) {
return console.error(err);
return error(err);
}
console.log(`Created "${newSongFolder}"...`);
debug(`Created "${newSongFolder}"...`);
//TODO: Find better way to proceed once files are done copying
setTimeout(() => {
processSongFolder(newSongFolderPath);
Expand All @@ -44,46 +69,55 @@ const processSongsInFolder = (folder) => {
}
});
});
setInterval(() => {}, 10000); // keep window open
setTimeout(() => {
console.log(chalk.green('You may close this window or copy the log to report any errors to the single-saberizer developer.'));
}, 2000);
};

const processSongFolder = (folder) => {
const infoFilePath = path.join(folder, 'info.json');
if(fs.existsSync(infoFilePath)) {
console.log(`Found "info.json" in "${folder}".`);
debug(`Found "info.json" in "${folder}".`);
processSongDataFile(infoFilePath, folder);
} else {
// recursion
console.log(`Did not find "info.json" in "${folder}", searching subdirectories...`);
fs.readdir(folder, function (err, items) {
// console.log(items);
each(items, (item) => {
processSongFolder(path.join(folder, item));
});
debug(`Did not find "info.json" in "${folder}", searching subdirectories...`);
const items = getDirectories(folder);
each(items, (item) => {
processSongFolder(item);
});
}
};

// Open and parse the info file.
const processSongDataFile = (infoFilePath, folder) => {
let rawData;
let rawData, infoObject;
try {
rawData = fs.readFileSync(infoFilePath);
}
catch(err) {
console.log('Error reading "info.json". Aborting conversion.');
console.log(err);
error('Error reading "info.json". Aborting conversion.');
debug(err);
}

if(rawData) {
try {
const infoObject = JSON.parse(rawData);
// TODO: Skip songs that are already oneSaber
modifyInfo(infoFilePath, infoObject, folder)
infoObject = JSON.parse(rawData);
}
catch(err) {
console.log('Error parsing "info.json". Aborting conversion.');
console.log(err);
console.log(rawData);
error(`Error parsing "${infoFilePath}. Aborting conversion.`);
debug(err);
debug(rawData);
}

// Skip songs that are already oneSaber
if(infoObject) {
if(infoObject.oneSaber) {
debug(`Existing single-saber track at "${infoFilePath}". Aborting conversion.`);
} else {
modifyInfo(infoFilePath, infoObject, folder);
}
}
}
};
Expand All @@ -95,12 +129,12 @@ const modifyInfo = (infoFilePath, infoObject, folder) => {
try {
let rawData = JSON.stringify(infoObject);
fs.writeFileSync(infoFilePath, rawData);
console.log(`Updated "${infoFilePath}".`);
processDifficultyLevels(infoObject.difficultyLevels, folder);
success(`Updated "${infoFilePath}". Processing songs...`);
processDifficultyLevels(infoObject.difficultyLevels, folder, infoObject);;
}
catch(err) {
console.log('Error writing "info.json". Aborting conversion.');
console.log(err);
error('Error writing "info.json". Aborting conversion.');
debug(err);
}
};

Expand All @@ -112,68 +146,76 @@ const modifyInfo = (infoFilePath, infoObject, folder) => {
// offset: -570,
// oldOffset: -570 }

const processDifficultyLevels = (levels, folder) => {
const processDifficultyLevels = (levels, folder, infoObject) => {
each(levels, ({ difficulty, jsonPath }) => {
const levelFilePath = path.join(folder, jsonPath);
processDifficultyLevel(levelFilePath, difficulty);
if(fs.existsSync(levelFilePath)) {
processDifficultyLevel(levelFilePath, difficulty, infoObject);
} else {
error(`Did not find "${levelFilePath}". Aborting conversion.`);
}
});
};

const processDifficultyLevel = (levelFilePath, difficulty) => {
const processDifficultyLevel = (levelFilePath, difficulty, infoObject) => {
let rawData;
try {
// console.log(`Loading "${levelFilePath}".`);
// debug(`Loading "${levelFilePath}".`);
rawData = fs.readFileSync(levelFilePath);
}
catch(err) {
console.log(`Error reading "${levelFilePath}". Aborting conversion.`);
console.log(err);
error(`Error reading "${levelFilePath}". Aborting conversion.`);
debug(err);
}

if(rawData) {
try {
const levelObject = JSON.parse(rawData);
updateDifficultyLevel(levelFilePath, levelObject, difficulty);
updateDifficultyLevel(levelFilePath, levelObject, difficulty, infoObject);
}
catch(err) {
console.log(`Error parsing "${levelFilePath}". Aborting conversion.`);
console.log(err);
console.log(rawData);
error(`Error parsing "${levelFilePath}". Aborting conversion.`);
debug(err);
debug(rawData);
}
}
};

const updateDifficultyLevel = (levelFilePath, levelObject, difficulty) => {
const updateDifficultyLevel = (levelFilePath, levelObject, difficulty, { beatsPerMinute }) => {
const notes = [];
let lastNote = { _time: 0 }, possibleRedConversion;
const _notes = sortBy(levelObject._notes, ['_time']);
each(_notes, (note) => {
// console.log(note._cutDirection);
if(possibleRedConversion) {
const timeElapsed2 = Math.abs(possibleRedConversion._time - note._time);
if(timeElapsed2 > 0.25) { //threshold
// flip the note for flow
// if(!lastNote || lastNote._cutDirection === note._cutDirection) {
// possibleRedConversion._cutDirection = OPPOSING_DIRECTIONS[note._cutDirection];
// }
notes.push(possibleRedConversion);
lastNote = possibleRedConversion;
possibleRedConversion = null;
// debug(note._cutDirection);
if(note._type > 1) { // auto allow mines or whatever
notes.push(note);
} else {
if (possibleRedConversion) {
const timeElapsed2 = Math.abs(possibleRedConversion._time - note._time);
if (beatsPerMinute / timeElapsed2 < 240) { //threshold
// flip the note for flow
// if(!lastNote || lastNote._cutDirection === note._cutDirection) {
// possibleRedConversion._cutDirection = OPPOSING_DIRECTIONS[note._cutDirection];
// }
notes.push(possibleRedConversion);
lastNote = possibleRedConversion;
possibleRedConversion = null;
}
}
}
if(!possibleRedConversion && note._type === 0) { // maybe make "red/left" into "blue/right" saber notes
const timeElapsed = Math.abs(lastNote._time - note._time);
if(timeElapsed > 0.25) { // threshold
possibleRedConversion = {
...note,
_type: 1,
};
if (!possibleRedConversion && note._type === 0) { // maybe make "red/left" into "blue/right" saber notes
const timeElapsed = Math.abs(lastNote._time - note._time);
if (beatsPerMinute / timeElapsed < 240) { // threshold
possibleRedConversion = {
...note,
_type: 1,
};
}
}
if (note._type === 1) { // auto allow "blue/right" saber notes
notes.push(note);
lastNote = note;
possibleRedConversion = null;
}
}
if(note._type === 1) { // auto allow "blue/right" saber notes
notes.push(note);
lastNote = note;
possibleRedConversion = null;
}
});
levelObject._notes = notes;
Expand All @@ -193,12 +235,12 @@ const writeDifficultyLevel = (levelFilePath, levelObject) => {
try {
let rawData = JSON.stringify(levelObject);
fs.writeFileSync(levelFilePath, rawData);
console.log(`Updated "${levelFilePath}".`);
success(`Updated "${levelFilePath}".`);
}
catch(err) {
console.log(`Error writing "${levelFilePath}". Aborting conversion.`);
console.log(err);
error(`Error writing "${levelFilePath}". Aborting conversion.`);
debug(err);
}
};

processSongsInFolder(SONG_FOLDER);
processSongsInFolder(path.resolve(SONG_FOLDER));
2 changes: 1 addition & 1 deletion yarn.lock
Expand Up @@ -213,7 +213,7 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=

chalk@2.4.2, chalk@~2.4.1:
chalk@2.4.2, chalk@^2.4.2, chalk@~2.4.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
Expand Down

0 comments on commit 15f8947

Please sign in to comment.