new(kb.gbapp): #259 BASIC from cell import done - second part.

This commit is contained in:
rodrigorodriguez 2023-02-22 13:18:16 -03:00
parent 5d112db576
commit 7268103831
2 changed files with 97 additions and 73 deletions

View file

@ -74,41 +74,46 @@ export class GBVMService extends GBService {
let filename: string = file.name; let filename: string = file.name;
if (filename.endsWith('.docx')) { if (filename.endsWith('.docx')) {
const wordFile = filename; filename = await this.loadDialog(filename, folder, min);
const vbsFile = filename.substr(0, filename.indexOf('docx')) + 'vbs'; }
const fullVbsFile = urlJoin(folder, vbsFile); });
const docxStat = Fs.statSync(urlJoin(folder, wordFile)); }
const interval = 3000; // If compiled is older 30 seconds, then recompile.
let writeVBS = true;
if (Fs.existsSync(fullVbsFile)) {
const vbsStat = Fs.statSync(fullVbsFile);
if (docxStat['mtimeMs'] < vbsStat['mtimeMs'] + interval) {
writeVBS = false;
}
}
filename = vbsFile;
let mainName = GBVMService.getMethodNameFromVBSFilename(filename);
min.scriptMap[filename] = mainName;
if (writeVBS) { public async loadDialog(filename: string, folder: string, min: GBMinInstance) {
let text = await this.getTextFromWord(folder, wordFile); const wordFile = filename;
const vbsFile = filename.substr(0, filename.indexOf('docx')) + 'vbs';
const fullVbsFile = urlJoin(folder, vbsFile);
const docxStat = Fs.statSync(urlJoin(folder, wordFile));
const interval = 3000; // If compiled is older 30 seconds, then recompile.
let writeVBS = true;
if (Fs.existsSync(fullVbsFile)) {
const vbsStat = Fs.statSync(fullVbsFile);
if (docxStat['mtimeMs'] < vbsStat['mtimeMs'] + interval) {
writeVBS = false;
}
}
filename = vbsFile;
let mainName = GBVMService.getMethodNameFromVBSFilename(filename);
min.scriptMap[filename] = mainName;
const schedule = GBVMService.getSetScheduleKeywordArgs(text); if (writeVBS) {
const s = new ScheduleServices(); let text = await this.getTextFromWord(folder, wordFile);
if (schedule) {
await s.createOrUpdateSchedule(min, schedule, mainName);
} else {
await s.deleteScheduleIfAny(min, mainName);
}
text = text.replace(/^\s*SET SCHEDULE (.*)/gim, '');
Fs.writeFileSync(urlJoin(folder, vbsFile), text);
}
// Process node_modules install. const schedule = GBVMService.getSetScheduleKeywordArgs(text);
const s = new ScheduleServices();
if (schedule) {
await s.createOrUpdateSchedule(min, schedule, mainName);
} else {
await s.deleteScheduleIfAny(min, mainName);
}
text = text.replace(/^\s*SET SCHEDULE (.*)/gim, '');
Fs.writeFileSync(urlJoin(folder, vbsFile), text);
}
const node_modules = urlJoin(folder, 'node_modules'); // Process node_modules install.
if (!Fs.existsSync(node_modules)) { const node_modules = urlJoin(folder, 'node_modules');
const packageJson = ` if (!Fs.existsSync(node_modules)) {
const packageJson = `
{ {
"name": "${min.botId}.gbdialog", "name": "${min.botId}.gbdialog",
"version": "1.0.0", "version": "1.0.0",
@ -123,40 +128,38 @@ export class GBVMService extends GBService {
"vm2": "3.9.11" "vm2": "3.9.11"
} }
}`; }`;
Fs.writeFileSync(urlJoin(folder, 'package.json'), packageJson); Fs.writeFileSync(urlJoin(folder, 'package.json'), packageJson);
GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`); GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`);
const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm'); const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm');
child_process.execSync(`${npmPath} install`, { cwd: folder }); child_process.execSync(`${npmPath} install`, { cwd: folder });
} }
// Hot swap for .vbs files. // Hot swap for .vbs files.
const fullFilename = urlJoin(folder, filename);
const fullFilename = urlJoin(folder, filename); if (process.env.GBDIALOG_HOTSWAP) {
if (process.env.GBDIALOG_HOTSWAP) { Fs.watchFile(fullFilename, async () => {
Fs.watchFile(fullFilename, async () => { await this.translateBASIC(fullFilename, mainName, min);
await this.translateBASIC(fullFilename, mainName, min);
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
});
}
const compiledAt = Fs.statSync(fullFilename);
const jsfile = urlJoin(folder, `${filename}.js`);
if (Fs.existsSync(jsfile)) {
const jsStat = Fs.statSync(jsfile);
const interval = 30000; // If compiled is older 30 seconds, then recompile.
if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) {
await this.translateBASIC(fullFilename, mainName, min);
}
} else {
await this.translateBASIC(fullFilename, mainName, min);
}
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8'); const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
});
}
const compiledAt = Fs.statSync(fullFilename);
const jsfile = urlJoin(folder, `${filename}.js`);
if (Fs.existsSync(jsfile)) {
const jsStat = Fs.statSync(jsfile);
const interval = 30000; // If compiled is older 30 seconds, then recompile.
if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) {
await this.translateBASIC(fullFilename, mainName, min);
} }
}); } else {
await this.translateBASIC(fullFilename, mainName, min);
}
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
return filename;
} }
public async translateBASIC(filename: any, mainName: string, min: GBMinInstance) { public async translateBASIC(filename: any, mainName: string, min: GBMinInstance) {
@ -260,18 +263,24 @@ export class GBVMService extends GBService {
private async getTextFromWord(folder: string, filename: string) { private async getTextFromWord(folder: string, filename: string) {
return new Promise<string>(async (resolve, reject) => { return new Promise<string>(async (resolve, reject) => {
textract.fromFileWithPath(urlJoin(folder, filename), { preserveLineBreaks: true }, (error, text) => { const path = urlJoin(folder, filename);
textract.fromFileWithPath(path, { preserveLineBreaks: true }, (error, text) => {
if (error) { if (error) {
reject(error); if (error.message.startsWith('File not correctly recognized as zip file')) {
} else { text = Fs.readFileSync(path, 'utf8');
} else {
reject(error);
}
}
if (text) {
text = text.replace('¨', '"'); text = text.replace('¨', '"');
text = text.replace('“', '"'); text = text.replace('“', '"');
text = text.replace('”', '"'); text = text.replace('”', '"');
text = text.replace('', "'"); text = text.replace('', "'");
text = text.replace('', "'"); text = text.replace('', "'");
resolve(text);
} }
resolve(text);
}); });
}); });
} }
@ -407,8 +416,6 @@ export class GBVMService extends GBService {
} catch (error) { } catch (error) {
throw new Error(`BASIC RUNTIME ERR: ${error.message ? error.message : error}\n Stack:${error.stack}`); throw new Error(`BASIC RUNTIME ERR: ${error.message ? error.message : error}\n Stack:${error.stack}`);
} finally { } finally {
} }
return result; return result;

View file

@ -72,6 +72,7 @@ import { url } from 'inspector';
import { min } from 'lodash'; import { min } from 'lodash';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { text } from 'body-parser'; import { text } from 'body-parser';
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
/** /**
* Result for quey on KB data. * Result for quey on KB data.
@ -410,7 +411,7 @@ export class KBService implements IGBKBService {
public async importKbTabularFile( public async importKbTabularFile(
filePath: string, filePath: string,
instanceId: number, min: GBMinInstance,
packageId: number packageId: number
): Promise<GuaribasQuestion[]> { ): Promise<GuaribasQuestion[]> {
GBLog.info(`Now reading file ${filePath}...`); GBLog.info(`Now reading file ${filePath}...`);
@ -522,10 +523,26 @@ export class KBService implements IGBKBService {
return false; return false;
} }
// In case of code cell, compiles it and associate with the answer.
if (answer.toLowerCase().startsWith ('/basic') ){
const code = answer.substr(6);
const gbaiName = `${min.instance.botId}.gbai`;
const gbdialogName = `${min.instance.botId}.gbdialog`;
const scriptName = `tmp${GBAdminService.getRndReadableIdentifier()}.docx`;
const localName = Path.join('work', gbaiName, gbdialogName, `${scriptName}`);
Fs.writeFileSync(localName, code, { encoding: null });
answer = scriptName;
const vm = new GBVMService();
await vm.loadDialog(Path.basename(localName), Path.dirname(localName), min);
}
// Now with all the data ready, creates entities in the store. // Now with all the data ready, creates entities in the store.
const answer1 = { const answer1 = {
instanceId: instanceId, instanceId: min.instance.instanceId,
content: answer, content: answer,
format: format, format: format,
media: media, media: media,
@ -543,7 +560,7 @@ export class KBService implements IGBKBService {
subject3: subject3, subject3: subject3,
subject4: subject4, subject4: subject4,
content: question.replace(/["]+/g, ''), content: question.replace(/["]+/g, ''),
instanceId: instanceId, instanceId: min.instance.instanceId,
skipIndex: question.charAt(0) === '"', skipIndex: question.charAt(0) === '"',
packageId: packageId packageId: packageId
}; };
@ -625,7 +642,7 @@ export class KBService implements IGBKBService {
// Import tabular files in the tabular directory. // Import tabular files in the tabular directory.
await this.importKbTabularDirectory(localPath, instance, packageStorage.packageId); await this.importKbTabularDirectory(localPath, min, packageStorage.packageId);
// Import remaining .md files in articles directory. // Import remaining .md files in articles directory.
@ -803,12 +820,12 @@ export class KBService implements IGBKBService {
} }
} }
public async importKbTabularDirectory(localPath: string, instance: IGBInstance, packageId: number): Promise<any> { public async importKbTabularDirectory(localPath: string, min: GBMinInstance, packageId: number): Promise<any> {
const files = await walkPromise(localPath); const files = await walkPromise(localPath);
await CollectionUtil.asyncForEach(files, async file => { await CollectionUtil.asyncForEach(files, async file => {
if (file !== null && file.name.endsWith('.xlsx')) { if (file !== null && file.name.endsWith('.xlsx')) {
return await this.importKbTabularFile(urlJoin(file.root, file.name), instance.instanceId, packageId); return await this.importKbTabularFile(urlJoin(file.root, file.name), min, packageId);
} }
}); });
} }