From e1c023bf527a94d0c92051836e7799cdde48f7d5 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Mon, 9 Aug 2021 17:55:55 -0300 Subject: [PATCH] new(basic.gblib) New SET SCHEDULE keyword. --- packages/basic.gblib/services/GBVMService.ts | 43 +++-- .../basic.gblib/services/ScheduleServices.ts | 155 ++++++++++++++++++ packages/core.gbapp/services/GBCoreService.ts | 38 ----- packages/core.gbapp/services/GBMinService.ts | 1 + 4 files changed, 188 insertions(+), 49 deletions(-) create mode 100644 packages/basic.gblib/services/ScheduleServices.ts diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index 10b5400c..f3a97745 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -42,6 +42,7 @@ import urlJoin = require('url-join'); import { DialogKeywords } from './DialogKeywords'; import { Messages } from '../strings'; import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService'; +import { ScheduleServices } from './ScheduleServices'; //tslint:disable-next-line:no-submodule-imports const vm = require('vm'); const vb2ts = require('./vbscript-to-typescript'); @@ -88,16 +89,27 @@ export class GBVMService extends GBService { writeVBS = false; } } - if (writeVBS) { - let text = await this.getTextFromWord(folder, wordFile); - fs.writeFileSync(urlJoin(folder, vbsFile), text); - } - filename = vbsFile; - let mainName = GBVMService.getMethodNameFromVBSFilename(filename); min.scriptMap[filename] = mainName; + if (writeVBS) { + let text = await this.getTextFromWord(folder, wordFile); + + + 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(/SET SCHEDULE (.*)/gi, ''); + fs.writeFileSync(urlJoin(folder, vbsFile), text); + } + const fullFilename = urlJoin(folder, filename); // TODO: Implement in development mode, how swap for .vbs files // fs.watchFile(fullFilename, async () => { @@ -114,6 +126,7 @@ export class GBVMService extends GBService { await this.executeBASIC(fullFilename, min, deployer, mainName); } else { const parsedCode: string = fs.readFileSync(jsfile, 'utf8'); + this.executeJS(min, deployer, parsedCode, mainName); } } else { @@ -128,6 +141,14 @@ export class GBVMService extends GBService { return mainName.toLowerCase(); } + public static getSetScheduleKeywordArgs(code: string) { + if (!code) + return null; + const keyword = /SET SCHEDULE (.*)/gi; + const result = keyword.exec(code); + return result ? result[1] : null; + } + private async getTextFromWord(folder: string, filename: string) { return new Promise(async (resolve, reject) => { textract.fromFileWithPath(urlJoin(folder, filename), { preserveLineBreaks: true }, (error, text) => { @@ -272,7 +293,7 @@ export class GBVMService extends GBService { code = code.replace(/(set max lines)(\s*)(.*)/gi, ($0, $1, $2, $3) => { return `setMaxLines (step, ${$3})\n`; }); - + code = code.replace(/(set translator)(\s*)(.*)/gi, ($0, $1, $2, $3) => { return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`; }); @@ -339,7 +360,7 @@ export class GBVMService extends GBService { } public async executeBASIC(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) { - + // Converts General Bots BASIC into regular VBS const basicCode: string = fs.readFileSync(filename, 'utf8'); @@ -348,11 +369,11 @@ export class GBVMService extends GBService { fs.writeFileSync(vbsFile, vbsCode, 'utf8'); // Converts VBS into TS. - + vb2ts.convertFile(vbsFile); // Convert TS into JS. - + const tsfile: string = `${filename}.ts`; let tsCode: string = fs.readFileSync(tsfile, 'utf8'); tsCode = tsCode.replace(/export.*\n/gi, `export function ${mainName}(step:any) { let resolve;`); @@ -361,7 +382,7 @@ export class GBVMService extends GBService { tsc.compile([tsfile]); // Run JS into the GB context. - + const jsfile = `${tsfile}.js`.replace('.ts', ''); if (fs.existsSync(jsfile)) { diff --git a/packages/basic.gblib/services/ScheduleServices.ts b/packages/basic.gblib/services/ScheduleServices.ts new file mode 100644 index 00000000..bf2fd1c6 --- /dev/null +++ b/packages/basic.gblib/services/ScheduleServices.ts @@ -0,0 +1,155 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| General Bots Copyright (c) Pragmatismo.io. All rights reserved. | +| Licensed under the AGPL-3.0. | +| | +| According to our dual licensing model, this program can be used either | +| under the terms of the GNU Affero General Public License, version 3, | +| or under a proprietary license. | +| | +| The texts of the GNU Affero General Public License with an additional | +| permission and of our proprietary license can be found at and | +| in the LICENSE file you have received along with this program. | +| | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY, without even the implied warranty of | +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +| GNU Affero General Public License for more details. | +| | +| "General Bots" is a registered trademark of Pragmatismo.io. | +| The licensing of the program under the AGPLv3 does not imply a | +| trademark license. Therefore any rights, title and interest in | +| our trademarks remain entirely with us. | +| | +\*****************************************************************************/ + +'use strict'; + +import { GBLog, GBMinInstance, GBService } from 'botlib'; +import { GBServer } from '../../../src/app'; +import { CollectionUtil } from 'pragmatismo-io-framework'; +import { GBVMService } from '../../basic.gblib/services/GBVMService'; +import { GuaribasSchedule } from '../../core.gbapp/models/GBModel'; + +const cron = require('node-cron'); + +/** + * @fileoverview Schedule Services. + */ + +/** + * Basic services for BASIC manipulation. + */ +export class ScheduleServices extends GBService { + + public async deleteScheduleIfAny(min: GBMinInstance, name: string) { + + const task = min["scheduleMap"] ? min["scheduleMap"][name] : null; + + if (task) { + task.destroy(); + delete min["scheduleMap"][name]; + } + + const count = await GuaribasSchedule.destroy({ + where: { + instanceId: min.instance.instanceId, + name: name + } + }); + + if (count > 0) { + GBLog.info(`BASIC: Removed ${name} SET SCHEDULE and ${count} rows from storage on: ${min.botId}...`); + } + } + + /** + * Finds and update user agent information to a next available person. + */ + public async createOrUpdateSchedule( + min: GBMinInstance, + schedule: string, + name: string + ): Promise { + let record = await GuaribasSchedule.findOne({ + where: { + instanceId: min.instance.instanceId, + name: name + } + }); + + if (record === null) { + record = await GuaribasSchedule.create({ + instanceId: min.instance.instanceId, + name: name, + schedule: schedule + }); + } else { + record.schedule = schedule; + await record.save(); + } + + this.ScheduleItem(record, min); + + return record; + } + + + /** + * Load all cached schedule from BASIC SET SCHEDULE keyword. + */ + public async loadSchedules(min: GBMinInstance) { + GBLog.info(`Loading instances from storage...`); + let schedules; + try { + const options = { where: { state: 'active' } }; + schedules = await GuaribasSchedule.findAll(options); + if (process.env.ENDPOINT_UPDATE === 'true') { + await CollectionUtil.asyncForEach(schedules, async item => { + this.ScheduleItem(item, min); + }); + } + } catch (error) { + throw new Error(`Cannot schedule: ${error.message}.`); + } + return schedules; + } + + + private ScheduleItem(item: GuaribasSchedule, min: GBMinInstance) { + GBLog.info(`Scheduling ${item.name} ${min.botId}...`); + try { + const options = { + scheduled: true, + timezone: 'America/Sao_Paulo' + }; + + const task = min["scheduleMap"][item.name]; + if (task) { + task.destroy(); + delete min["scheduleMap"][name]; + + } + + min["scheduleMap"][item.name] = cron.schedule( + item.schedule, + async () => { + let script = item.name; + let min: GBMinInstance = GBServer.globals.minInstances.filter( + p => p.instance.instanceId === item.instanceId + )[0]; + await GBVMService.callVM(script, min, null, null); + }, + options + ); + GBLog.info(`Running .gbdialog word ${item.name} on:${item.schedule}...`); + } catch (error) { } + } +} diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index e60a70dc..f922d3c6 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -657,42 +657,4 @@ ENDPOINT_UPDATE=true return value; } - /** - * Load all cached schedule from BASIC SET SCHEDULE keyword. - */ - public async loadSchedules() { - GBLog.info(`Loading instances from storage...`); - let schedules; - try { - const options = { where: { state: 'active' } }; - schedules = await GuaribasSchedule.findAll(options); - if (process.env.ENDPOINT_UPDATE === 'true') { - await CollectionUtil.asyncForEach(schedules, async item => { - GBLog.info(`Updating bot endpoint for ${item.botId}...`); - try { - const options = { - scheduled: true, - timezone: 'America/Sao_Paulo' - }; - - cron.schedule( - item.schedule, - async () => { - let script = item.name; - let min: GBMinInstance = GBServer.globals.minInstances.filter( - p => p.instance.instanceId === item.instanceId - )[0]; - GBVMService.callVM(script, min, null, null); - }, - options - ); - GBLog.info(`Running .gbdialog word ${item.name} on:${item.schedule}...`); - } catch (error) { } - }); - } - } catch (error) { - throw new Error(`Cannot schedule: ${error.message}.`); - } - return schedules; - } } diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 51e1df7b..1f44d0fa 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -632,6 +632,7 @@ export class GBMinService { min.cbMap = {}; min.scriptMap = {}; min.sandBoxMap = {}; + min["scheduleMap"] = {}; min.packages = sysPackages; min.appPackages = appPackages;