Fb2Parser.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const fs = require('fs-extra');
  2. const iconv = require('iconv-lite');
  3. const textUtils = require('./textUtils');
  4. const XmlParser = require('./XmlParser');
  5. const utils = require('../utils');
  6. class Fb2Parser {
  7. checkEncoding(data) {
  8. //Корректируем кодировку UTF-16
  9. let encoding = textUtils.getEncoding(data);
  10. if (encoding.indexOf('UTF-16') == 0) {
  11. data = Buffer.from(iconv.decode(data, encoding));
  12. encoding = 'utf-8';
  13. }
  14. //Корректируем пробелы, всякие файлы попадаются :(
  15. if (data[0] == 32) {
  16. data = Buffer.from(data.toString().trim());
  17. }
  18. //Окончательно корректируем кодировку
  19. let result = data;
  20. let left = data.indexOf('<?xml version="1.0"');
  21. if (left < 0) {
  22. left = data.indexOf('<?xml version=\'1.0\'');
  23. }
  24. if (left >= 0) {
  25. const right = data.indexOf('?>', left);
  26. if (right >= 0) {
  27. const head = data.slice(left, right + 2).toString();
  28. const m = head.match(/encoding=['"](.*?)['"]/);
  29. if (m) {
  30. let enc = m[1].toLowerCase();
  31. if (enc != 'utf-8') {
  32. //enc может не соответсвовать реальной кодировке файла, поэтому:
  33. if (encoding.indexOf('ISO-8859') >= 0) {
  34. encoding = enc;
  35. }
  36. result = iconv.decode(data, encoding);
  37. result = Buffer.from(result.toString().replace(m[0], `encoding="utf-8"`));
  38. }
  39. }
  40. }
  41. }
  42. return result;
  43. }
  44. async getDescAndCover(bookFile) {
  45. let data = await fs.readFile(bookFile);
  46. data = await utils.gunzipBuffer(data);
  47. data = this.checkEncoding(data);
  48. const xml = new XmlParser();
  49. xml.fromString(data.toString(), {
  50. lowerCase: true,
  51. pickNode: route => route.indexOf('fictionbook/body') !== 0,
  52. });
  53. let cover = null;
  54. //console.log(xml.toString());
  55. //xml.each(node => console.log(node.name));
  56. const desc = xml.$$('description').toObject();
  57. return {desc, cover};
  58. }
  59. }
  60. module.exports = Fb2Parser;