Browse Source

Доработка загрузки и обработки файлов книг

Book Pauk 6 years ago
parent
commit
568e9c6663
3 changed files with 51 additions and 17 deletions
  1. 25 0
      server/core/BookConverter.js
  2. 4 6
      server/core/FileDecompressor.js
  3. 22 11
      server/core/ReaderWorker.js

+ 25 - 0
server/core/BookConverter.js

@@ -0,0 +1,25 @@
+const fs = require('fs-extra');
+
+class BookConverter {
+    constructor() {
+    }
+
+    async convertToFb2(inputFile, outputFile, fileType, callback) {
+        if (fileType.ext == 'html' || fileType.ext == 'xml') {
+            const data = await fs.readFile(inputFile, 'utf8');
+
+            if (data.indexOf('FictionBook') >= 0) {            
+                await fs.writeFile(outputFile, data);
+                return;
+            }
+
+            //Заглушка
+            await fs.writeFile(outputFile, data);
+            callback(100);
+        } else {
+            throw new Error(`unknown file format: ${fileType.mime}`);
+        }
+    }
+}
+
+module.exports = BookConverter;

+ 4 - 6
server/core/FileDecompressor.js

@@ -1,4 +1,3 @@
-const fs = require('fs-extra');
 const decompress = require('decompress');
 const decompress = require('decompress');
 const FileDetector = require('./FileDetector');
 const FileDetector = require('./FileDetector');
 
 
@@ -17,13 +16,12 @@ class FileDecompressor {
 
 
         let result = filename;
         let result = filename;
         let max = 0;
         let max = 0;
-        if (!files.length) {
+        if (files.length) {
             //ищем файл с максимальным размером
             //ищем файл с максимальным размером
             for (let file of files) {
             for (let file of files) {
-                const stats = await fs.stat(file);
-                if (stats.size > max) {
-                    result = file;
-                    max = stats.size;
+                if (file.data.length > max) {
+                    result = `${outputDir}/${file.path}`;
+                    max = file.data.length;
                 }
                 }
             }
             }
         }
         }

+ 22 - 11
server/core/ReaderWorker.js

@@ -1,7 +1,7 @@
 const workerState = require('./workerState');
 const workerState = require('./workerState');
 const FileDetector = require('./FileDetector');
 const FileDetector = require('./FileDetector');
 const FileDecompressor = require('./FileDecompressor');
 const FileDecompressor = require('./FileDecompressor');
-//const BookParser = require('./BookParser');
+const BookConverter = require('./BookConverter');
 const utils = require('./utils');
 const utils = require('./utils');
 
 
 const fs = require('fs-extra');
 const fs = require('fs-extra');
@@ -15,13 +15,18 @@ class ReaderWorker {
         this.config = Object.assign({}, config);
         this.config = Object.assign({}, config);
         this.config.tempDownloadDir = `${config.tempDir}/download`;
         this.config.tempDownloadDir = `${config.tempDir}/download`;
         fs.ensureDirSync(this.config.tempDownloadDir);
         fs.ensureDirSync(this.config.tempDownloadDir);
+        this.config.tempPublicDir = `${config.publicDir}/tmp`;
+        fs.ensureDirSync(this.config.tempPublicDir);
         this.detector = new FileDetector();
         this.detector = new FileDetector();
         this.decomp = new FileDecompressor();
         this.decomp = new FileDecompressor();
+        this.bookConverter = new BookConverter();
     }
     }
 
 
     async loadBook(url, wState) {
     async loadBook(url, wState) {
         const maxDownloadSize = 10*1024*1024;
         const maxDownloadSize = 10*1024*1024;
         let errMes = '';
         let errMes = '';
+        let decompDir = '';
+        let downloadedFilename = '';
         try {
         try {
             wState.set({state: 'download', step: 1, totalSteps: 3, url});
             wState.set({state: 'download', step: 1, totalSteps: 3, url});
 
 
@@ -38,28 +43,34 @@ class ReaderWorker {
                     d.destroy();
                     d.destroy();
                 }
                 }
             });
             });
-            const downloadedFilename = `${this.config.tempDownloadDir}/${tempFilename}`;
+            downloadedFilename = `${this.config.tempDownloadDir}/${tempFilename}`;
             await pipeline(d, fs.createWriteStream(downloadedFilename));
             await pipeline(d, fs.createWriteStream(downloadedFilename));
 
 
             //decompress
             //decompress
             wState.set({state: 'decompress', step: 2, progress: 0});
             wState.set({state: 'decompress', step: 2, progress: 0});
-            const decompDir = `${this.config.tempDownloadDir}/${decompDirname}`;
+            decompDir = `${this.config.tempDownloadDir}/${decompDirname}`;
             const decompFilename = await this.decomp.decompressFile(downloadedFilename, decompDir);
             const decompFilename = await this.decomp.decompressFile(downloadedFilename, decompDir);
             wState.set({progress: 100});
             wState.set({progress: 100});
             
             
             //parse book
             //parse book
+            wState.set({state: 'parse', step: 3, progress: 0});
             const fileType = await this.detector.detectFile(decompFilename);
             const fileType = await this.detector.detectFile(decompFilename);
-            if (fileType.ext == 'html' || fileType.ext == 'xml') {
-                //parse
-            }
-
-            //clean
-            await fs.remove(decompDir);
-            await fs.remove(downloadedFilename);
+            fileType.url = url;
+            let resultFilename = `${this.config.tempPublicDir}/${tempFilename2}`;
+            await this.bookConverter.convertToFb2(decompFilename, resultFilename, fileType, progress => {
+                wState.set({progress});
+            });
+            wState.set({progress: 100});
 
 
-            wState.finish({step: 3, file: tempFilename, fileType: fileType});
+            wState.finish({file: `/tmp/${tempFilename2}`});
         } catch (e) {
         } catch (e) {
             wState.set({state: 'error', error: (errMes ? errMes : e.message)});
             wState.set({state: 'error', error: (errMes ? errMes : e.message)});
+        } finally {
+            //clean
+            if (decompDir)
+                await fs.remove(decompDir);
+            if (downloadedFilename)
+                await fs.remove(downloadedFilename);
         }
         }
     }
     }