Добавлена возможность фильтрации по авторам при формировании поисковой БД.
Критерии фильтрации должны находиться в файле inpx-web-filter.json
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const InpxParser = require('./InpxParser');
|
||||
const InpxHashCreator = require('./InpxHashCreator');
|
||||
const utils = require('./utils');
|
||||
|
||||
const emptyFieldValue = '?';
|
||||
@@ -8,6 +11,29 @@ class DbCreator {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async loadInpxFilter() {
|
||||
const inpxFilterFile = this.config.inpxFilterFile;
|
||||
|
||||
if (await fs.pathExists(inpxFilterFile)) {
|
||||
let filter = await fs.readFile(inpxFilterFile, 'utf8');
|
||||
filter = JSON.parse(filter);
|
||||
|
||||
if (filter.includeAuthors) {
|
||||
filter.includeAuthors = filter.includeAuthors.map(a => a.toLowerCase());
|
||||
filter.includeSet = new Set(filter.includeAuthors);
|
||||
}
|
||||
|
||||
if (filter.excludeAuthors) {
|
||||
filter.excludeAuthors = filter.excludeAuthors.map(a => a.toLowerCase());
|
||||
filter.excludeSet = new Set(filter.excludeAuthors);
|
||||
}
|
||||
|
||||
return filter;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//процедура формировани БД несколько усложнена, в целях экономии памяти
|
||||
async run(db, callback) {
|
||||
const config = this.config;
|
||||
@@ -44,10 +70,37 @@ class DbCreator {
|
||||
callback({recsLoaded});
|
||||
let chunkNum = 0;
|
||||
|
||||
//фильтр по авторам
|
||||
const inpxFilter = await this.loadInpxFilter();
|
||||
let filterAuthor = () => true;
|
||||
if (inpxFilter) {
|
||||
filterAuthor = (author) => {
|
||||
if (!author)
|
||||
author = emptyFieldValue;
|
||||
|
||||
author = author.toLowerCase();
|
||||
|
||||
let excluded = false;
|
||||
if (inpxFilter.excludeSet) {
|
||||
const authors = author.split(',');
|
||||
|
||||
for (const a of authors) {
|
||||
if (inpxFilter.excludeSet.has(a)) {
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (!inpxFilter.includeSet || inpxFilter.includeSet.has(author)) && !excluded
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
//вспомогательные функции
|
||||
const splitAuthor = (author) => {
|
||||
if (!author) {
|
||||
if (!author)
|
||||
author = emptyFieldValue;
|
||||
}
|
||||
|
||||
const result = author.split(',');
|
||||
if (result.length > 1)
|
||||
@@ -69,7 +122,15 @@ class DbCreator {
|
||||
|
||||
let id = 0;
|
||||
const parsedCallback = async(chunk) => {
|
||||
let filtered = false;
|
||||
for (const rec of chunk) {
|
||||
//сначала фильтр по авторам
|
||||
if (!filterAuthor(rec.author)) {
|
||||
rec.id = 0;
|
||||
filtered = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
rec.id = ++id;
|
||||
|
||||
if (!rec.del) {
|
||||
@@ -116,7 +177,14 @@ class DbCreator {
|
||||
}
|
||||
}
|
||||
|
||||
await db.insert({table: 'book', rows: chunk});
|
||||
let saveChunk = [];
|
||||
if (filtered) {
|
||||
saveChunk = chunk.filter(r => r.id);
|
||||
} else {
|
||||
saveChunk = chunk;
|
||||
}
|
||||
|
||||
await db.insert({table: 'book', rows: saveChunk});
|
||||
|
||||
recsLoaded += chunk.length;
|
||||
callback({recsLoaded});
|
||||
@@ -373,12 +441,12 @@ class DbCreator {
|
||||
};
|
||||
//console.log(stats);
|
||||
|
||||
const inpxHash = await utils.getFileHash(config.inpxFile, 'sha256', 'hex');
|
||||
const inpxHashCreator = new InpxHashCreator(config);
|
||||
|
||||
await db.insert({table: 'config', rows: [
|
||||
{id: 'inpxInfo', value: parser.info},
|
||||
{id: 'inpxInfo', value: (inpxFilter && inpxFilter.info ? inpxFilter.info : parser.info)},
|
||||
{id: 'stats', value: stats},
|
||||
{id: 'inpxHash', value: inpxHash},
|
||||
{id: 'inpxHash', value: await inpxHashCreator.getHash()},
|
||||
]});
|
||||
|
||||
//сохраним поисковые таблицы
|
||||
|
||||
28
server/core/InpxHashCreator.js
Normal file
28
server/core/InpxHashCreator.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const utils = require('./utils');
|
||||
|
||||
//поправить в случае, если изменился порядок формирования id для авторов в DbCreator
|
||||
//иначе будет неправильно работать кеширование на клиенте
|
||||
const dbCreatorVersion = '1';
|
||||
|
||||
class InpxHashCreator {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async getHash() {
|
||||
const config = this.config;
|
||||
|
||||
let inpxFilterHash = '';
|
||||
if (await fs.pathExists(config.inpxFilterFile))
|
||||
inpxFilterHash = await utils.getFileHash(config.inpxFilterFile, 'sha256', 'hex');
|
||||
|
||||
const joinedHash = dbCreatorVersion + inpxFilterHash +
|
||||
await utils.getFileHash(config.inpxFile, 'sha256', 'hex');
|
||||
|
||||
return utils.getBufHash(joinedHash, 'sha256', 'hex');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InpxHashCreator;
|
||||
@@ -9,6 +9,7 @@ const WorkerState = require('./WorkerState');
|
||||
const { JembaDbThread } = require('jembadb');
|
||||
const DbCreator = require('./DbCreator');
|
||||
const DbSearcher = require('./DbSearcher');
|
||||
const InpxHashCreator = require('./InpxHashCreator');
|
||||
|
||||
const ayncExit = new (require('./AsyncExit'))();
|
||||
const log = new (require('./AppLogger'))().log;//singleton
|
||||
@@ -497,13 +498,14 @@ class WebWorker {
|
||||
if (!inpxCheckInterval)
|
||||
return;
|
||||
|
||||
const inpxHashCreator = new InpxHashCreator(this.config);
|
||||
|
||||
while (1) {// eslint-disable-line no-constant-condition
|
||||
try {
|
||||
while (this.myState != ssNormal)
|
||||
await utils.sleep(1000);
|
||||
|
||||
log('check inpx file for changes');
|
||||
const newInpxHash = await utils.getFileHash(this.config.inpxFile, 'sha256', 'hex');
|
||||
const newInpxHash = await inpxHashCreator.getHash();
|
||||
|
||||
const dbConfig = await this.dbConfig();
|
||||
const currentInpxHash = (dbConfig.inpxHash ? dbConfig.inpxHash : '');
|
||||
|
||||
@@ -103,6 +103,7 @@ async function init() {
|
||||
}
|
||||
|
||||
config.recreateDb = argv.recreate || false;
|
||||
config.inpxFilterFile = `${config.execDir}/inpx-web-filter.json`;
|
||||
|
||||
//app
|
||||
const appDir = `${config.publicDir}/app`;
|
||||
|
||||
Reference in New Issue
Block a user