firmament-vita
Version:
Firmament module for automating VITA tasks
184 lines (173 loc) • 5.98 kB
text/typescript
import {injectable, inject} from 'inversify';
import {VitaFileUtil} from "../interfaces/vita-file-util";
import {
FindFilesOptions, UnZipFileResult, UnZipFileOptions, UnZipFileStatus, CopyFileResult
} from "../interfaces/vita-options-results";
import {ForceErrorImpl, CommandUtil} from "firmament-yargs";
import {VitaSpawn} from "../interfaces/vita-spawn";
const fs = require('fs');
const find = require('find');
const path = require('path');
const async = require('async');
const mkdirp = require('mkdirp');
()
export class VitaFileUtilImpl extends ForceErrorImpl implements VitaFileUtil {
constructor(('VitaSpawn')private vitaSpawn: VitaSpawn,
('CommandUtil')private commandUtil: CommandUtil) {
super();
}
findFilesSync(options: FindFilesOptions) {
try {
options.pattern = options.pattern || /.*/;
options.files = options.files || [];
options.folders = options.folders || [process.cwd()];
options.folders.forEach(folder => {
try {
options.files = options.files.concat(find.fileSync(options.pattern, folder));
} catch (err) {
}
});
} catch (err) {
}
return options.files;
}
findFiles(options: FindFilesOptions,
cb: (err: Error,
files?: string[])=>void) {
this.checkCallback(cb)(null, this.findFilesSync(options));
}
unZipFiles(options: UnZipFileOptions,
cbStatus: (err: Error, unZipFileStatus: UnZipFileStatus)=>void,
cbFinal: (err: Error, unZipFileResults?: UnZipFileResult[])=>void) {
cbStatus = this.checkCallback(cbStatus);
cbFinal = this.checkCallback(cbFinal);
options.deleteOriginalZipFile = options.deleteOriginalZipFile || false;
options.zippedFiles = options.zippedFiles || [];
options.targetFolder = options.targetFolder || '';
options.foldersOfZippedFiles = options.foldersOfZippedFiles || [];
options.zippedFiles = this.findFilesSync({
pattern: /\.gz$/,
files: options.zippedFiles,
folders: options.foldersOfZippedFiles
});
if (options.targetFolder) {
try {
mkdirp.sync(options.targetFolder);
} catch (err) {
cbFinal(err);
return;
}
}
let fnArray = [];
options.zippedFiles.forEach(inFile => {
//We know all filenames end in '.gz' because of our search pattern. Remove
//last 3 characters for uncompressed filename.
let outFile = inFile.slice(0, -3);
if (options.targetFolder) {
outFile = path.resolve(options.targetFolder, path.basename(outFile));
}
fnArray.push(async.apply(this.spawnUnZipOperation.bind(this),
inFile,
outFile,
options.deleteOriginalZipFile,
cbStatus));
});
async.parallelLimit(fnArray, 3, (err, results) => {
cbFinal(err, results);
});
}
deleteFile(file: string) {
fs.unlink(file);
}
deleteFiles(files: string[]) {
files.forEach(file => {
try {
this.deleteFile(file);
this.commandUtil.log(`Deleting: ${file}`);
} catch (err) {
this.commandUtil.error(err.toString());
}
});
}
copyFile(inFile: string,
outFile: string,
cb: (err: Error, copyFileResult: CopyFileResult)=>void) {
let rd = fs.createReadStream(inFile);
rd.on("error", function (err) {
done(err);
});
let wr = fs.createWriteStream(outFile);
wr.on("error", function (err) {
done(err);
});
wr.on("close", function (err) {
done(err);
});
rd.pipe(wr);
function done(err) {
if (cb) {
cb(null, {error: err, inFile, outFile});
cb = null;
}
}
}
private spawnUnZipOperation(inFile: string,
outFile: string,
deleteZipFile: boolean,
cbStatus: (err: Error, unZipFileStatus: UnZipFileStatus)=>void,
cbFinal: (err: Error, unZipFileResult: UnZipFileResult)=>void) {
let testResult = '';
this.vitaSpawn.spawnIt(
'gunzip', ['--test', inFile],
(err: Error, result: any) => {
},
(err: Error, result: any) => {
if (err) {
cbFinal(null, {error: err, zippedFilePath: inFile});
return;
}
let listResult = '';
this.vitaSpawn.spawnIt(
'gunzip', ['--list', inFile],
(err: Error, result: Uint8Array) => {
listResult += result.toString();
},
(err: Error, result: any) => {
if (err) {
cbFinal(null, {error: err, zippedFilePath: inFile});
return;
}
//SuperHACK to get the uncompressed file size from 'gunzip --list'
let re = /(\d+)/g;
let r = re.exec(listResult);
let totalBytes = parseInt(r[1]);//uncompressed file size (bytes)
let bytesWritten = 0;
let writeFileStream = fs.createWriteStream(outFile);
this.vitaSpawn.spawnIt(
'gunzip', ['--stdout', inFile],
(err: Error, result: Uint8Array) => {
bytesWritten += result.length;
let taskName = `UnZipping ${path.basename(outFile)}`;
let current = bytesWritten;
let total = totalBytes;
cbStatus(null, {taskName, current, total});
writeFileStream.write(result);
},
(err: Error, result: any) => {
writeFileStream.close();
if (err) {
cbFinal(null, {error: err, zippedFilePath: inFile});
return;
}
if (deleteZipFile) {
this.deleteFile(inFile);
}
cbFinal(err, {unzippedFilePath: outFile, zippedFilePath: inFile});
}
);
}
);
}
);
}
}