new(basic.gblib): FILL keyword can now template images and AS IMAGE can convert a DOCX to a PNG.

This commit is contained in:
rodrigorodriguez 2023-02-05 18:19:39 -03:00
parent d4845dc062
commit 8a5bdf3934
3 changed files with 1398 additions and 1394 deletions

View file

@ -364,7 +364,7 @@ export class GBVMService extends GBService {
sandbox['httpPs'] = ''; sandbox['httpPs'] = '';
sandbox['pid'] = pid; sandbox['pid'] = pid;
if (GBConfigService.get('VM3') === 'false') { if (GBConfigService.get('GBVM') === 'false') {
try { try {
const vm1 = new NodeVM({ const vm1 = new NodeVM({
allowAsync: true, allowAsync: true,

View file

@ -355,7 +355,7 @@ export class SystemKeywords {
const res = await client.api(`${baseUrl}/drive/root:/${tmpDocx}:/content?format=pdf`).get(); const res = await client.api(`${baseUrl}/drive/root:/${tmpDocx}:/content?format=pdf`).get();
await client.api(`${baseUrl}/drive/root:/${tmpDocx}:/content`).delete(); await client.api(`${baseUrl}/drive/root:/${tmpDocx}:/content`).delete();
const streamToString = stream => { const streamToBuffer = stream => {
const chunks = []; const chunks = [];
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk)); stream.on('data', chunk => chunks.push(chunk));
@ -364,7 +364,7 @@ export class SystemKeywords {
}); });
}; };
gbfile.data = await streamToString(res); gbfile.data = await streamToBuffer(res);
// Converts the PDF to PNG. // Converts the PDF to PNG.
@ -1267,7 +1267,7 @@ export class SystemKeywords {
try { try {
const res = await client.api(`${baseUrl}/drive/root:/${srcPath}:/content?format=pdf`).get(); const res = await client.api(`${baseUrl}/drive/root:/${srcPath}:/content?format=pdf`).get();
const streamToString = stream => { const streamToBuffer = stream => {
const chunks = []; const chunks = [];
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk)); stream.on('data', chunk => chunks.push(chunk));
@ -1276,7 +1276,7 @@ export class SystemKeywords {
}); });
}; };
const result = await streamToString(res); const result = await streamToBuffer(res);
await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result); await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result);
} catch (error) { } catch (error) {
@ -1387,27 +1387,27 @@ export class SystemKeywords {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
const gbaiName = `${botId}.gbai`; const gbaiName = `${botId}.gbai`;
const path = `/${botId}.gbai/${botId}.gbdata`; const path = `/${botId}.gbai/${botId}.gbdrive`;
// Downloads template from .gbdrive. // Downloads template from .gbdrive.
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
let template = await this.internalGetDocument(client, baseUrl, path, templateName); let template = await this.internalGetDocument(client, baseUrl, path, templateName);
let url = template['@microsoft.graph.downloadUrl']; let url = template['@microsoft.graph.downloadUrl'];
let localName = Path.join('work', gbaiName, 'cache', ``); const res = await fetch(url);
const response = await fetch(url); let localName = Path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.docx`);
Fs.writeFileSync(localName, Buffer.from(await response.arrayBuffer()), { encoding: null }); let buf = Buffer.from(await res.arrayBuffer());
Fs.writeFileSync(localName, buf, { encoding: null });
// Loads the file as binary content. // Loads the file as binary content.
let content = Fs.readFileSync(localName, 'binary'); let zip = new PizZip(buf);
let zip = new PizZip(content);
let doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true }); let doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
if (localName.endsWith('.pptx')) { if (localName.endsWith('.pptx')) {
doc.attachModule(pptxTemplaterModule); doc.attachModule(pptxTemplaterModule);
} }
// Replace image path on all elements of data.s // Replace image path on all elements of data.
const images = []; const images = [];
@ -1448,6 +1448,9 @@ export class SystemKeywords {
traverse(data, process); traverse(data, process);
doc.render(data); doc.render(data);
buf = doc.getZip().generate({ type: 'nodebuffer', compression: 'DEFLATE' });
Fs.writeFileSync(localName, buf, { encoding: null });
if (images) { if (images) {
// Replaces images within the document. // Replaces images within the document.

View file

@ -34,30 +34,30 @@
* @fileoverview General Bots server core. * @fileoverview General Bots server core.
*/ */
'use strict'; 'use strict';
import cliProgress from 'cli-progress'; import cliProgress from 'cli-progress';
import { DialogSet, TextPrompt } from 'botbuilder-dialogs'; import { DialogSet, TextPrompt } from 'botbuilder-dialogs';
import express from 'express'; import express from 'express';
import SwaggerClient from 'swagger-client'; import SwaggerClient from 'swagger-client';
import removeRoute from 'express-remove-route'; import removeRoute from 'express-remove-route';
import AuthenticationContext from 'adal-node'; import AuthenticationContext from 'adal-node';
import wash from 'washyourmouthoutwithsoap'; import wash from 'washyourmouthoutwithsoap';
import { FacebookAdapter } from 'botbuilder-adapter-facebook'; import { FacebookAdapter } from 'botbuilder-adapter-facebook';
import path from 'path'; import path from 'path';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import Fs from 'fs'; import Fs from 'fs';
import arrayBufferToBuffer from 'arraybuffer-to-buffer'; import arrayBufferToBuffer from 'arraybuffer-to-buffer';
import { import {
AutoSaveStateMiddleware, AutoSaveStateMiddleware,
BotFrameworkAdapter, BotFrameworkAdapter,
ConversationState, ConversationState,
MemoryStorage, MemoryStorage,
TurnContext, TurnContext,
UserState UserState
} from 'botbuilder'; } from 'botbuilder';
import { AttachmentPrompt, ConfirmPrompt, OAuthPrompt, WaterfallDialog } from 'botbuilder-dialogs'; import { AttachmentPrompt, ConfirmPrompt, OAuthPrompt, WaterfallDialog } from 'botbuilder-dialogs';
import { import {
GBDialogStep, GBDialogStep,
GBLog, GBLog,
GBMinInstance, GBMinInstance,
@ -66,32 +66,32 @@
IGBCoreService, IGBCoreService,
IGBInstance, IGBInstance,
IGBPackage IGBPackage
} from 'botlib'; } from 'botlib';
import { CollectionUtil } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework';
import { MicrosoftAppCredentials } from 'botframework-connector'; import { MicrosoftAppCredentials } from 'botframework-connector';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { GuaribasConversationMessage } from '../../analytics.gblib/models/index.js'; import { GuaribasConversationMessage } from '../../analytics.gblib/models/index.js';
import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService.js'; import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService.js';
import { GBVMService } from '../../basic.gblib/services/GBVMService.js'; import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
import { AskDialogArgs } from '../../kb.gbapp/dialogs/AskDialog.js'; import { AskDialogArgs } from '../../kb.gbapp/dialogs/AskDialog.js';
import { KBService } from '../../kb.gbapp/services/KBService.js'; import { KBService } from '../../kb.gbapp/services/KBService.js';
import { SecService } from '../../security.gbapp/services/SecService.js'; import { SecService } from '../../security.gbapp/services/SecService.js';
import { WhatsappDirectLine } from '../../whatsapp.gblib/services/WhatsappDirectLine.js'; import { WhatsappDirectLine } from '../../whatsapp.gblib/services/WhatsappDirectLine.js';
import { Messages } from '../strings.js'; import { Messages } from '../strings.js';
import { GBConfigService } from './GBConfigService.js'; import { GBConfigService } from './GBConfigService.js';
import { GBConversationalService } from './GBConversationalService.js'; import { GBConversationalService } from './GBConversationalService.js';
import { GBDeployer } from './GBDeployer.js'; import { GBDeployer } from './GBDeployer.js';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { GoogleChatDirectLine } from '../../google-chat.gblib/services/GoogleChatDirectLine.js'; import { GoogleChatDirectLine } from '../../google-chat.gblib/services/GoogleChatDirectLine.js';
import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js'; import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
import * as nlp from 'node-nlp'; import * as nlp from 'node-nlp';
import Path from 'path'; import Path from 'path';
/** /**
* Minimal service layer for a bot and encapsulation of BOT Framework calls. * Minimal service layer for a bot and encapsulation of BOT Framework calls.
*/ */
export class GBMinService { export class GBMinService {
/** /**
* Default General Bots User Interface package. * Default General Bots User Interface package.
*/ */
@ -1159,7 +1159,7 @@
} }
// Prepare Promises to download each attachment and then execute each Promise. // Prepare Promises to download each attachment and then execute each Promise.
if (step.context.activity.attachments) {
const promises = step.context.activity.attachments.map( const promises = step.context.activity.attachments.map(
GBMinService.downloadAttachmentAndWrite.bind({ min, user, params }) GBMinService.downloadAttachmentAndWrite.bind({ min, user, params })
); );
@ -1176,10 +1176,12 @@
const replyPromises = successfulSaves.map(replyForReceivedAttachments.bind(step.context)); const replyPromises = successfulSaves.map(replyForReceivedAttachments.bind(step.context));
await Promise.all(replyPromises); await Promise.all(replyPromises);
if (successfulSaves.length > 0) { if (successfulSaves.length > 0) {
class GBFile {
data: Buffer;
filename: string;
}
class GBFile {data:Buffer; filename: string}; const results = successfulSaves.reduce((accum: GBFile[], item) => {
const results = successfulSaves.reduce((accum:GBFile[], item)=>{
const result: GBFile = { const result: GBFile = {
data: Fs.readFileSync(successfulSaves[0]['localPath']), data: Fs.readFileSync(successfulSaves[0]['localPath']),
filename: successfulSaves[0]['fileName'] filename: successfulSaves[0]['fileName']
@ -1188,13 +1190,13 @@
}, []) as GBFile[]; }, []) as GBFile[];
if (min.cbMap[userId] && min.cbMap[userId].promise == '!GBHEAR') { if (min.cbMap[userId] && min.cbMap[userId].promise == '!GBHEAR') {
if (results.length>1) if (results.length > 1) {
{
throw new Error('It is only possible to upload one file per message, right now.'); throw new Error('It is only possible to upload one file per message, right now.');
} }
min.cbMap[userId].promise = results[0]; min.cbMap[userId].promise = results[0];
} }
} }
}
// Files in .gbdialog can be called directly by typing its name normalized into JS . // Files in .gbdialog can be called directly by typing its name normalized into JS .
@ -1422,5 +1424,4 @@
} }
} }
} }
} }