import ServiceElectron from '../service.electron' ; import Logger from '../../tools/env.logger' ; import ServiceStreams from "../service.streams" ; import MergeFiles from '../../controllers/features/merge/merge.files' ; import MergeDiscover from '../../controllers/features/merge/merge.discover' ; import MergeFormat from '../../controllers/features/merge/merge.format' ; import { IPCMessages } from '../service.electron' ; import { Subscription } from '../../tools/index' ; import { IService } from '../../interfaces/interface.service' ; import { Progress } from "indexer-neon" ; import { IFile as IMergeFileRequest } from '../../../../common/ipc/electron.ipc.messages/merge.files.request' ; import { IMapItem } from '../../controllers/files.parsers/interface' ; import * as moment from 'moment-timezone' ; class description class ServiceMergeFiles implements IService { private _logger : Logger = new Logger ( 'ServiceMergeFiles' ) ; private _subscriptions : { [ key ] : Subscription ; } = { } ; private _tasks : { merge : Map < string , MergeFiles > ; } = { merge : new Map < string , MergeFiles > ( ) , } ; returns public init ( ) { return new Promise ( ( resolve , reject ) => { Promise . all ( [ ServiceElectron . IPC . subscribe ( IPCMessages . MergeFilesRequest , this . _onMergeFilesRequest . bind ( this ) ) . then ( ( subscription ) => { this . _subscriptions . MergeFilesRequest = subscription ; } ) , ServiceElectron . IPC . subscribe ( IPCMessages . MergeFilesTestRequest , this . _onMergeFilesTestRequest . bind ( this ) ) . then ( ( subscription ) => { this . _subscriptions . MergeFilesTestRequest = subscription ; } ) , ServiceElectron . IPC . subscribe ( IPCMessages . MergeFilesTimezonesRequest , this . _onMergeFilesTimezonesRequest . bind ( this ) ) . then ( ( subscription ) => { this . _subscriptions . MergeFilesTimezonesRequest = subscription ; } ) , ServiceElectron . IPC . subscribe ( IPCMessages . MergeFilesDiscoverRequest , this . _onMergeFilesDiscoverRequest . bind ( this ) ) . then ( ( subscription ) => { this . _subscriptions . MergeFilesDiscoverRequest = subscription ; } ) , ServiceElectron . IPC . subscribe ( IPCMessages . MergeFilesFormatRequest , this . _onMergeFilesFormatRequest . bind ( this ) ) . then ( ( subscription ) => { this . _subscriptions . MergeFilesFormatRequest = subscription ; } ) , ] ) . then ( ( ) => { this . _subscriptions . onSessionClosed = ServiceStreams . getSubjects ( ) . onSessionClosed . subscribe ( this . _onSessionClosed . bind ( this ) ) ; resolve ( ) ; } ) . catch ( ( error ) => { this . _logger . error ( `Fail to init module due error: ${ error . message }` ) ; reject ( error ) ; } ) ; } ) ; } public destroy ( ) { return new Promise ( ( resolve ) => { Object . keys ( this . _subscriptions ) . forEach ( ( key ) => { this . _subscriptions [ key ] . destroy ( ) ; } ) ; resolve ( ) ; } ) ; } public getName ( ) { return 'ServiceMergeFiles' ; } private _onMergeFilesTimezonesRequest ( request , response ) { response ( new IPCMessages . MergeFilestimezoneResponse ( { zones : moment . tz . names ( ) , } ) ) ; } private _onMergeFilesRequest ( request , response ) { const req = request as IPCMessages . MergeFilesRequest ; const dest = ServiceStreams . getStreamFile ( req . session ) ; if ( dest instanceof Error ) { return response ( new IPCMessages . MergeFilesResponse ( { written : 0 , id : req . id , error : `Fail merge file due error: ${ dest . message }` , } ) ) ; } const controller = new MergeFiles ( req . session , req . files . map ( ( file ) => { return { file : file . file , offset : file . offset === undefined ? 0 : file . offset , parser : file . parser , year : file . year , format : file . format , } ; } ) , ( ticks ) => { ServiceStreams . updateProgressSession ( req . id , ticks . ellapsed / ticks . total , req . session ) ; } ) ; controller . write ( ( map ) => { ServiceStreams . pushToStreamFileMap ( dest . streamId , map ) ; } ) . then ( ( written ) => { response ( new IPCMessages . MergeFilesResponse ( { written : written , id : req . id , } ) ) ; } ) . catch ( ( mergeError ) => { response ( new IPCMessages . MergeFilesResponse ( { written : 0 , id : req . id , error : mergeError . message , } ) ) ; } ) . cancel ( ( ) => { response ( new IPCMessages . MergeFilesResponse ( { written : 0 , id : req . id , error : `Operation is canceled` , } ) ) ; } ) . finally ( ( ) => { this . _tasks . merge . delete ( req . session ) ; ServiceStreams . removeProgressSession ( req . id ) ; } ) ; this . _tasks . merge . set ( req . session , controller ) ; } private _onMergeFilesDiscoverRequest ( request , response ) { const req = request as IPCMessages . MergeFilesDiscoverRequest ; this . _discover ( req . files ) . then ( ( processed ) => { response ( new IPCMessages . MergeFilesDiscoverResponse ( { id : req . id , files : processed , } ) ) ; } ) . catch ( ( error ) => { response ( new IPCMessages . MergeFilesDiscoverResponse ( { id : req . id , files : [ ] , error : error . message , } ) ) ; } ) ; } private _onMergeFilesFormatRequest ( request , response ) { const req = request as IPCMessages . MergeFilesFormatRequest ; this . _format ( req . format ) . then ( ( ) => { response ( new IPCMessages . MergeFilesFormatResponse ( { } ) ) ; } ) . catch ( ( error ) => { response ( new IPCMessages . MergeFilesFormatResponse ( { error : error . message , } ) ) ; } ) ; } private _onMergeFilesTestRequest ( request , response ) { const req = request as IPCMessages . MergeFilesTestRequest ; this . _test ( req . file , req . format , req . year ) . then ( ( results ) => { response ( new IPCMessages . MergeFilesTestResponse ( { id : req . id , format : results . format , error : results . error , maxTime : results . maxTime , minTime : results . minTime , path : req . file , } ) ) ; } ) . catch ( ( error ) => { response ( new IPCMessages . MergeFilesTestResponse ( { id : req . id , error : error . message , path : req . file , } ) ) ; } ) ; } private _test ( file , format , year ) { return new Promise ( ( resolve , reject ) => { const controller = new MergeDiscover ( [ { file : file , format : format , year : year } ] ) ; controller . discover ( ) . then ( ( processed ) => { if ( processed . length !== 1 ) { return reject ( new Error ( `Unexpected count of results: ${ processed . length }. Expected 1.` ) ) ; } resolve ( processed [ 0 ] ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } private _discover ( files ) { return new Promise ( ( resolve , reject ) => { const controller = new MergeDiscover ( files . map ( ( file ) => { return { file : file } ; } ) ) ; controller . discover ( ) . then ( ( processed ) => { resolve ( processed ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } private _format ( format ) { return new Promise ( ( resolve , reject ) => { const controller = new MergeFormat ( format ) ; controller . validate ( ) . then ( ( ) => { resolve ( ) ; } ) . catch ( ( error ) => { reject ( error ) ; } ) ; } ) ; } private _onSessionClosed ( guid ) { const controller = this . _tasks . merge . get ( guid ) ; if ( controller === undefined ) { return ; } controller . abort ( ) . then ( ( ) => { this . _logger . debug ( `Task is aborted` ) ; } ) ; } } export default ( new ServiceMergeFiles ( ) ) ;