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",
|
||||
"adal-node": "0.2.2",
|
||||
"adm-zip": "0.5.6",
|
||||
"alasql": "^1.7.3",
|
||||
"any-shell-escape": "0.1.1",
|
||||
"async-promises": "0.2.3",
|
||||
"azure-arm-cognitiveservices": "3.0.0",
|
||||
|
@ -102,6 +103,7 @@
|
|||
"npm": "7.21.0",
|
||||
"opn": "6.0.0",
|
||||
"pdf-extraction": "1.0.2",
|
||||
"pdfkit": "^0.13.0",
|
||||
"phone": "2.4.21",
|
||||
"pragmatismo-io-framework": "1.0.20",
|
||||
"prism-media": "1.3.1",
|
||||
|
@ -123,6 +125,7 @@
|
|||
"ssr-for-bots": "1.0.1-c",
|
||||
"strict-password-generator": "1.1.2",
|
||||
"swagger-client": "2.1.18",
|
||||
"tabulator-tables": "^5.2.6",
|
||||
"tedious": "14.0.0",
|
||||
"textract": "2.5.0",
|
||||
"typescript": "3.6.4",
|
||||
|
|
|
@ -138,8 +138,6 @@ export class HearDialog {
|
|||
const promises = step.context.activity.attachments.map(HearDialog.downloadAttachmentAndWrite);
|
||||
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) {
|
||||
if (localAttachmentData) {
|
||||
// Because the TurnContext was bound to this function, the bot can call
|
||||
|
|
|
@ -595,6 +595,19 @@ export class DialogKeywords {
|
|||
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.
|
||||
*
|
||||
|
@ -789,13 +802,7 @@ export class DialogKeywords {
|
|||
const url = urlJoin(
|
||||
GBServer.globals.publicAddress,
|
||||
'kb',
|
||||
`${this.min.botId}.gbai`,
|
||||
`${this.min.botId}.gbkb`,
|
||||
'assets',
|
||||
filename
|
||||
);
|
||||
|
||||
await this.min.conversationalService.sendFile(this.min, step, mobile, url, caption);
|
||||
`${this.min.botId}.gbaiurlonalService.sendFile(this.min, step, mobile, url, caption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,6 +193,14 @@ export class GBVMService extends GBService {
|
|||
|
||||
// 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) => {
|
||||
return `${$1} = getPage(step, ${$2})\n`;
|
||||
});
|
||||
|
@ -251,7 +259,6 @@ export class GBVMService extends GBService {
|
|||
return `${$1} = hear("menu", ${$2})`;
|
||||
});
|
||||
|
||||
|
||||
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
||||
return `${$2} = hear()`;
|
||||
});
|
||||
|
@ -374,6 +381,10 @@ export class GBVMService extends GBService {
|
|||
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) => {
|
||||
return `setWholeWord (step, "${$3.toLowerCase()}")\n`;
|
||||
});
|
||||
|
@ -442,6 +453,10 @@ export class GBVMService extends GBService {
|
|||
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) => {
|
||||
return `sys().saveFile(${$2}, ${$1})\n`;
|
||||
});
|
||||
|
@ -645,6 +660,10 @@ export class GBVMService extends GBService {
|
|||
code = code.replace(/("[^"]*"|'[^']*')|\bsetTranslatorOn\b/gi, ($0, $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) => {
|
||||
return $1 === undefined ? 'this.setWholeWord' : $1;
|
||||
});
|
||||
|
|
|
@ -34,15 +34,20 @@ import { GBDialogStep, GBLog, GBMinInstance } from 'botlib';
|
|||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||
import * as request from 'request-promise-native';
|
||||
|
||||
const urlJoin = require('url-join');
|
||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService';
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||
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 ComputerVisionClient = require('@azure/cognitiveservices-computervision').ComputerVisionClient;
|
||||
const ApiKeyCredentials = require('@azure/ms-rest-js').ApiKeyCredentials;
|
||||
const alasql = require('alasql');
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview General Bots server core.
|
||||
|
@ -127,9 +132,9 @@ export class SystemKeywords {
|
|||
for (let i = 0; i < result.regions.length; i++) {
|
||||
const region = result.regions[i];
|
||||
|
||||
for (let j = 0; j < region.lines.length; j++) {
|
||||
for (let j = 0; j < region.lines.length; j++) {
|
||||
const line = region.lines[j];
|
||||
|
||||
|
||||
for (let k = 0; k < line.words.length; k++) {
|
||||
final += `${line.words[k].text} `;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -250,14 +364,13 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async set(file: any, address: string, value: any): Promise<any> {
|
||||
|
||||
|
||||
// Handles calls for HTML stuff
|
||||
|
||||
if (file._javascriptEnabled)
|
||||
{
|
||||
if (file._javascriptEnabled) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -888,7 +888,7 @@ export class GBMinService {
|
|||
user.subjects = [];
|
||||
user.cb = undefined;
|
||||
user.welcomed = false;
|
||||
user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true };
|
||||
user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true, theme: "white" };
|
||||
|
||||
firstTime = true;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue