From 7e7cbc13debba38b2d6a202ea4c999d1289f0549 Mon Sep 17 00:00:00 2001 From: "balakrishna@mantralabsglobal.com" Date: Tue, 31 Dec 2019 16:59:43 +0530 Subject: [PATCH 1/3] Issue #SB-16923 feat: SDk changes for content sharing --- .../handlers/export/copy-to-destination.ts | 21 +++++++++++++++++++ src/content/impl/content-service-impl.ts | 3 +++ 2 files changed, 24 insertions(+) create mode 100644 src/content/handlers/export/copy-to-destination.ts diff --git a/src/content/handlers/export/copy-to-destination.ts b/src/content/handlers/export/copy-to-destination.ts new file mode 100644 index 000000000..db216f70d --- /dev/null +++ b/src/content/handlers/export/copy-to-destination.ts @@ -0,0 +1,21 @@ +import { Response } from '../../../api'; +import {FileUtil} from '../../../util/file/util/file-util'; + +export class CopyToDestination { + + constructor() { + } + + public async copyFile(exportResponse: Response, destinationFolder): Promise { + return new Promise((resolve, reject) => { + buildconfigreader.copyFile(FileUtil.getDirecory(exportResponse.body.ecarFilePath), destinationFolder, + FileUtil.getFileName(exportResponse.body.ecarFilePath), + () => { + resolve(exportResponse); + }, err => { + console.error(err); + resolve(err); + }); + }); + } +} diff --git a/src/content/impl/content-service-impl.ts b/src/content/impl/content-service-impl.ts index d94a69440..46bd9c5a1 100644 --- a/src/content/impl/content-service-impl.ts +++ b/src/content/impl/content-service-impl.ts @@ -93,6 +93,7 @@ import {SdkConfig} from '../../sdk-config'; import {DeviceInfo} from '../../util/device'; import {GetContentHeirarchyHandler} from './../handlers/get-content-heirarchy-handler'; import {catchError, map, mapTo, mergeMap, take} from 'rxjs/operators'; +import { CopyToDestination } from '../handlers/export/copy-to-destination'; @injectable() export class ContentServiceImpl implements ContentService, DownloadCompleteDelegate, SdkServiceOnInitDelegate { @@ -291,6 +292,8 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg return new CopyAsset(this.fileService).execute(exportResponse.body); }).then((exportResponse: Response) => { return new EcarBundle(this.fileService, this.zipService).execute(exportResponse.body); + }).then((exportResponse: Response) => { + return new CopyToDestination().copyFile(exportResponse, contentExportRequest.destinationFolder); }).then((exportResponse: Response) => { return new DeleteTempEcar(this.fileService).execute(exportResponse.body); }).then((exportResponse: Response) => { From 282bd6b87632a9096bb1feafd6b7094c6864ec2a Mon Sep 17 00:00:00 2001 From: "balakrishna@mantralabsglobal.com" Date: Fri, 3 Jan 2020 14:44:53 +0530 Subject: [PATCH 2/3] Issue #SB-66923 feat: content sharing --- .../export/copy-to-destination.spec.ts | 83 +++++++++++++++++++ .../handlers/export/copy-to-destination.ts | 2 +- src/content/impl/content-service-impl.ts | 2 +- 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/content/handlers/export/copy-to-destination.spec.ts diff --git a/src/content/handlers/export/copy-to-destination.spec.ts b/src/content/handlers/export/copy-to-destination.spec.ts new file mode 100644 index 000000000..e169746e1 --- /dev/null +++ b/src/content/handlers/export/copy-to-destination.spec.ts @@ -0,0 +1,83 @@ +import { CopyToDestination } from './copy-to-destination'; +import {FileService} from '../../../util/file/def/file-service'; +import {ContentEntry} from '../../db/schema'; +import {Response} from '../../../api' + +describe('CopyToDestination', () => { + let copyToDestination: CopyToDestination; + const mockFileService: Partial = {}; + + beforeAll(() => { + copyToDestination = new CopyToDestination(); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should be create a instance of copy asset', () => { + expect(copyToDestination).toBeTruthy(); + }); + + it('should be copied a file by invoked exicute() for error MEssage', async (done) => { + // arrange + const contentEntrySchema: ContentEntry.SchemaMap[] = [{ + identifier: 'IDENTIFIER', + server_data: 'SERVER_DATA', + local_data: '{"children": [{"DOWNLOAD": 1}, "do_234", "do_345"], "artifactUrl": "http:///do_123"}', + mime_type: 'MIME_TYPE', + manifest_version: 'MAINFEST_VERSION', + content_type: 'CONTENT_TYPE', + content_state: 2, + }]; + + const exportContext = { + destinationFolder: 'SAMPLE_DESTINATION_FOLDER', + tmpLocationPath: 'SAMPLE_TEMP_PATH', + contentModelsToExport: contentEntrySchema, + items: ['artifactUrl'], + metadata: {'SAMPLE_KEY': 'SAMPLE_META_DATA'}, + ecarFilePath: 'sampledir/samplefile' + }; + const response: Response = new Response(); + + response.body = exportContext; + // act + await copyToDestination.execute(response, 'SAMPLE_DESTINATION_FOLDER').then((result) => { + // assert + expect(result).toEqual(response); + done(); + }); + }); + + it('should be copied a file by invoked exicute() for error MEssage', async (done) => { + // arrange + const contentEntrySchema: ContentEntry.SchemaMap[] = [{ + identifier: 'IDENTIFIER', + server_data: 'SERVER_DATA', + local_data: '{"children": [{"DOWNLOAD": 1}, "do_234", "do_345"], "artifactUrl": "http:///do_123"}', + mime_type: 'MIME_TYPE', + manifest_version: 'MAINFEST_VERSION', + content_type: 'CONTENT_TYPE', + content_state: 2, + }]; + + const exportContext = { + destinationFolder: 'SAMPLE_DESTINATION_FOLDER', + tmpLocationPath: 'SAMPLE_TEMP_PATH', + contentModelsToExport: contentEntrySchema, + items: ['artifactUrl'], + metadata: {'SAMPLE_KEY': 'SAMPLE_META_DATA'}, + ecarFilePath: 'sampledir/samplefile' + }; + const response: Response = new Response(); + + response.body = exportContext; + // act + await copyToDestination.execute(response, 'SAMPLE_DESTINATION_FOLDER').catch((result) => { + // assert + done(); + }); + }); + +}); diff --git a/src/content/handlers/export/copy-to-destination.ts b/src/content/handlers/export/copy-to-destination.ts index db216f70d..0f20e6c1b 100644 --- a/src/content/handlers/export/copy-to-destination.ts +++ b/src/content/handlers/export/copy-to-destination.ts @@ -6,7 +6,7 @@ export class CopyToDestination { constructor() { } - public async copyFile(exportResponse: Response, destinationFolder): Promise { + public async execute(exportResponse: Response, destinationFolder): Promise { return new Promise((resolve, reject) => { buildconfigreader.copyFile(FileUtil.getDirecory(exportResponse.body.ecarFilePath), destinationFolder, FileUtil.getFileName(exportResponse.body.ecarFilePath), diff --git a/src/content/impl/content-service-impl.ts b/src/content/impl/content-service-impl.ts index 46bd9c5a1..0118ac248 100644 --- a/src/content/impl/content-service-impl.ts +++ b/src/content/impl/content-service-impl.ts @@ -293,7 +293,7 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg }).then((exportResponse: Response) => { return new EcarBundle(this.fileService, this.zipService).execute(exportResponse.body); }).then((exportResponse: Response) => { - return new CopyToDestination().copyFile(exportResponse, contentExportRequest.destinationFolder); + return new CopyToDestination().execute(exportResponse, contentExportRequest.destinationFolder); }).then((exportResponse: Response) => { return new DeleteTempEcar(this.fileService).execute(exportResponse.body); }).then((exportResponse: Response) => { From a8aa994e1820cf6f477886ef4b8b3fa1a2113e5a Mon Sep 17 00:00:00 2001 From: "balakrishna@mantralabsglobal.com" Date: Fri, 3 Jan 2020 16:50:14 +0530 Subject: [PATCH 3/3] Issue #SB-66923 feat: content sharing --- src/content/def/requests.ts | 1 + .../handlers/export/copy-to-destination.ts | 9 +++++++- .../handlers/export/deletete-temp-dir.ts | 22 +++++++++++++++++++ .../export/generate-export-share-telemetry.ts | 12 +++++++--- src/content/impl/content-service-impl.ts | 18 ++++++++++----- 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 src/content/handlers/export/deletete-temp-dir.ts diff --git a/src/content/def/requests.ts b/src/content/def/requests.ts index 2d3808a05..9052235c6 100644 --- a/src/content/def/requests.ts +++ b/src/content/def/requests.ts @@ -91,6 +91,7 @@ export interface ContentImport { export interface ContentExportRequest { destinationFolder: string; contentIds: string[]; + saveLocally?: boolean; } export interface ContentMarkerRequest { diff --git a/src/content/handlers/export/copy-to-destination.ts b/src/content/handlers/export/copy-to-destination.ts index 0f20e6c1b..8a1ff0a03 100644 --- a/src/content/handlers/export/copy-to-destination.ts +++ b/src/content/handlers/export/copy-to-destination.ts @@ -1,13 +1,20 @@ import { Response } from '../../../api'; import {FileUtil} from '../../../util/file/util/file-util'; +import { ContentExportRequest } from '../..'; export class CopyToDestination { constructor() { } - public async execute(exportResponse: Response, destinationFolder): Promise { + public async execute(exportResponse: Response, contentExportRequest: ContentExportRequest): Promise { return new Promise((resolve, reject) => { + let destinationFolder; + if (contentExportRequest.saveLocally) { + destinationFolder = contentExportRequest.destinationFolder; + } else { + destinationFolder = cordova.file.externalCacheDirectory; + } buildconfigreader.copyFile(FileUtil.getDirecory(exportResponse.body.ecarFilePath), destinationFolder, FileUtil.getFileName(exportResponse.body.ecarFilePath), () => { diff --git a/src/content/handlers/export/deletete-temp-dir.ts b/src/content/handlers/export/deletete-temp-dir.ts new file mode 100644 index 000000000..679501ace --- /dev/null +++ b/src/content/handlers/export/deletete-temp-dir.ts @@ -0,0 +1,22 @@ +import {Response} from '../../../api'; +import {ExportContentContext} from '../..'; + +export class DeleteTempDir { + + constructor() { + } + + public async execute(exportContext: ExportContentContext): Promise { + const response: Response = new Response(); + return new Promise((resolve, reject) => { + const tmpDirPath = exportContext.destinationFolder!.concat('tmp/'); + buildconfigreader.rm(tmpDirPath, '', () => { + response.body = exportContext; + resolve(response); + }, (e) => { + response.body = exportContext; + resolve(response); + }); + }); + } +} diff --git a/src/content/handlers/export/generate-export-share-telemetry.ts b/src/content/handlers/export/generate-export-share-telemetry.ts index 16eb9857a..28c514e08 100644 --- a/src/content/handlers/export/generate-export-share-telemetry.ts +++ b/src/content/handlers/export/generate-export-share-telemetry.ts @@ -1,4 +1,4 @@ -import {ContentExportResponse, ExportContentContext} from '../..'; +import {ContentExportResponse, ExportContentContext, ContentExportRequest} from '../..'; import {Response} from '../../../api'; import {Item, ShareDirection, ShareItemType, ShareType, TelemetryService, TelemetryShareRequest} from '../../../telemetry'; import {ContentUtil} from '../../util/content-util'; @@ -7,7 +7,7 @@ export class GenerateExportShareTelemetry { constructor(private telemetryService: TelemetryService) { } - execute(exportContentContext: ExportContentContext): Promise { + execute(exportContentContext: ExportContentContext, fileName: string, contentExportRequest: ContentExportRequest): Promise { const response: Response = new Response(); const items: Item[] = []; for (const element of exportContentContext.items!) { @@ -28,7 +28,13 @@ export class GenerateExportShareTelemetry { }; return this.telemetryService.share(req).toPromise() .then(() => { - const exportResponse: ContentExportResponse = {exportedFilePath: exportContentContext.ecarFilePath!}; + let exportedFilePath; + if (contentExportRequest.saveLocally) { + exportedFilePath = contentExportRequest.destinationFolder.concat(fileName); + } else { + exportedFilePath = cordova.file.externalCacheDirectory.concat(fileName); + } + const exportResponse: ContentExportResponse = {exportedFilePath: exportedFilePath}; response.body = exportResponse; return Promise.resolve(response); }).catch(() => { diff --git a/src/content/impl/content-service-impl.ts b/src/content/impl/content-service-impl.ts index 0118ac248..9284422b2 100644 --- a/src/content/impl/content-service-impl.ts +++ b/src/content/impl/content-service-impl.ts @@ -94,6 +94,7 @@ import {DeviceInfo} from '../../util/device'; import {GetContentHeirarchyHandler} from './../handlers/get-content-heirarchy-handler'; import {catchError, map, mapTo, mergeMap, take} from 'rxjs/operators'; import { CopyToDestination } from '../handlers/export/copy-to-destination'; +import { DeleteTempDir } from './../handlers/export/deletete-temp-dir'; @injectable() export class ContentServiceImpl implements ContentService, DownloadCompleteDelegate, SdkServiceOnInitDelegate { @@ -277,9 +278,9 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg contentModelsToExport: contentsInDb, tmpLocationPath: tempLocationPath.nativeURL }; - return new CleanTempLoc(this.fileService).execute(exportContentContext); - }).then((exportResponse: Response) => { - return new CreateTempLoc(this.fileService).execute(exportResponse.body); + // return new CleanTempLoc(this.fileService).execute(exportContentContext); + // }).then((exportResponse: Response) => { + return new CreateTempLoc(this.fileService).execute(exportContentContext); }).then((exportResponse: Response) => { return new CreateContentExportManifest(this.dbService, exportHandler).execute(exportResponse.body); }).then((exportResponse: Response) => { @@ -293,11 +294,16 @@ export class ContentServiceImpl implements ContentService, DownloadCompleteDeleg }).then((exportResponse: Response) => { return new EcarBundle(this.fileService, this.zipService).execute(exportResponse.body); }).then((exportResponse: Response) => { - return new CopyToDestination().execute(exportResponse, contentExportRequest.destinationFolder); + return new CopyToDestination().execute(exportResponse, contentExportRequest); + // }).then((exportResponse: Response) => { + // return new DeleteTempEcar(this.fileService).execute(exportResponse.body); }).then((exportResponse: Response) => { - return new DeleteTempEcar(this.fileService).execute(exportResponse.body); + return new DeleteTempDir().execute(exportResponse.body); }).then((exportResponse: Response) => { - return new GenerateExportShareTelemetry(this.telemetryService).execute(exportResponse.body); + const fileName = ContentUtil.getExportedFileName(contentsInDb); + return new GenerateExportShareTelemetry( + this.telemetryService).execute(exportResponse.body, fileName, contentExportRequest + ); }).then((exportResponse: Response) => { return exportResponse.body; });