Добавлена возможность фильтрации по авторам при формировании поисковой БД.

Критерии фильтрации должны находиться в файле inpx-web-filter.json
This commit is contained in:
Book Pauk
2022-10-03 16:25:51 +07:00
parent f5bb97a081
commit 904e3e6c2f
4 changed files with 107 additions and 8 deletions

View File

@@ -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()},
]});
//сохраним поисковые таблицы

View 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;

View File

@@ -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 : '');

View File

@@ -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`;