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, };