ReaderWorker.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. const fs = require('fs-extra');
  2. const path = require('path');
  3. const workerState = require('./workerState');
  4. const FileDownloader = require('./FileDownloader');
  5. const FileDecompressor = require('./FileDecompressor');
  6. const BookConverter = require('./BookConverter');
  7. const utils = require('./utils');
  8. class ReaderWorker {
  9. constructor(config) {
  10. this.config = Object.assign({}, config);
  11. this.config.tempDownloadDir = `${config.tempDir}/download`;
  12. fs.ensureDirSync(this.config.tempDownloadDir);
  13. this.config.tempPublicDir = `${config.publicDir}/tmp`;
  14. fs.ensureDirSync(this.config.tempPublicDir);
  15. this.down = new FileDownloader();
  16. this.decomp = new FileDecompressor();
  17. this.bookConverter = new BookConverter();
  18. }
  19. async loadBook(url, wState) {
  20. let errMes = '';
  21. let decompDir = '';
  22. let downloadedFilename = '';
  23. let convertFilename = '';
  24. try {
  25. wState.set({state: 'download', step: 1, totalSteps: 3, url});
  26. const tempFilename = utils.randomHexString(30);
  27. const tempFilename2 = utils.randomHexString(30);
  28. const decompDirname = utils.randomHexString(30);
  29. //download
  30. const downdata = await this.down.load(url, (progress) => {
  31. wState.set({progress});
  32. });
  33. downloadedFilename = `${this.config.tempDownloadDir}/${tempFilename}`;
  34. await fs.writeFile(downloadedFilename, downdata);
  35. wState.set({progress: 100});
  36. //decompress
  37. wState.set({state: 'decompress', step: 2, progress: 0});
  38. decompDir = `${this.config.tempDownloadDir}/${decompDirname}`;
  39. const decompFilename = await this.decomp.decompressFile(downloadedFilename, decompDir);
  40. wState.set({progress: 100});
  41. //parse book
  42. wState.set({state: 'convert', step: 3, progress: 0});
  43. convertFilename = `${this.config.tempDownloadDir}/${tempFilename2}`;
  44. await this.bookConverter.convertToFb2(decompFilename, convertFilename, url, progress => {
  45. wState.set({progress});
  46. });
  47. //compress file to tmp dir, if not exists with the same hashname
  48. const compFilename = await this.decomp.gzipFileIfNotExists(convertFilename, `${this.config.tempPublicDir}`);
  49. wState.set({progress: 100});
  50. //finish
  51. const finishFilename = path.basename(compFilename);
  52. wState.finish({path: `/tmp/${finishFilename}`});
  53. } catch (e) {
  54. wState.set({state: 'error', error: (errMes ? errMes : e.message)});
  55. } finally {
  56. //clean
  57. if (decompDir)
  58. await fs.remove(decompDir);
  59. if (downloadedFilename)
  60. await fs.remove(downloadedFilename);
  61. if (convertFilename)
  62. await fs.remove(convertFilename);
  63. }
  64. }
  65. loadBookUrl(url) {
  66. const workerId = workerState.generateWorkerId();
  67. const wState = workerState.getControl(workerId);
  68. wState.set({state: 'start'});
  69. this.loadBook(url, wState);
  70. return workerId;
  71. }
  72. }
  73. module.exports = ReaderWorker;