Добавлена поддержка rar-архивов с помощью внешнего архиватора

This commit is contained in:
Book Pauk
2020-12-02 23:56:17 +07:00
parent 0124c2b17d
commit 2f82b0db34
3 changed files with 71 additions and 5 deletions

View File

@@ -15,6 +15,13 @@ class FileDecompressor {
constructor(limitFileSize = 0) {
this.detector = new FileDetector();
this.limitFileSize = limitFileSize;
this.rarPath = '/usr/bin/rar';
this.rarExists = false;
(async() => {
if (await fs.pathExists(this.rarPath))
this.rarExists = true;
})();
}
async decompressNested(filename, outputDir) {
@@ -30,7 +37,11 @@ class FileDecompressor {
files: []
};
if (!fileType || !(fileType.ext == 'zip' || fileType.ext == 'bz2' || fileType.ext == 'gz' || fileType.ext == 'tar')) {
if (!fileType || !(
fileType.ext == 'zip' || fileType.ext == 'bz2' || fileType.ext == 'gz'
|| fileType.ext == 'tar' || (this.rarExists && fileType.ext == 'rar')
)
) {
return result;
}
@@ -94,6 +105,11 @@ class FileDecompressor {
async decompress(fileExt, filename, outputDir) {
let files = [];
if (fileExt == 'rar' && this.rarExists) {
files = await this.unRar(filename, outputDir);
return files;
}
switch (fileExt) {
case 'zip':
files = await this.unZip(filename, outputDir);
@@ -123,8 +139,7 @@ class FileDecompressor {
decodeEntryNameCallback: (nameRaw) => {
return utils.bufferRemoveZeroes(nameRaw);
}
}
);
});
} catch (e) {
fs.emptyDir(outputDir);
return await zip.unpack(filename, outputDir, {
@@ -222,7 +237,39 @@ class FileDecompressor {
inputStream.pipe(stream).pipe(outputStream);
})().catch(reject); });
}
}
async unRar(filename, outputDir) {
try {
const args = ['e', '-y', filename, `${outputDir}/`];
const result = await utils.spawnProcess(this.rarPath, {
killAfter: 60,
args
});
if (result.code == 0) {
const files = [];
await utils.findFiles(async(file) => {
const stat = await fs.stat(file);
files.push({path: path.relative(outputDir, file), size: stat.size});
}, outputDir);
return files;
} else {
const error = `${result.code}|FORLOG|, exec: ${this.rarPath}, args: ${args.join(' ')}, stdout: ${result.stdout}, stderr: ${result.stderr}`;
throw new Error(`Архиватор Rar завершился с ошибкой: ${error}`);
}
} catch(e) {
if (e.status == 'killed') {
throw new Error('Слишком долгое ожидание архиватора Rar');
} else if (e.status == 'error') {
throw new Error(e.error);
} else {
throw new Error(e);
}
}
}
async gzipBuffer(buf) {
return new Promise((resolve, reject) => {