瀏覽代碼

Поправки распознавания кодировки fb2-файла

Book Pauk 4 年之前
父節點
當前提交
dbb1bfe587
共有 1 個文件被更改,包括 27 次插入6 次删除
  1. 27 6
      server/core/Reader/BookConverter/ConvertFb2.js

+ 27 - 6
server/core/Reader/BookConverter/ConvertFb2.js

@@ -1,5 +1,6 @@
 const ConvertBase = require('./ConvertBase');
 const iconv = require('iconv-lite');
+const textUtils = require('./textUtils');
 
 class ConvertFb2 extends ConvertBase {
     check(data, opts) {
@@ -9,26 +10,46 @@ class ConvertFb2 extends ConvertBase {
     }
 
     async run(data, opts) {
-        if (!this.check(data, opts))
+        let newData = data;
+
+        //Корректируем кодировку, 16-битные кодировки должны стать utf-8
+        const encoding = textUtils.getEncoding(newData);
+        if (encoding.indexOf('UTF-16') == 0) {
+            newData = Buffer.from(iconv.decode(newData, encoding));
+        }
+
+        if (!this.check(newData, opts))
             return false;
 
-        return this.checkEncoding(data);
+        return this.checkEncoding(newData);
     }
 
     checkEncoding(data) {
         let result = data;
 
-        const left = data.indexOf('<?xml version="1.0"');
+        let q = '"';
+        let left = data.indexOf('<?xml version="1.0"');
+        if (left < 0) {
+            left = data.indexOf('<?xml version=\'1.0\'');
+            q = '\'';
+        }
+
         if (left >= 0) {
             const right = data.indexOf('?>', left);
             if (right >= 0) {
                 const head = data.slice(left, right + 2).toString();
-                const m = head.match(/encoding="(.*?)"/);
+                const m = head.match(/encoding=['"](.*?)['"]/);
                 if (m) {
                     let encoding = m[1].toLowerCase();
                     if (encoding != 'utf-8') {
-                        result = iconv.decode(data, encoding);
-                        result = Buffer.from(result.toString().replace(m[0], 'encoding="utf-8"'));
+                        //encoding может не соответсвовать реальной кодировке файла, поэтому:
+                        let calcEncoding = textUtils.getEncoding(data);
+                        if (calcEncoding.indexOf('ISO-8859') >= 0) {
+                            calcEncoding = encoding;
+                        }
+
+                        result = iconv.decode(data, calcEncoding);
+                        result = Buffer.from(result.toString().replace(m[0], `encoding=${q}utf-8${q}`));
                     }
                 }
             }