webamp/experiments/skinArchiveTools/lib/utils.js
2019-03-19 06:55:24 -07:00

121 lines
2.8 KiB
JavaScript

const fsPromises = require("fs").promises;
const path = require("path");
const childProcess = require("child_process");
const JSZip = require("jszip");
const { FILE_TYPES } = require("./constants");
// Reduce an array down to it's unique value given an async hasher function
async function unique(arr, hasher) {
const seen = new Set();
const items = [];
await Promise.all(
arr.map(async item => {
const key = await hasher(item);
if (seen.has(key)) {
return;
}
seen.add(key);
items.push(item);
})
);
return items;
}
function md5File(filePath) {
return new Promise((resolve, reject) => {
childProcess.execFile(`md5`, ["-q", filePath], (err, stdout) => {
if (err) {
// node couldn't execute the command
reject(err);
}
resolve(stdout.trimRight());
});
});
}
function skinWasGenerated(filePath) {
return new Promise(resolve => {
childProcess.execFile(
`zipgrep`,
["This file was created by Skinamp", filePath],
err => {
if (err) {
// node couldn't execute the command
resolve(false);
}
resolve(true);
}
);
});
}
function getArchiveItemName(skin) {
const { filePaths } = skin;
const filename = `${path.parse(filePaths[0]).name}`;
const token = filename.replace(/[^0-9a-zA-Z]+/g, "_");
return `winampskin_${token}`;
}
function getArchiveTitle(skin) {
const { filePaths } = skin;
const filename = `${path.parse(filePaths[0]).name}`;
return `Winamp Skin: ${filename}`;
}
function archive(skin, itemName) {
return new Promise((resolve, reject) => {
const { classicMd5Path, filePaths, screenshotPath } = skin;
const filename = `${path.parse(filePaths[0]).name}`;
childProcess.execFile(
`python`,
[
"/Users/jordaneldredge/projects/ia-skins/sync.py",
classicMd5Path,
screenshotPath,
`${filename}.wsz`,
getArchiveTitle(skin),
itemName,
],
(err, stdout) => {
if (err) {
// node couldn't execute the command
reject(err);
}
resolve(stdout.trimRight());
}
);
});
}
async function skinType(skinPath) {
if (skinPath.endsWith(".wsz")) {
return FILE_TYPES.CLASSIC;
} else if (skinPath.endsWith(".wal")) {
return FILE_TYPES.MODERN;
}
const buffer = await fsPromises.readFile(skinPath);
try {
const zip = await JSZip.loadAsync(buffer);
if (zip.file(/.*\.(wsz|wal|zip)$/i).length) {
// This is a collection of skins
return FILE_TYPES.PACK;
}
const mains = zip.file(/^(.+\/)main\.bmp$/i);
return mains.length === 1 ? FILE_TYPES.CLASSIC : FILE_TYPES.MODERN;
} catch (e) {
return FILE_TYPES.INVALID;
}
}
module.exports = {
unique,
skinType,
skinWasGenerated,
md5File,
archive,
getArchiveItemName,
getArchiveTitle,
};