Улучшение работы с inpx: теперь понимает zip-архивы, вложенные в каталоги

Улучшение работы с zip-файлами: теперь понимает кодировку cp866
This commit is contained in:
Book Pauk
2023-04-25 16:08:47 +07:00
parent b0edc3561e
commit 76fc64c1b7

View File

@@ -2,6 +2,7 @@ const os = require('os');
const path = require('path'); const path = require('path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const _ = require('lodash'); const _ = require('lodash');
const iconv = require('iconv-lite');
const ZipReader = require('./ZipReader'); const ZipReader = require('./ZipReader');
const WorkerState = require('./WorkerState');//singleton const WorkerState = require('./WorkerState');//singleton
@@ -369,15 +370,14 @@ class WebWorker {
return result; return result;
} }
async extractBook(bookPath) { async extractBook(libFolder, libFile) {
const outFile = `${this.config.tempDir}/${utils.randomHexString(30)}`; const outFile = `${this.config.tempDir}/${utils.randomHexString(30)}`;
bookPath = bookPath.replace(/\\/g, '/').replace(/\/\//g, '/'); libFolder = libFolder.replace(/\\/g, '/').replace(/\/\//g, '/');
const i = bookPath.indexOf('/');
const folder = `${this.config.libDir}/${(i >= 0 ? bookPath.substring(0, i) : bookPath )}`;
const file = (i >= 0 ? bookPath.substring(i + 1) : '' );
const folder = `${this.config.libDir}/${libFolder}`;
const file = libFile;
const fullPath = `${folder}/${file}`; const fullPath = `${folder}/${file}`;
if (!file || await fs.pathExists(fullPath)) {// файл есть на диске if (!file || await fs.pathExists(fullPath)) {// файл есть на диске
@@ -390,6 +390,11 @@ class WebWorker {
try { try {
await zipReader.extractToFile(file, outFile); await zipReader.extractToFile(file, outFile);
if (!await fs.pathExists(outFile)) {//не удалось найти в архиве, попробуем имя файла в кодировке cp866
await zipReader.extractToFile(iconv.encode(file, 'cp866').toString(), outFile);
}
return outFile; return outFile;
} finally { } finally {
await zipReader.close(); await zipReader.close();
@@ -397,14 +402,14 @@ class WebWorker {
} }
} }
async restoreBook(bookUid, bookPath, downFileName) { async restoreBook(bookUid, libFolder, libFile, downFileName) {
const db = this.db; const db = this.db;
let extractedFile = ''; let extractedFile = '';
let hash = ''; let hash = '';
if (!this.remoteLib) { if (!this.remoteLib) {
extractedFile = await this.extractBook(bookPath); extractedFile = await this.extractBook(libFolder, libFile);
hash = await utils.getFileHash(extractedFile, 'sha256', 'hex'); hash = await utils.getFileHash(extractedFile, 'sha256', 'hex');
} else { } else {
hash = await this.remoteLib.downloadBook(bookUid); hash = await this.remoteLib.downloadBook(bookUid);
@@ -424,7 +429,7 @@ class WebWorker {
await utils.touchFile(bookFile); await utils.touchFile(bookFile);
} }
await fs.writeFile(bookFileDesc, JSON.stringify({bookPath, downFileName})); await fs.writeFile(bookFileDesc, JSON.stringify({libFolder, libFile, downFileName}));
} else { } else {
if (extractedFile) if (extractedFile)
await fs.remove(extractedFile); await fs.remove(extractedFile);
@@ -437,8 +442,7 @@ class WebWorker {
table: 'file_hash', table: 'file_hash',
replace: true, replace: true,
rows: [ rows: [
{id: bookPath, hash}, {id: bookUid, hash},
{id: hash, bookPath, downFileName}
] ]
}); });
@@ -452,7 +456,7 @@ class WebWorker {
const db = this.db; const db = this.db;
let link = ''; let link = '';
//найдем downFileName и bookPath //найдем downFileName, libFolder, libFile
let rows = await db.select({table: 'book', where: `@@hash('_uid', ${db.esc(bookUid)})`}); let rows = await db.select({table: 'book', where: `@@hash('_uid', ${db.esc(bookUid)})`});
if (!rows.length) if (!rows.length)
throw new Error('404 Файл не найден'); throw new Error('404 Файл не найден');
@@ -479,11 +483,12 @@ class WebWorker {
if (downFileName.substring(downFileName.length - ext.length) != ext) if (downFileName.substring(downFileName.length - ext.length) != ext)
downFileName += ext; downFileName += ext;
const bookPath = `${book.folder}/${book.file}${ext}`; const libFolder = book.folder;
const libFile = `${book.file}${ext}`;
//найдем хеш //найдем хеш
rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookPath)})`}); rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookUid)})`});
if (rows.length) {//хеш найден по bookPath if (rows.length) {//хеш найден по bookUid
const hash = rows[0].hash; const hash = rows[0].hash;
const bookFile = `${this.config.bookDir}/${hash}`; const bookFile = `${this.config.bookDir}/${hash}`;
const bookFileDesc = `${bookFile}.d.json`; const bookFileDesc = `${bookFile}.d.json`;
@@ -494,13 +499,13 @@ class WebWorker {
} }
if (!link) { if (!link) {
link = await this.restoreBook(bookUid, bookPath, downFileName) link = await this.restoreBook(bookUid, libFolder, libFile, downFileName);
} }
if (!link) if (!link)
throw new Error('404 Файл не найден'); throw new Error('404 Файл не найден');
return {link, bookPath, downFileName}; return {link, libFolder, libFile, downFileName};
} catch(e) { } catch(e) {
log(LM_ERR, `getBookLink error: ${e.message}`); log(LM_ERR, `getBookLink error: ${e.message}`);
if (e.message.indexOf('ENOENT') >= 0) if (e.message.indexOf('ENOENT') >= 0)