ReaderWorker.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. const workerState = require('./workerState');
  2. const FileDetector = require('./FileDetector');
  3. const FileDecompressor = require('./FileDecompressor');
  4. //const BookParser = require('./BookParser');
  5. const utils = require('./utils');
  6. const fs = require('fs-extra');
  7. const util = require('util');
  8. const stream = require('stream');
  9. const pipeline = util.promisify(stream.pipeline);
  10. const download = require('download');
  11. class ReaderWorker {
  12. constructor(config) {
  13. this.config = Object.assign({}, config);
  14. this.config.tempDownloadDir = `${config.tempDir}/download`;
  15. fs.ensureDirSync(this.config.tempDownloadDir);
  16. this.detector = new FileDetector();
  17. this.decomp = new FileDecompressor();
  18. }
  19. async loadBook(url, wState) {
  20. const maxDownloadSize = 10*1024*1024;
  21. let errMes = '';
  22. try {
  23. wState.set({state: 'download', step: 1, totalSteps: 3, url});
  24. const tempFilename = utils.randomHexString(30);
  25. const tempFilename2 = utils.randomHexString(30);
  26. const decompDirname = utils.randomHexString(30);
  27. //download
  28. const d = download(url);
  29. d.on('downloadProgress', progress => {
  30. wState.set({progress: Math.round(progress.percent*100)});
  31. if (progress.transferred > maxDownloadSize) {
  32. errMes = 'file too big';
  33. d.destroy();
  34. }
  35. });
  36. const downloadedFilename = `${this.config.tempDownloadDir}/${tempFilename}`;
  37. await pipeline(d, fs.createWriteStream(downloadedFilename));
  38. //decompress
  39. wState.set({state: 'decompress', step: 2, progress: 0});
  40. const decompDir = `${this.config.tempDownloadDir}/${decompDirname}`;
  41. const decompFilename = await this.decomp.decompressFile(downloadedFilename, decompDir);
  42. wState.set({progress: 100});
  43. //parse book
  44. const fileType = await this.detector.detectFile(decompFilename);
  45. if (fileType.ext == 'html' || fileType.ext == 'xml') {
  46. //parse
  47. }
  48. //clean
  49. await fs.remove(decompDir);
  50. await fs.remove(downloadedFilename);
  51. wState.finish({step: 3, file: tempFilename, fileType: fileType});
  52. } catch (e) {
  53. wState.set({state: 'error', error: (errMes ? errMes : e.message)});
  54. }
  55. }
  56. loadBookUrl(url) {
  57. const workerId = workerState.generateWorkerId();
  58. const wState = workerState.getControl(workerId);
  59. wState.set({state: 'start'});
  60. this.loadBook(url, wState);
  61. return workerId;
  62. }
  63. }
  64. module.exports = ReaderWorker;