Jelajahi Sumber

Добавлена расшифровка имен жанров в информации о книге(#24)

Book Pauk 1 tahun lalu
induk
melakukan
a3b83f93c3

+ 22 - 0
client/components/Search/BookInfoDialog/BookInfoDialog.vue

@@ -118,6 +118,7 @@ class BookInfoDialog {
     _props = {
         modelValue: Boolean,
         bookInfo: Object,
+        genreMap: Object,
     };
 
     dialogVisible = false;
@@ -169,6 +170,19 @@ class BookInfoDialog {
         return `${size.toFixed(1)} ${unit}`;
     }
 
+    convertGenres(genreArr) {
+        let result = [];
+        if (genreArr) {
+            for (const genre of genreArr) {
+                const g = genre.trim();
+                const name = this.genreMap.get(g);
+                result.push(name ? name : g);
+            }
+        }
+
+        return result.join(', ');
+    }
+
     get inpx() {
         const mapping = [
             {name: 'fileInfo', label: 'Информация о файле', value: [
@@ -211,6 +225,9 @@ class BookInfoDialog {
             if (nodePath == 'titleInfo/author')
                 return value.split(',').join(', ');
 
+            if (nodePath == 'titleInfo/genre')
+                return this.convertGenres(value.split(','));
+
             if (nodePath == 'titleInfo/librate' && !value)
                 return null;
 
@@ -279,11 +296,16 @@ class BookInfoDialog {
                 }
             }
 
+            const self = this;
             this.fb2 = parser.bookInfoList(infoObj, {
                 valueToString(value, nodePath, origVTS) {//eslint-disable-line no-unused-vars
                     if (nodePath == 'documentInfo/historyHtml' && value)
                         return value.replace(/<p>/g, `<p class="p-history">`);
 
+                    if ((nodePath == 'titleInfo/genre' || nodePath == 'srcTitleInfo/genre') && value) {
+                        return self.convertGenres(value);
+                    }
+
                     return origVTS(value, nodePath);
                 },
             });

+ 1 - 1
client/components/Search/Search.vue

@@ -347,7 +347,7 @@
         <SelectLibRateDialog v-model="selectLibRateDialogVisible" v-model:librate="search.librate" />
         <SelectDateDialog v-model="selectDateDialogVisible" v-model:date="search.date" />
         <SelectExtDialog v-model="selectExtDialogVisible" v-model:ext="search.ext" :ext-list="extList" />        
-        <BookInfoDialog v-model="bookInfoDialogVisible" :book-info="bookInfo" />
+        <BookInfoDialog v-model="bookInfoDialogVisible" :book-info="bookInfo" :genre-map="genreMap" />
         <SelectExtSearchDialog v-model="selectExtSearchDialogVisible" v-model:ext-search="extSearch" />        
     </div>
 </template>

+ 25 - 3
server/core/WebWorker.js

@@ -314,7 +314,7 @@ class WebWorker {
 
         let result;
         const db = this.db;
-        if (!db.wwCache.genres) {
+        if (!db.wwCache.genreTree) {
             const genres = _.cloneDeep(genreTree);
             const last = genres[genres.length - 1];
 
@@ -362,9 +362,31 @@ class WebWorker {
                 inpxHash: (config.inpxHash ? config.inpxHash : ''),
             };
 
-            db.wwCache.genres = result;
+            db.wwCache.genreTree = result;
         } else {
-            result = db.wwCache.genres;
+            result = db.wwCache.genreTree;
+        }
+
+        return result;
+    }
+
+    async getGenreMap() {
+        this.checkMyState();
+
+        let result;
+        const db = this.db;
+        if (!db.wwCache.genreMap) {
+            const genreTree = await this.getGenreTree();
+
+            result = new Map();
+            for (const section of genreTree.genreTree) {
+                for (const g of section.value)
+                    result.set(g.value, g.name);
+            }
+
+            db.wwCache.genreMap = result;
+        } else {
+            result = db.wwCache.genreMap;
         }
 
         return result;

+ 28 - 1
server/core/opds/BookPage.js

@@ -24,6 +24,19 @@ class BookPage extends BasePage {
         return `${size.toFixed(1)} ${unit}`;
     }
 
+    convertGenres(genreArr) {
+        let result = [];
+        if (genreArr) {
+            for (const genre of genreArr) {
+                const g = genre.trim();
+                const name = this.genreMap.get(g);
+                result.push(name ? name : g);
+            }
+        }
+
+        return result.join(', ');
+    }
+
     inpxInfo(bookRec) {
         const mapping = [
             {name: 'fileInfo', label: 'Информация о файле', value: [
@@ -66,6 +79,9 @@ class BookPage extends BasePage {
             if (nodePath == 'titleInfo/author')
                 return value.split(',').join(', ');
 
+            if (nodePath == 'titleInfo/genre')
+                return this.convertGenres(value.split(','));
+
             if (nodePath == 'titleInfo/librate' && !value)
                 return null;
 
@@ -118,6 +134,7 @@ class BookPage extends BasePage {
     async body(req) {
         const result = {};
 
+        this.genreMap = await this.webWorker.getGenreMap();
         result.link = this.baseLinks(req, true);
 
         const bookUid = req.query.uid;
@@ -183,7 +200,17 @@ class BookPage extends BasePage {
                         }
 
                         ann = infoObj.titleInfo.annotationHtml || '';
-                        const infoList = parser.bookInfoList(infoObj);
+                        const self = this;
+                        const infoList = parser.bookInfoList(infoObj, {
+                            valueToString(value, nodePath, origVTS) {//eslint-disable-line no-unused-vars
+                                if ((nodePath == 'titleInfo/genre' || nodePath == 'srcTitleInfo/genre') && value) {
+                                    return self.convertGenres(value);
+                                }
+
+                                return origVTS(value, nodePath);
+                            },
+                        });
+
                         info += this.htmlInfo('Fb2 инфо', infoList);
                     }
                 }