Добавлена поддержка rar-архивов с помощью внешнего архиватора
This commit is contained in:
@@ -34,6 +34,7 @@ sudo -u www-data tar xvf calibre-5.5.0-x86_64.txz -C /home/liberama/data/calibre
|
||||
|
||||
### external converters
|
||||
```
|
||||
sudo apt install rar
|
||||
sudo apt install libreoffice
|
||||
sudo apt install poppler-utils
|
||||
```
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const { spawn } = require('child_process');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const baseX = require('base-x');
|
||||
|
||||
@@ -91,6 +92,22 @@ function spawnProcess(cmd, opts) {
|
||||
})().catch(reject); });
|
||||
}
|
||||
|
||||
async function findFiles(callback, dir) {
|
||||
if (!(callback && dir))
|
||||
return;
|
||||
let result = true;
|
||||
const files = await fs.readdir(dir, { withFileTypes: true });
|
||||
|
||||
for (const file of files) {
|
||||
const found = path.resolve(dir, file.name);
|
||||
if (file.isDirectory())
|
||||
result = await findFiles(callback, found);
|
||||
else
|
||||
await callback(found);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
toBase36,
|
||||
fromBase36,
|
||||
@@ -99,5 +116,6 @@ module.exports = {
|
||||
sleep,
|
||||
randomHexString,
|
||||
touchFile,
|
||||
spawnProcess
|
||||
spawnProcess,
|
||||
findFiles
|
||||
};
|
||||
Reference in New Issue
Block a user