new(basic.gblib): AS IMAGE, AS PDF, SET THEME and SQL new keywords.
This commit is contained in:
parent
4125c510ca
commit
0e367f1a7f
7 changed files with 880 additions and 26 deletions
726
package-lock.json
generated
726
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -61,6 +61,7 @@
|
||||||
"@types/validator": "13.1.4",
|
"@types/validator": "13.1.4",
|
||||||
"adal-node": "0.2.2",
|
"adal-node": "0.2.2",
|
||||||
"adm-zip": "0.5.6",
|
"adm-zip": "0.5.6",
|
||||||
|
"alasql": "^1.7.3",
|
||||||
"any-shell-escape": "0.1.1",
|
"any-shell-escape": "0.1.1",
|
||||||
"async-promises": "0.2.3",
|
"async-promises": "0.2.3",
|
||||||
"azure-arm-cognitiveservices": "3.0.0",
|
"azure-arm-cognitiveservices": "3.0.0",
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
"npm": "7.21.0",
|
"npm": "7.21.0",
|
||||||
"opn": "6.0.0",
|
"opn": "6.0.0",
|
||||||
"pdf-extraction": "1.0.2",
|
"pdf-extraction": "1.0.2",
|
||||||
|
"pdfkit": "^0.13.0",
|
||||||
"phone": "2.4.21",
|
"phone": "2.4.21",
|
||||||
"pragmatismo-io-framework": "1.0.20",
|
"pragmatismo-io-framework": "1.0.20",
|
||||||
"prism-media": "1.3.1",
|
"prism-media": "1.3.1",
|
||||||
|
@ -123,6 +125,7 @@
|
||||||
"ssr-for-bots": "1.0.1-c",
|
"ssr-for-bots": "1.0.1-c",
|
||||||
"strict-password-generator": "1.1.2",
|
"strict-password-generator": "1.1.2",
|
||||||
"swagger-client": "2.1.18",
|
"swagger-client": "2.1.18",
|
||||||
|
"tabulator-tables": "^5.2.6",
|
||||||
"tedious": "14.0.0",
|
"tedious": "14.0.0",
|
||||||
"textract": "2.5.0",
|
"textract": "2.5.0",
|
||||||
"typescript": "3.6.4",
|
"typescript": "3.6.4",
|
||||||
|
|
|
@ -138,8 +138,6 @@ export class HearDialog {
|
||||||
const promises = step.context.activity.attachments.map(HearDialog.downloadAttachmentAndWrite);
|
const promises = step.context.activity.attachments.map(HearDialog.downloadAttachmentAndWrite);
|
||||||
const successfulSaves = await Promise.all(promises);
|
const successfulSaves = await Promise.all(promises);
|
||||||
|
|
||||||
// Replies back to the user with information about where the attachment is stored on the bot's server,
|
|
||||||
// and what the name of the saved file is.
|
|
||||||
async function replyForReceivedAttachments(localAttachmentData) {
|
async function replyForReceivedAttachments(localAttachmentData) {
|
||||||
if (localAttachmentData) {
|
if (localAttachmentData) {
|
||||||
// Because the TurnContext was bound to this function, the bot can call
|
// Because the TurnContext was bound to this function, the bot can call
|
||||||
|
|
|
@ -595,6 +595,19 @@ export class DialogKeywords {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the theme for assets generation.
|
||||||
|
*
|
||||||
|
* @example SET THEME "themename"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public async setTheme(step, theme) {
|
||||||
|
const user = await this.min.userProfile.get(step.context, {});
|
||||||
|
user.basicOptions.theme = theme.trim();
|
||||||
|
await this.min.userProfile.set(step.context, user);
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines translator behaviour.
|
* Defines translator behaviour.
|
||||||
*
|
*
|
||||||
|
@ -789,13 +802,7 @@ export class DialogKeywords {
|
||||||
const url = urlJoin(
|
const url = urlJoin(
|
||||||
GBServer.globals.publicAddress,
|
GBServer.globals.publicAddress,
|
||||||
'kb',
|
'kb',
|
||||||
`${this.min.botId}.gbai`,
|
`${this.min.botId}.gbaiurlonalService.sendFile(this.min, step, mobile, url, caption);
|
||||||
`${this.min.botId}.gbkb`,
|
|
||||||
'assets',
|
|
||||||
filename
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.min.conversationalService.sendFile(this.min, step, mobile, url, caption);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,14 @@ export class GBVMService extends GBService {
|
||||||
|
|
||||||
// Keywords from General Bots BASIC.
|
// Keywords from General Bots BASIC.
|
||||||
|
|
||||||
|
code = code.replace(/(\w+)\s*\=\s*SELECT\s*(.*)/gi, ($0, $1, $2) => {
|
||||||
|
|
||||||
|
let tableName = /\sFROM\s(\w+)/.exec($1)[0];
|
||||||
|
|
||||||
|
return `sys().executeSQL(${$2}, ${$1}, ${tableName})\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
code = code.replace(/(\w+)\s*\=\s*get html\s*(.*)/gi, ($0, $1, $2, $3) => {
|
code = code.replace(/(\w+)\s*\=\s*get html\s*(.*)/gi, ($0, $1, $2, $3) => {
|
||||||
return `${$1} = getPage(step, ${$2})\n`;
|
return `${$1} = getPage(step, ${$2})\n`;
|
||||||
});
|
});
|
||||||
|
@ -251,7 +259,6 @@ export class GBVMService extends GBService {
|
||||||
return `${$1} = hear("menu", ${$2})`;
|
return `${$1} = hear("menu", ${$2})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
||||||
return `${$2} = hear()`;
|
return `${$2} = hear()`;
|
||||||
});
|
});
|
||||||
|
@ -374,6 +381,10 @@ export class GBVMService extends GBService {
|
||||||
return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`;
|
return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
code = code.replace(/(set theme)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
|
||||||
|
return `setTheme (step, "${$3.toLowerCase()}")\n`;
|
||||||
|
});
|
||||||
|
|
||||||
code = code.replace(/(set whole word)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
|
code = code.replace(/(set whole word)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
|
||||||
return `setWholeWord (step, "${$3.toLowerCase()}")\n`;
|
return `setWholeWord (step, "${$3.toLowerCase()}")\n`;
|
||||||
});
|
});
|
||||||
|
@ -442,6 +453,10 @@ export class GBVMService extends GBService {
|
||||||
return `sys().convert(${$3})\n`;
|
return `sys().convert(${$3})\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
code = code.replace(/(\w+)\s*\=\s*(.*)\s*as image/gi, ($0, $1, $2) => {
|
||||||
|
return `sys().asImage(${$2}, ${$1})\n`;
|
||||||
|
});
|
||||||
|
|
||||||
code = code.replace(/save\s(.*)\sas\s(.*)/gi, ($0, $1, $2, $3) => {
|
code = code.replace(/save\s(.*)\sas\s(.*)/gi, ($0, $1, $2, $3) => {
|
||||||
return `sys().saveFile(${$2}, ${$1})\n`;
|
return `sys().saveFile(${$2}, ${$1})\n`;
|
||||||
});
|
});
|
||||||
|
@ -645,6 +660,10 @@ export class GBVMService extends GBService {
|
||||||
code = code.replace(/("[^"]*"|'[^']*')|\bsetTranslatorOn\b/gi, ($0, $1) => {
|
code = code.replace(/("[^"]*"|'[^']*')|\bsetTranslatorOn\b/gi, ($0, $1) => {
|
||||||
return $1 === undefined ? 'this.setTranslatorOn' : $1;
|
return $1 === undefined ? 'this.setTranslatorOn' : $1;
|
||||||
});
|
});
|
||||||
|
code = code.replace(/("[^"]*"|'[^']*')|\bsetTheme\b/gi, ($0, $1) => {
|
||||||
|
return $1 === undefined ? 'this.setTheme' : $1;
|
||||||
|
});
|
||||||
|
|
||||||
code = code.replace(/("[^"]*"|'[^']*')|\bsetWholeWord\b/gi, ($0, $1) => {
|
code = code.replace(/("[^"]*"|'[^']*')|\bsetWholeWord\b/gi, ($0, $1) => {
|
||||||
return $1 === undefined ? 'this.setWholeWord' : $1;
|
return $1 === undefined ? 'this.setWholeWord' : $1;
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,15 +34,20 @@ import { GBDialogStep, GBLog, GBMinInstance } from 'botlib';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
import * as request from 'request-promise-native';
|
import * as request from 'request-promise-native';
|
||||||
|
|
||||||
const urlJoin = require('url-join');
|
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||||
import { DialogKeywords } from './DialogKeywords';
|
import { DialogKeywords } from './DialogKeywords';
|
||||||
const path = require('path');
|
import { Tabulator } from 'tabulator-tables';
|
||||||
|
import { GBServer } from '../../../src/app';
|
||||||
|
|
||||||
|
const urlJoin = require('url-join');
|
||||||
|
const puppeteer = require('puppeteer')
|
||||||
|
const Path = require('path');
|
||||||
const sgMail = require('@sendgrid/mail');
|
const sgMail = require('@sendgrid/mail');
|
||||||
const ComputerVisionClient = require('@azure/cognitiveservices-computervision').ComputerVisionClient;
|
const ComputerVisionClient = require('@azure/cognitiveservices-computervision').ComputerVisionClient;
|
||||||
const ApiKeyCredentials = require('@azure/ms-rest-js').ApiKeyCredentials;
|
const ApiKeyCredentials = require('@azure/ms-rest-js').ApiKeyCredentials;
|
||||||
|
const alasql = require('alasql');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
|
@ -172,6 +177,115 @@ export class SystemKeywords {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param renderPDF
|
||||||
|
* @param renderImage
|
||||||
|
* @returns
|
||||||
|
*
|
||||||
|
* @see http://tabulator.info/examples/5.2
|
||||||
|
* @see puppeteer.
|
||||||
|
*/
|
||||||
|
private async renderTable(data, renderPDF, renderImage) {
|
||||||
|
|
||||||
|
const gbaiName = `${this.min.botId}.gbai`;
|
||||||
|
const browser = await puppeteer.launch({ headless: false });
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
// Includes the associated CSS related to current theme.
|
||||||
|
|
||||||
|
const theme = this.dk.user.basicOptions.theme;
|
||||||
|
switch (theme) {
|
||||||
|
case "white":
|
||||||
|
await page.addStyleTag({ path: 'node_modules/tabulator-tables/dist/css/tabulator_simple.min.css' })
|
||||||
|
break;
|
||||||
|
case "dark":
|
||||||
|
await page.addStyleTag({ path: 'node_modules/tabulator-tables/dist/css/tabulator_midnight.min.css' })
|
||||||
|
break;
|
||||||
|
case "blue":
|
||||||
|
await page.addStyleTag({ path: 'node_modules/tabulator-tables/dist/css/tabulator_modern.min.css' })
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let fields = [];
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
fields.push({field:data[i]});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.createElement("div");
|
||||||
|
el.id = "table";
|
||||||
|
document.body.prepend(el);
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.evaluate(`
|
||||||
|
new Tabulator("#example-table", {
|
||||||
|
height:"311px",
|
||||||
|
data: ${JSON.stringify(data)},
|
||||||
|
columns:[ ${JSON.stringify(fields)}]
|
||||||
|
});
|
||||||
|
`);
|
||||||
|
|
||||||
|
let url;
|
||||||
|
let localName;
|
||||||
|
|
||||||
|
if (renderImage) {
|
||||||
|
|
||||||
|
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.png`);
|
||||||
|
|
||||||
|
await page.screenshot({ path: localName });
|
||||||
|
|
||||||
|
url = urlJoin(
|
||||||
|
GBServer.globals.publicAddress,
|
||||||
|
this.min.botId,
|
||||||
|
'cache',
|
||||||
|
Path.basename(localName)
|
||||||
|
);
|
||||||
|
GBLog.info(`BASIC: Table image generated at ${url} .`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderPDF) {
|
||||||
|
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.pdf`);
|
||||||
|
|
||||||
|
url = urlJoin(
|
||||||
|
GBServer.globals.publicAddress,
|
||||||
|
this.min.botId,
|
||||||
|
'cache',
|
||||||
|
Path.basename(localName)
|
||||||
|
);
|
||||||
|
|
||||||
|
let pdf = await page.pdf({ format: 'A4' });
|
||||||
|
GBLog.info(`BASIC: Table PDF generated at ${url} .`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
return [url, localName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async asPDF(data, filename) {
|
||||||
|
let file = await this.renderTable(data, true, false);
|
||||||
|
return file['url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async asImage(data, filename) {
|
||||||
|
let file = await this.renderTable(data, false, true);
|
||||||
|
return file['url'];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async executeSQL(data, sql, tableName) {
|
||||||
|
|
||||||
|
sql = `SELECT ${sql}`.replaceAll(tableName, '?');
|
||||||
|
|
||||||
|
return alasql(sql, [data]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrives the content of a given URL.
|
* Retrives the content of a given URL.
|
||||||
*/
|
*/
|
||||||
|
@ -253,11 +367,10 @@ export class SystemKeywords {
|
||||||
|
|
||||||
// Handles calls for HTML stuff
|
// Handles calls for HTML stuff
|
||||||
|
|
||||||
if (file._javascriptEnabled)
|
if (file._javascriptEnabled) {
|
||||||
{
|
|
||||||
GBLog.info(`BASIC: Web automation setting ${file}' to '${value}' (SET). `);
|
GBLog.info(`BASIC: Web automation setting ${file}' to '${value}' (SET). `);
|
||||||
|
|
||||||
await this.dk.type(null, file, address, value );
|
await this.dk.type(null, file, address, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -888,7 +888,7 @@ export class GBMinService {
|
||||||
user.subjects = [];
|
user.subjects = [];
|
||||||
user.cb = undefined;
|
user.cb = undefined;
|
||||||
user.welcomed = false;
|
user.welcomed = false;
|
||||||
user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true };
|
user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true, theme: "white" };
|
||||||
|
|
||||||
firstTime = true;
|
firstTime = true;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue