UNPKG

7.21 kBJavaScriptView Raw
1const promisesTranslateTree = {};
2const _ = require('lodash');
3const PromiseBlue = require('bluebird');
4
5class AsksuiteTreeManagerGeneral {
6 constructor({
7 CompanyMap,
8 TreeMap,
9 IntentsMap,
10 AsksuiteUtil,
11 AsksuiteService,
12 InitMap,
13 getLanguages,
14 translator,
15 wait,
16 }) {
17 this.CompanyMap = CompanyMap;
18 this.TreeMap = TreeMap;
19 this.getLanguages = getLanguages;
20 this.IntentsMap = IntentsMap;
21 this.AsksuiteUtil = AsksuiteUtil;
22 this.translator = translator;
23 this.AsksuiteService = AsksuiteService;
24 this.InitMap = InitMap;
25 this.wait = wait;
26 }
27
28 getLanguagesByCompany(chatTreeId) {
29 const company =
30 this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]);
31 if (company && !_.isEmpty(company.languages)) {
32 return company.languages;
33 }
34
35 const languages = [];
36
37 let flag = null;
38 let languageFlag = null;
39 const regex = /https:\/\/lipis\.github\.io\/flag-icon-css\/flags\/4x3\/(\w+)\.svg/;
40
41 if (company && company.languageFlags) {
42 const addLanguage = (attrLanguageFlag, defaultFlag, prefixLanguage, defaultLanguage) => {
43 if ((languageFlag = _.get(company.languageFlags, attrLanguageFlag, ''))) {
44 flag = _.get(languageFlag.match(regex), '1', defaultFlag);
45 languages.push(`${prefixLanguage}-${flag}`);
46 } else {
47 languages.push(defaultLanguage);
48 }
49 };
50
51 addLanguage('pt_br', 'br', 'pt', 'pt-br');
52 languages.push('en-us');
53 addLanguage('es', 'es', 'es', 'es-es');
54 } else {
55 return ['pt-br', 'en-us', 'es-es'];
56 }
57
58 return languages;
59 }
60
61 resolveDefaultLanguage(languages, language) {
62 if (languages.includes(language)) {
63 return language;
64 }
65
66 return _.find(languages, l => l.substring(0, 2) === language.substring(0, 2)) || language;
67 }
68
69 resolveLanguage(paramLanguage, companyId) {
70 let languages = this.getLanguages();
71 companyId = companyId || '';
72 const company = this.CompanyMap.get(companyId) || this.CompanyMap.get(companyId.split('.')[1]);
73 if (company && !_.isEmpty(company.languages)) {
74 languages = _.filter(languages, l => _.includes(company.languages, l.formatIso));
75 }
76 return this.AsksuiteUtil.resolveLanguage(paramLanguage, languages);
77 }
78
79 flushTreeMapKeys(keys) {
80 const languages = this.getLanguages();
81 if (keys && Array.isArray(keys)) {
82 languages.forEach(({ formatIso }) => {
83 keys.forEach(key => {
84 const treeInstance = this.resolveTreeInstance(formatIso);
85 if (treeInstance.has(key)) {
86 treeInstance.delete(key);
87 }
88 });
89 });
90 }
91 }
92
93 resolveTreeInstance(language, companyId) {
94 language = this.resolveLanguage(language, companyId);
95 if (!this.TreeMap.has(language)) {
96 this.TreeMap.set(language, new Map());
97 }
98
99 return this.TreeMap.get(language);
100 }
101
102 isTreeAlreadyRegistred(chatTreeId, paramLanguage) {
103 const company =
104 this.CompanyMap.get(chatTreeId) || this.CompanyMap.get(chatTreeId.split('.')[1]);
105 if (!paramLanguage && company) {
106 return this.resolveTreeInstance(company.defaultLanguage, chatTreeId).has(chatTreeId);
107 }
108 return this.resolveTreeInstance(paramLanguage, chatTreeId).has(chatTreeId);
109 }
110
111 async recursiveDialog(map, node) {
112 if (node.children) {
113 node.children.forEach(async item => {
114 map.set(item.dialog, item);
115 await this.recursiveDialog(map, item);
116 });
117 }
118 }
119
120 async initTreeMap(map, tree) {
121 map.set(tree.json.dialog, tree.json);
122 await this.recursiveDialog(map, tree.json);
123 }
124
125 initTreeByLanguage(language, languageFrom, tree, needTranslate, languages) {
126 const treeInstance = this.resolveTreeInstance(language, tree.chatTreeId);
127
128 return new Promise((resolve, reject) => {
129 (async () => {
130 if (needTranslate) {
131 console.time(`${tree.chatTreeId}: ${languageFrom} -> ${language}`);
132 tree = await this.translator
133 .translate(tree, language, languageFrom, languages)
134 .catch(reject);
135 console.timeEnd(`${tree.chatTreeId}: ${languageFrom} -> ${language}`);
136 }
137 await this.initTreeMap(treeInstance, tree).catch(reject);
138
139 resolve();
140 })();
141 });
142 }
143
144 async initTreesByCompanyIDIfNeeded(idsTrees, paramLanguage) {
145 return Promise.all(
146 _.map(idsTrees, async idTree => {
147 const language = this.resolveLanguage(paramLanguage, idTree);
148 if (!this.isTreeAlreadyRegistred(idTree, language)) {
149 await this.initTreeByCompanyID(idTree, language);
150 }
151 }),
152 );
153 }
154
155 async initTreeByCompanyID(idTree, paramLanguage) {
156 const language = this.resolveLanguage(paramLanguage, idTree);
157 let key = `${idTree}`;
158 if (language) {
159 key += `-${language}`;
160 }
161 if (!this.InitMap.get(idTree) && !(language && this.InitMap.get(key))) {
162 this.InitMap.set(key, true);
163 const tree = await this.AsksuiteService.findTreeByCompanyId(idTree);
164 const result = await this.initTree(tree, language).catch(e => {
165 return { error: true, e };
166 });
167 this.InitMap.delete(key);
168 if (result && result.error) {
169 throw result.e;
170 }
171 } else {
172 await this.wait.until(function() {
173 return !this.InitMap.get(idTree) && !(language && this.InitMap.get(key));
174 });
175 }
176 }
177
178 async initTree(tree, language) {
179 if (promisesTranslateTree[tree.chatTreeId]) {
180 return promisesTranslateTree[tree.chatTreeId]
181 .catch(e => console.log('error initTree', e))
182 .then(() => this.initTree(tree, language));
183 }
184
185 promisesTranslateTree[tree.chatTreeId] = new Promise(resolve => {
186 (async () => {
187 console.log('init initTree', tree.chatTreeId);
188 this.IntentsMap.set(tree.chatTreeId, tree.intents);
189
190 let languages = this.getLanguagesByCompany(tree.chatTreeId);
191 const defaultLanguage = this.resolveDefaultLanguage(languages, tree.defaultLanguage);
192
193 if (language) {
194 const lang = this.resolveDefaultLanguage(languages, language);
195 languages = _.filter(languages, l => l === lang);
196
197 if (
198 !this.isTreeAlreadyRegistred(tree.chatTreeId, defaultLanguage) &&
199 !_.includes(languages, defaultLanguage)
200 ) {
201 languages.push(defaultLanguage);
202 }
203 }
204
205 const allLanguages = this.getLanguages();
206
207 try {
208 await PromiseBlue.map(
209 languages,
210 lang => {
211 return this.initTreeByLanguage(
212 lang,
213 defaultLanguage,
214 tree,
215 lang !== defaultLanguage,
216 allLanguages,
217 );
218 },
219 { concurrency: 1 },
220 );
221 } catch (e) {
222 console.log('error on initTree', e);
223 } finally {
224 console.log('end initTree', tree.chatTreeId);
225 resolve();
226 delete promisesTranslateTree[tree.chatTreeId];
227 }
228 })();
229 });
230
231 return promisesTranslateTree[tree.chatTreeId];
232 }
233}
234
235module.exports = {
236 AsksuiteTreeManagerGeneral,
237};