new(admin.gbapp): MSGraph now used to download .gbkb artifacts.
This commit is contained in:
parent
face6c59ef
commit
6b1bc00e41
6 changed files with 120 additions and 65 deletions
|
@ -192,17 +192,9 @@ export class GBAdminService implements IGBAdminService {
|
||||||
// .gbot packages are handled using storage API, so no download
|
// .gbot packages are handled using storage API, so no download
|
||||||
// of local resources is required.
|
// of local resources is required.
|
||||||
|
|
||||||
|
await deployer['downloadFolder'](min,
|
||||||
if (!localFolder.endsWith('.gbot') && !process.env.DONT_DOWNLOAD) {
|
Path.join('work', `${min.instance.botId}.gbai`),
|
||||||
GBLog.warn(`${GBConfigService.get('CLOUD_USERNAME')} must be authorized on SharePoint related site to download to: ${localFolder}`);
|
Path.basename(folderName));
|
||||||
await s.downloadFolder(
|
|
||||||
localFolder,
|
|
||||||
siteName,
|
|
||||||
folderName,
|
|
||||||
GBConfigService.get('CLOUD_USERNAME'),
|
|
||||||
GBConfigService.get('CLOUD_PASSWORD')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await deployer.deployPackage(min, localFolder);
|
await deployer.deployPackage(min, localFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
|
||||||
|
|
||||||
const parameters = {
|
const parameters = {
|
||||||
properties: {
|
properties: {
|
||||||
description: description,
|
description: `${description}`,
|
||||||
displayName: name,
|
displayName: name,
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
iconUrl: iconUrl
|
iconUrl: iconUrl
|
||||||
|
|
|
@ -70,23 +70,6 @@ export class SystemKeywords {
|
||||||
this.deployer = deployer;
|
this.deployer = deployer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrives token and initialize drive client API.
|
|
||||||
*/
|
|
||||||
private async internalGetDriveClient() {
|
|
||||||
let token = await this.min.adminService.acquireElevatedToken(this.min.instance.instanceId);
|
|
||||||
let siteId = process.env.STORAGE_SITE_ID;
|
|
||||||
let libraryId = process.env.STORAGE_LIBRARY;
|
|
||||||
|
|
||||||
let client = MicrosoftGraph.Client.init({
|
|
||||||
authProvider: done => {
|
|
||||||
done(null, token);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}`;
|
|
||||||
return [baseUrl, client];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrives the content of a given URL.
|
* Retrives the content of a given URL.
|
||||||
*/
|
*/
|
||||||
|
@ -175,7 +158,7 @@ export class SystemKeywords {
|
||||||
public async set(file: string, address: string, value: any): Promise<any> {
|
public async set(file: string, address: string, value: any): Promise<any> {
|
||||||
GBLog.info(`BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `);
|
GBLog.info(`BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `);
|
||||||
|
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
|
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||||
|
@ -223,7 +206,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async save(file: string, ...args): Promise<any> {
|
public async save(file: string, ...args): Promise<any> {
|
||||||
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
|
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||||
|
|
||||||
|
@ -257,7 +240,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async get(file: string, address: string): Promise<any> {
|
public async get(file: string, address: string): Promise<any> {
|
||||||
GBLog.info(`BASIC: GET '${address}' in '${file}'.`);
|
GBLog.info(`BASIC: GET '${address}' in '${file}'.`);
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||||
|
|
||||||
|
@ -293,7 +276,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async find(file: string, ...args): Promise<any> {
|
public async find(file: string, ...args): Promise<any> {
|
||||||
GBLog.info(`BASIC: FIND running on ${file} and args: ${JSON.stringify(args)}...`);
|
GBLog.info(`BASIC: FIND running on ${file} and args: ${JSON.stringify(args)}...`);
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||||
|
|
||||||
|
@ -313,7 +296,7 @@ export class SystemKeywords {
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
let results = await client
|
let results = await client
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:Z100')`)
|
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:Z2000')`)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
// Increments columnIndex by looping until find a column match.
|
// Increments columnIndex by looping until find a column match.
|
||||||
|
@ -380,7 +363,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async createFolder(name: string) {
|
public async createFolder(name: string) {
|
||||||
|
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
let path = `/${botId}.gbai/${botId}.gbdata`;
|
let path = `/${botId}.gbai/${botId}.gbdata`;
|
||||||
|
|
||||||
|
@ -436,7 +419,7 @@ export class SystemKeywords {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public async shareFolder(folderReference, email: string, message: string) {
|
public async shareFolder(folderReference, email: string, message: string) {
|
||||||
let [, client] = await this.internalGetDriveClient();
|
let [, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const driveId = folderReference.parentReference.driveId;
|
const driveId = folderReference.parentReference.driveId;
|
||||||
const itemId = folderReference.id;
|
const itemId = folderReference.id;
|
||||||
const body = {
|
const body = {
|
||||||
|
@ -462,7 +445,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async copyFile(src, dest) {
|
public async copyFile(src, dest) {
|
||||||
GBLog.info(`BASIC: BEGINING COPY '${src}' to '${dest}'`);
|
GBLog.info(`BASIC: BEGINING COPY '${src}' to '${dest}'`);
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
|
|
||||||
// Normalizes all slashes.
|
// Normalizes all slashes.
|
||||||
|
@ -531,7 +514,7 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async convert(src, dest) {
|
public async convert(src, dest) {
|
||||||
GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`);
|
GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`);
|
||||||
let [baseUrl, client] = await this.internalGetDriveClient();
|
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||||
const botId = this.min.instance.botId;
|
const botId = this.min.instance.botId;
|
||||||
|
|
||||||
// Normalizes all slashes.
|
// Normalizes all slashes.
|
||||||
|
@ -642,8 +625,6 @@ export class SystemKeywords {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls any REST API by using GET HTTP method.
|
* Calls any REST API by using GET HTTP method.
|
||||||
*
|
*
|
||||||
|
@ -658,7 +639,7 @@ export class SystemKeywords {
|
||||||
let result = await request.get(options);
|
let result = await request.get(options);
|
||||||
GBLog.info(`[GET]: ${url} : ${result}`);
|
GBLog.info(`[GET]: ${url} : ${result}`);
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls any REST API by using POST HTTP method.
|
* Calls any REST API by using POST HTTP method.
|
||||||
|
@ -679,9 +660,9 @@ export class SystemKeywords {
|
||||||
let result = await request.post(options);
|
let result = await request.post(options);
|
||||||
GBLog.info(`[POST]: ${url} (${data}): ${result}`);
|
GBLog.info(`[POST]: ${url} (${data}): ${result}`);
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async numberOnly(text: string) {
|
public async numberOnly(text: string) {
|
||||||
return text.replace(/\D/gi, '');
|
return text.replace(/\D/gi, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@ import urlJoin = require('url-join');
|
||||||
const Fs = require('fs');
|
const Fs = require('fs');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
const graph = require('@microsoft/microsoft-graph-client');
|
|
||||||
const rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
|
const request = require('request-promise-native');
|
||||||
|
|
||||||
import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBDeployer, IGBInstance, IGBPackage } from 'botlib';
|
import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBDeployer, IGBInstance, IGBPackage } from 'botlib';
|
||||||
import { AzureSearch } from 'pragmatismo-io-framework';
|
import { AzureSearch } from 'pragmatismo-io-framework';
|
||||||
|
@ -98,6 +98,23 @@ export class GBDeployer implements IGBDeployer {
|
||||||
return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${instance.storageUsername};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
|
return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${instance.storageUsername};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrives token and initialize drive client API.
|
||||||
|
*/
|
||||||
|
public static async internalGetDriveClient(min: GBMinInstance) {
|
||||||
|
let token = await min.adminService.acquireElevatedToken(min.instance.instanceId);
|
||||||
|
let siteId = process.env.STORAGE_SITE_ID;
|
||||||
|
let libraryId = process.env.STORAGE_LIBRARY;
|
||||||
|
|
||||||
|
let client = MicrosoftGraph.Client.init({
|
||||||
|
authProvider: done => {
|
||||||
|
done(null, token);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}`;
|
||||||
|
return [baseUrl, client];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs package deployment in all .gbai or default.
|
* Performs package deployment in all .gbai or default.
|
||||||
*/
|
*/
|
||||||
|
@ -422,6 +439,71 @@ export class GBDeployer implements IGBDeployer {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all para from tabular file Config.xlsx.
|
||||||
|
*/
|
||||||
|
public async downloadFolder(min: GBMinInstance, localPath: string, remotePath: string,
|
||||||
|
baseUrl: string = null, client = null): Promise<any> {
|
||||||
|
if (!baseUrl) {
|
||||||
|
[baseUrl, client] = await GBDeployer.internalGetDriveClient(min);
|
||||||
|
|
||||||
|
remotePath = remotePath.replace(/\\/gi, '/');
|
||||||
|
const parts = remotePath.split('/');
|
||||||
|
|
||||||
|
// Creates each subfolder.
|
||||||
|
|
||||||
|
let pathBase = localPath;
|
||||||
|
if (!Fs.existsSync(pathBase)) {
|
||||||
|
Fs.mkdirSync(pathBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
await CollectionUtil.asyncForEach(parts, async item => {
|
||||||
|
pathBase = Path.join(pathBase, item);
|
||||||
|
if (!Fs.existsSync(pathBase)) {
|
||||||
|
Fs.mkdirSync(pathBase);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retrieves all files in remote folder.
|
||||||
|
|
||||||
|
const botId = min.instance.botId;
|
||||||
|
const path = urlJoin(`/${botId}.gbai`, remotePath);
|
||||||
|
let url = `${baseUrl}/drive/root:${path}:/children`;
|
||||||
|
|
||||||
|
const res = await client
|
||||||
|
.api(url)
|
||||||
|
.get();
|
||||||
|
const documents = res.value;
|
||||||
|
if (documents === undefined || documents.length === 0) {
|
||||||
|
GBLog.info(`${remotePath} is an empty folder.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download files or navigate to directory to recurse.
|
||||||
|
|
||||||
|
await CollectionUtil.asyncForEach(documents, async item => {
|
||||||
|
|
||||||
|
const itemPath = Path.join(localPath, remotePath, item.name);
|
||||||
|
|
||||||
|
if (item.folder) {
|
||||||
|
if (!Fs.existsSync(itemPath)) {
|
||||||
|
Fs.mkdirSync(itemPath);
|
||||||
|
}
|
||||||
|
const nextFolder = urlJoin(remotePath, item.name);
|
||||||
|
await this.downloadFolder(min, localPath, nextFolder);
|
||||||
|
} else {
|
||||||
|
GBLog.info(`Downloading ${itemPath}...`);
|
||||||
|
const url = item['@microsoft.graph.downloadUrl'];
|
||||||
|
const options = {
|
||||||
|
uri: url,
|
||||||
|
encoding: null
|
||||||
|
};
|
||||||
|
const response = await request({ uri: url, encoding: null });
|
||||||
|
Fs.writeFileSync(itemPath, response, { encoding: null });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* UndDeploys a bot to the storage.
|
* UndDeploys a bot to the storage.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -157,7 +157,7 @@ export class GBMinService {
|
||||||
try {
|
try {
|
||||||
await this.mountBot(instance);
|
await this.mountBot(instance);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
GBLog.error(`Error mounting bot ${instance.botId}: ${error.message}`);
|
GBLog.error(`Error mounting bot ${instance.botId}: ${error.message}\n${error.stack}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue