import { Bucket } from './../common/Bucket' ; import { Path } from './../common/Path' ; import { IBucketObject } from './../common/IBucketObject' ; import { File } from './../common/File' ; import { Folder } from './../common/Folder' ; import { IFolderContents } from './../common/IFolderContents' ; import { IUploadConfig } from './../common/IUploadConfig' ; import { IBackend } from './../common/IBackend' ; import { AmazonS3Backend } from './../common/AmazonS3Backend' ; export class BucketController { see http public static $inject = [ '$rootScope' ] ; /**
     * Backend name. Passed in as component binding.
     */ public backendName : string ; /**
     * Bucket name. Passed in as a component binding.
     */ public bucketName : string ; /**
     * Allow Download. Flag indicating whether to allow file download.
     */ public allowDownload : boolean ; /**
     * AWS region. Passed in as a component binding.
     */ public awsRegion : string ; /**
     * AWS Access Key ID. Passed in as a component binding.
     */ public awsAccessKeyId : string ; /**
     * AWS Secret Access Key. Passed in as a component binding.
     */ public awsSecretAccessKey : string ; /**
     * AWS Session Token. Passed in as a component binding.
     */ public awsSessionToken : string ; /**
     * AWS bucket prefix for a folder. Passed in as a component binding.
     */ public awsBucketPrefix : string ; /**
     * Flag used to indicate a background operation is running.
     */ public working : boolean ; /**
     * Error encountered running background operation.
     */ public error : Error ; /**
     * Bucket.
     */ public bucket : Bucket ; /**
     * Display deleted files in the folder.
     */ public showDeleted : boolean ; /**
     * Current working folder.
     */ public currentFolder : Folder ; /**
     * Folder objects in the current working path.
     */ public folders : Folder [ ] ; /**
     * File objects in the current working path.
     */ public files : File [ ] ; /**
     * Deleted folder objects in the current working path.
     */ public deletedFolders : Folder [ ] ; /**
     * deleted file objects in the current working path.
     */ public deletedFiles : File [ ] ; /**
     * Settings for uploading files.
     */ public uploadConfig : IUploadConfig ; /**
     * Used to specify the name of new folders.
     */ public folderName : string ; /**
     * Backend.
     */ private backend : IBackend ; /**
     * Create an instance of the controller.
     */ constructor ( private $rootScope ) { this . working = false ; this . error = null ; this . bucket = null ; this . showDeleted = false ; this . folders = [ ] ; this . deletedFolders = [ ] ; this . files = [ ] ; this . deletedFiles = [ ] ; this . uploadConfig = null ; this . folderName = '' ; $rootScope . $watch ( ( ) : string => { return this . awsAccessKeyId ; } , ( newVal , oldVal ) : void => { this . regenerateBackend ( ) ; } ) ; } /**
     * Initialize the controller.
     */ $onInit ( ) { if ( this . awsBucketPrefix === undefined ) { this . awsBucketPrefix = '/' ; } this . currentFolder = new Folder ( new Path ( this . awsBucketPrefix ) ) ; if ( this . awsSessionToken === undefined ) { this . awsSessionToken = null ; } if ( this . allowDownload === undefined ) { this . allowDownload = true ; } this . regenerateBackend ( ) ; } /**
     * Create the backend and load the contents.
     */ public regenerateBackend ( ) { if ( this . backendName === 's3' ) { this . backend = new AmazonS3Backend ( this . awsRegion , this . awsAccessKeyId , this . awsSecretAccessKey , this . awsSessionToken , this . allowDownload ) ; } else { throw new Error ( `Unknown backend: ${ this . backendName }` ) ; } this . loadContents ( ) ; } /**
     * Load bucket and objects at working path.
     */ public loadContents ( ) { this . working = true ; this . error = null ; return this . backend . getBucket ( this . bucketName ) . then ( ( bucket ) => { this . bucket = bucket ; this . uploadConfig = this . backend . getUploadConfig ( this . bucket , this . currentFolder ) ; return this . backend . getContents ( bucket , this . currentFolder ) ; } ) . then ( ( contents ) => { function compareObjectNames ( a , b ) { var nameA = a . getPath ( ) . name ( ) . toLowerCase ( ) ; var nameB = b . getPath ( ) . name ( ) . toLowerCase ( ) ; if ( nameA < nameB ) { return - 1 ; } if ( nameA > nameB ) { return 1 ; } return 0 ; } this . folders = contents . folders . sort ( compareObjectNames ) ; this . files = contents . files . sort ( compareObjectNames ) ; return this . backend . getDeletedContents ( this . bucket , this . currentFolder ) . then ( ( contents ) => { contents . folders = contents . folders . filter ( ( folder ) => { for ( var i = 0 ; i < this . folders . length ; i ++ ) { if ( this . folders [ i ] . getPath ( ) . equals ( folder . getPath ( ) ) ) { return false ; } } return true ; } ) ; return contents ; } ) . then ( ( contents ) => { function compareObjectNames ( a , b ) { var nameA = a . getPath ( ) . name ( ) . toLowerCase ( ) ; var nameB = b . getPath ( ) . name ( ) . toLowerCase ( ) ; if ( nameA < nameB ) { return - 1 ; } if ( nameA > nameB ) { return 1 ; } return 0 ; } this . deletedFolders = contents . folders . sort ( compareObjectNames ) ; this . deletedFiles = contents . files . sort ( compareObjectNames ) ; } ) . catch ( ( error ) => { this . error = error ; } ) ; } ) . catch ( ( error ) => { this . error = error ; } ) . then ( ( ) => { this . working = false ; this . $rootScope . $digest ( ) ; } ) ; } /**
     * Toggle the working status of this bucket. Useful for toggling callbacks.
     */ public toggleWorking ( state ) { this . working = state ; this . $rootScope . $digest ( ) ; } /**
     * Navigate to a folder.
     */ public navigateFolder ( folder ) { this . currentFolder = folder ; return this . loadContents ( ) ; } /**
     * Navigate to the parent folder.
     */ public navigateParent ( ) { this . currentFolder = this . currentFolder . parent ( ) ; return this . loadContents ( ) ; } /**
     * Create a folder.
     */ public createFolder ( ) { let folderRegex = new RegExp ( '^[\\w\\.\\-]+$' ) ; if ( ! folderRegex . test ( this . folderName ) ) { this . error = new Error ( 'Invalid folder name!' ) ; return ; } let folderPath = this . currentFolder . getPath ( ) . clone ( ) . push ( `${ this . folderName }/` ) ; this . working = true ; this . error = null ; return this . backend . createFolder ( this . bucket , new Folder ( folderPath ) ) . then ( ( ) => { this . folderName = '' ; return this . loadContents ( ) ; } ) . catch ( ( ) => { this . error = new Error ( 'Failed to create folder' ) ; } ) ; } /**
     * Delete a folder and it's contents.
     */ public deleteFolder ( folder ) { this . working = true ; this . error = null ; return this . backend . deleteFolder ( this . bucket , folder ) . then ( ( ) => { return this . loadContents ( ) ; } ) . catch ( ( ) => { this . error = new Error ( 'Failed to delete folder' ) ; } ) ; } /**
     * Load file versions.
     */ public loadFileVersions ( file ) { return this . backend . getFileVersions ( this . bucket , file ) ; } /**
     * Delete a file.
     */ public deleteFile ( file ) { this . working = true ; this . error = null ; return this . backend . deleteFile ( this . bucket , file ) . then ( ( ) => { return this . loadContents ( ) ; } ) . catch ( ( ) => { this . error = new Error ( 'Failed to delete file' ) ; } ) ; } /**
     * Returns true if the current folder is at the bucket prefix
     */ public isAtBucketPrefix ( ) { return this . currentFolder . getPath ( ) . toString ( ) === this . awsBucketPrefix ; } }