import { Injectable , NgZone } from '@angular/core' ; import { remote } from 'electron' ; import { Observable } from "rxjs/Observable" ; import { catchError } from "rxjs/operators" ; import { of } from "rxjs/observable/of" ; import * as fs from 'fs' ; import * as path from 'path' ; import { Subject } from "rxjs/Subject" ; import FileFilter = Electron . FileFilter ; import Size = Electron . Size ; let { dialog , screen } = remote ; let actionOutputName = 'actions.json' ; @ Injectable ( ) export class FileProvider { selectedFolder : string ; selectedSaveFolder : string ; filesChange : Subject < string [ ] > = new Subject < string [ ] > ( ) ; filesLoading : Subject < boolean > = new Subject < boolean > ( ) ; static systemResolution : Size ; constructor ( private ngZone ) { FileProvider . systemResolution = screen . getPrimaryDisplay ( ) . size ; } param { "openFile" | "openDirectory" } properties param filters { FileFilter [ ] } returns { Observable < string > } showOpenDialog ( properties ? , filters ? ) { return new Observable < string > ( ( observer ) => { if ( ! properties ) { properties = 'openDirectory' ; } dialog . showOpenDialog ( { properties : [ properties ] , ... ( filters && { filters : filters } ) } , ( path ) => { if ( ! path ) { observer . error ( ) ; } else { observer . next ( path [ 0 ] ) ; } observer . complete ( ) ; } ) ; } ) . pipe ( catchError ( this . handleError ( 'showOpenDialog()' , '' ) ) ) ; } showSaveDialog ( filters ? ) { return new Observable < string > ( ( observer ) => { dialog . showSaveDialog ( undefined , { title : 'Save annotations' , ... ( filters && { filters : filters } ) } , filename => { if ( ! filename ) { observer . error ( ) ; } else { observer . next ( filename ) ; } observer . complete ( ) ; } ) ; } ) . pipe ( catchError ( this . handleError ( 'showSaveDialog()' , '' ) ) ) ; } param { string } directoryPath param { string [ ] } extensions returns { Observable < string [ ] > } listFiles ( directoryPath , extensions ? ) { return new Observable < string [ ] > ( ( observer ) => { this . ngZone . run ( ( ) => { this . filesLoading . next ( true ) ; } ) ; if ( ! fs . existsSync ( directoryPath ) ) { observer . error ( 'Directory does not exist!' ) ; observer . complete ( ) ; } else { fs . readdir ( directoryPath , ( err , files ) => { if ( err ) { console . error ( `Cannot read path ${ err }!` ) ; } else { if ( ! extensions ) { observer . next ( files ) ; } else { let outFiles = files . filter ( ( file ) => { return extensions . indexOf ( path . extname ( file ) ) != - 1 ; } ) ; observer . next ( outFiles ) ; } observer . complete ( ) ; } } ) ; } } ) . pipe ( catchError ( ( error ) : Observable < any > => { this . ngZone . run ( ( ) => { this . filesLoading . next ( false ) ; } ) ; console . log ( `Caught error when listing files: ${ error }` ) ; return of ( null ) ; } ) ) ; } param data saveFiles ( data ) { return new Observable < any > ( ( observer ) => { console . log ( 'saving the following: ' ) ; console . log ( data [ 'frames' ] ) ; for ( let imageFile in data [ 'frames' ] ) { if ( data . hasOwnProperty ( imageFile ) ) { let _imageFile = path . basename ( imageFile ) ; let outputName = _imageFile . replace ( path . extname ( _imageFile ) , ".json" ) ; let _data = JSON . stringify ( data [ imageFile ] , null , 4 ) ; console . log ( 'saveFiles is going to save ' ) ; console . log ( _imageFile ) ; fs . writeFile ( path . join ( this . selectedSaveFolder , outputName ) , _data , 'utf8' , ( err ) => { if ( err ) { observer . error ( err ) ; } else { observer . next ( ) ; } } ) ; } } console . log ( 'saving the following: ' ) ; let _data = JSON . stringify ( data [ 'actions' ] , null , 4 ) ; console . log ( _data ) ; fs . writeFile ( path . join ( this . selectedSaveFolder , actionOutputName ) , _data , 'utf8' , ( err ) => { if ( err ) { observer . error ( err ) ; } else { observer . next ( ) ; } } ) ; observer . complete ( ) ; } ) . pipe ( catchError ( this . handleError ( 'File.saveFileDialog()' , null ) ) ) ; } param data param { string } location returns { Observable < any > } saveFile ( data , location ) { return new Observable < any > ( ( observer ) => { let _data = JSON . stringify ( data , null , 4 ) ; fs . writeFile ( location , _data , 'utf8' , ( err ) => { if ( err ) { observer . error ( err ) ; } else { observer . next ( true ) ; } observer . complete ( ) ; } ) ; } ) . pipe ( catchError ( this . handleError ( 'File.saveFiles()' , false ) ) ) ; } loadJSON ( path ) { return new Observable < any > ( ( observer ) => { fs . readFile ( path , ( err , data ) => { if ( err ) { observer . error ( err ) ; } else { observer . next ( JSON . parse ( data . toString ( ) ) ) ; } observer . complete ( ) ; } ) ; } ) . pipe ( catchError ( this . handleError ( 'loadJSON()' , null ) ) ) ; } param operation param result private handleError < T > ( operation = 'operation' , result ? ) { return ( error ) : Observable < T > => { console . error ( `Caught error at ${ operation }: ${ error }` ) ; return of ( result as T ) ; } ; } static setHasUnsavedChanges ( hasUnsavedChanges ) { remote . getGlobal ( 'shared' ) . hasUnsavedChanges = hasUnsavedChanges ; } }