UNPKG

asksuite-core

Version:
262 lines (224 loc) 7.85 kB
const promisesTranslateTree = {}; const thenPromisesTranslateTree = {}; const _ = require('lodash'); const PromiseBlue = require('bluebird'); const { AsksuiteTreeManagerGeneralUtils } = require('./asksuite.tree.manager.general.utils'); class AsksuiteTreeManagerGeneral { constructor({ configuration, CompanyMap, TreeMap, IntentsMap, AsksuiteUtil, AsksuiteService, InitMap, treesTestingCache, getLanguages, translator, wait, }) { this.configuration = configuration; this.CompanyMap = CompanyMap; this.TreeMap = TreeMap; this.getLanguages = getLanguages; this.IntentsMap = IntentsMap; this.AsksuiteUtil = AsksuiteUtil; this.translator = translator; this.AsksuiteService = AsksuiteService; this.treesTestingCache = treesTestingCache; this.InitMap = InitMap; this.wait = wait; } getLanguagesByCompany(chatTreeId) { const company = this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]); return AsksuiteTreeManagerGeneralUtils.getLanguagesByCompany(company); } resolveDefaultLanguage(languages, language) { return AsksuiteTreeManagerGeneralUtils.resolveDefaultLanguage(languages, language); } resolveLanguage(paramLanguage, companyId) { let languages = this.getLanguages(); companyId = companyId || ''; const company = this.CompanyMap.get(companyId) || this.CompanyMap.get(companyId.split('.')[1]); if (company && !_.isEmpty(company.languages)) { languages = _.filter(languages, l => _.includes(company.languages, l.formatIso)); } return this.AsksuiteUtil.resolveLanguage(paramLanguage, languages); } flushTreeMapKeys(keys) { const languages = this.getLanguages(); if (keys && Array.isArray(keys)) { languages.forEach(({ formatIso }) => { keys.forEach(key => { const treeInstance = this.resolveTreeInstance(formatIso); if (treeInstance.has(key)) { treeInstance.delete(key); } }); }); } } resolveTreeInstance(language, companyId) { language = this.resolveLanguage(language, companyId); if (!this.TreeMap.has(language)) { this.TreeMap.set(language, new Map()); } return this.TreeMap.get(language); } isTreeAlreadyRegistred(chatTreeId, paramLanguage) { const company = this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]); if (!paramLanguage && company) { return this.resolveTreeInstance(company.defaultLanguage, chatTreeId).has(chatTreeId); } return this.resolveTreeInstance(paramLanguage, chatTreeId).has(chatTreeId); } async recursiveDialog(map, node) { if (node.children) { node.children.forEach(async item => { map.set(item.dialog, item); await this.recursiveDialog(map, item); }); } } async initTreeMap(map, tree) { map.set(tree.json.dialog, tree.json); await this.recursiveDialog(map, tree.json); } async initTreeByLanguage(language, languageFrom, tree, needTranslate, languages) { const treeInstance = this.resolveTreeInstance(language, tree.chatTreeId); return new Promise((resolve, reject) => { (async () => { if (needTranslate) { console.time(`${tree.chatTreeId}: ${languageFrom} -> ${language}`); const cached = await AsksuiteTreeManagerGeneralUtils.getCachedChatTree( this.configuration, tree.chatTreeId, language, ); if (cached) { tree = cached; console.log(`Cached tree ${tree.chatTreeId} -- ${language}`); } else { tree = await this.translator .translate(tree, language, languageFrom, languages) .catch(reject); } console.timeEnd(`${tree.chatTreeId}: ${languageFrom} -> ${language}`); } await this.initTreeMap(treeInstance, tree).catch(reject); resolve(); })(); }); } async initTreesByCompanyIDIfNeeded(idsTrees, paramLanguage) { return Promise.all( _.map(idsTrees, async idTree => { const language = this.resolveLanguage(paramLanguage, idTree); if (!this.isTreeAlreadyRegistred(idTree, language)) { await this.initTreeByCompanyID(idTree, language); } }), ); } async initTreeByCompanyID(idTree, paramLanguage) { const language = this.resolveLanguage(paramLanguage, idTree); let key = `${idTree}`; if (language) { key += `-${language}`; } if (!this.InitMap.get(idTree) && !(language && this.InitMap.get(key))) { this.InitMap.set(key, true); let tree; if (this.treesTestingCache && this.treesTestingCache.get(idTree)) { tree = this.treesTestingCache.get(idTree); } else { tree = await this.AsksuiteService.findTreeByCompanyId(idTree); } const result = await this.initTree(tree, language).catch(e => { return { error: true, e }; }); this.InitMap.delete(key); if (result && result.error) { throw result.e; } } else { await this.wait.until(function() { return !this.InitMap.get(idTree) && !(language && this.InitMap.get(key)); }); } } resolveThenInitTree(chatTreeId) { const { tree, language } = thenPromisesTranslateTree[chatTreeId]; console.log('--------------------------------------- resolveThenInitTree', { chatTreeId, language, }); delete thenPromisesTranslateTree[chatTreeId]; return this.initTree(tree, language); } async initTree(tree, language) { if (promisesTranslateTree[tree.chatTreeId]) { //next initTree const itemInQueue = thenPromisesTranslateTree[tree.chatTreeId]; const promise = promisesTranslateTree[tree.chatTreeId].catch(e => console.log('error initTree', e), ); if (itemInQueue) { if (itemInQueue.language && itemInQueue.language !== language) { itemInQueue.language = null; } itemInQueue.tree = tree; } else { thenPromisesTranslateTree[tree.chatTreeId] = { tree, language }; return promise.then(() => this.resolveThenInitTree(tree.chatTreeId)); } return promise; } promisesTranslateTree[tree.chatTreeId] = new Promise(resolve => { (async () => { console.log('init initTree', tree.chatTreeId); this.IntentsMap.set(tree.chatTreeId, tree.intents); let languages = this.getLanguagesByCompany(tree.chatTreeId); const defaultLanguage = this.resolveDefaultLanguage(languages, tree.defaultLanguage); if (language) { const lang = this.resolveDefaultLanguage(languages, language); languages = _.filter(languages, l => l === lang); if ( !this.isTreeAlreadyRegistred(tree.chatTreeId, defaultLanguage) && !_.includes(languages, defaultLanguage) ) { languages.push(defaultLanguage); } } const allLanguages = this.getLanguages(); try { await PromiseBlue.map( languages, lang => { return this.initTreeByLanguage( lang, defaultLanguage, tree, lang !== defaultLanguage, allLanguages, ); }, { concurrency: 1 }, ); } catch (e) { console.log('error on initTree', e); } finally { console.log('end initTree', tree.chatTreeId); resolve(); delete promisesTranslateTree[tree.chatTreeId]; } })(); }); return promisesTranslateTree[tree.chatTreeId]; } } module.exports = { AsksuiteTreeManagerGeneral, };