2020-11-07 12:05:15 +01:00
import { Injectable } from '@angular/core' ;
import { Subject } from 'rxjs' ;
2021-02-02 16:22:36 +01:00
import { environment } from 'src/environments/environment' ;
2021-01-26 00:51:45 +01:00
import { WebsocketConsumerStatusMessage } from '../data/websocket-consumer-status-message' ;
export enum FileStatusPhase {
STARTED = 0 ,
UPLOADING = 1 ,
PROCESSING = 2 ,
SUCCESS = 3 ,
FAILED = 4
}
2021-01-28 22:06:02 +01:00
export const FILE_STATUS_MESSAGES = {
"document_already_exists" : $localize ` Document already exists. ` ,
"file_not_found" : $localize ` File not found. ` ,
2021-02-02 13:10:51 +01:00
"pre_consume_script_not_found" : $localize ` :Pre-Consume is a term that appears like that in the documentation as well and does not need a specific translation:Pre-consume script does not exist. ` ,
"pre_consume_script_error" : $localize ` :Pre-Consume is a term that appears like that in the documentation as well and does not need a specific translation:Error while executing pre-consume script. ` ,
"post_consume_script_not_found" : $localize ` :Post-Consume is a term that appears like that in the documentation as well and does not need a specific translation:Post-consume script does not exist. ` ,
"post_consume_script_error" : $localize ` :Post-Consume is a term that appears like that in the documentation as well and does not need a specific translation:Error while executing post-consume script. ` ,
2021-01-28 22:06:02 +01:00
"new_file" : $localize ` Received new file. ` ,
"unsupported_type" : $localize ` File type not supported. ` ,
"parsing_document" : $localize ` Processing document... ` ,
"generating_thumbnail" : $localize ` Generating thumbnail... ` ,
"parse_date" : $localize ` Retrieving date from document... ` ,
"save_document" : $localize ` Saving document... ` ,
"finished" : $localize ` Finished. `
}
2021-01-26 00:51:45 +01:00
export class FileStatus {
filename : string
taskId : string
2021-01-26 02:32:45 -08:00
phase : FileStatusPhase = FileStatusPhase . STARTED
2021-01-26 00:51:45 +01:00
currentPhaseProgress : number
currentPhaseMaxProgress : number
message : string
documentId : number
getProgress ( ) : number {
switch ( this . phase ) {
case FileStatusPhase . STARTED :
return 0.0
case FileStatusPhase . UPLOADING :
return this . currentPhaseProgress / this . currentPhaseMaxProgress * 0.2
case FileStatusPhase . PROCESSING :
2021-01-26 02:32:45 -08:00
return ( this . currentPhaseProgress / this . currentPhaseMaxProgress * 0.8 ) + 0.2
2021-01-26 00:51:45 +01:00
case FileStatusPhase . SUCCESS :
case FileStatusPhase . FAILED :
return 1.0
}
}
updateProgress ( status : FileStatusPhase , currentProgress? : number , maxProgress? : number ) {
if ( status >= this . phase ) {
this . phase = status
2021-01-27 15:23:29 +01:00
if ( currentProgress != null ) {
2021-01-26 00:51:45 +01:00
this . currentPhaseProgress = currentProgress
}
2021-01-27 15:23:29 +01:00
if ( maxProgress != null ) {
2021-01-26 00:51:45 +01:00
this . currentPhaseMaxProgress = maxProgress
}
}
}
2020-11-07 12:05:15 +01:00
}
@Injectable ( {
providedIn : 'root'
} )
export class ConsumerStatusService {
constructor ( ) { }
2021-02-02 16:22:36 +01:00
private statusWebSocket : WebSocket
2020-11-07 12:05:15 +01:00
2021-01-26 01:10:39 +01:00
private consumerStatus : FileStatus [ ] = [ ]
2021-01-27 17:28:11 +01:00
private documentDetectedSubject = new Subject < FileStatus > ( )
2020-11-07 12:05:15 +01:00
private documentConsumptionFinishedSubject = new Subject < FileStatus > ( )
private documentConsumptionFailedSubject = new Subject < FileStatus > ( )
2021-01-26 00:51:45 +01:00
private get ( taskId : string , filename? : string ) {
2021-01-27 15:23:29 +01:00
let status = this . consumerStatus . find ( e = > e . taskId == taskId ) || this . consumerStatus . find ( e = > e . filename == filename && e . taskId == null )
2021-01-27 17:28:11 +01:00
let created = false
2021-01-26 00:51:45 +01:00
if ( ! status ) {
status = new FileStatus ( )
this . consumerStatus . push ( status )
2021-01-27 17:28:11 +01:00
created = true
2021-01-26 00:51:45 +01:00
}
status . taskId = taskId
status . filename = filename
2021-01-27 17:28:11 +01:00
return { 'status' : status , 'created' : created }
2021-01-26 00:51:45 +01:00
}
2021-01-26 01:10:39 +01:00
newFileUpload ( filename : string ) : FileStatus {
2021-01-26 00:51:45 +01:00
let status = new FileStatus ( )
2021-01-26 01:10:39 +01:00
status . filename = filename
2021-01-26 00:51:45 +01:00
this . consumerStatus . push ( status )
return status
}
2021-01-26 01:10:39 +01:00
getConsumerStatus ( phase? : FileStatusPhase ) {
2021-01-28 10:54:56 +01:00
if ( phase != null ) {
2021-01-26 01:10:39 +01:00
return this . consumerStatus . filter ( s = > s . phase == phase )
} else {
return this . consumerStatus
}
}
2021-01-28 10:54:56 +01:00
getConsumerStatusNotCompleted() {
return this . consumerStatus . filter ( s = > s . phase < FileStatusPhase . SUCCESS )
}
2021-01-27 18:34:59 +01:00
getConsumerStatusCompleted() {
return this . consumerStatus . filter ( s = > s . phase == FileStatusPhase . FAILED || s . phase == FileStatusPhase . SUCCESS )
}
2020-11-07 12:05:15 +01:00
connect() {
this . disconnect ( )
2021-02-02 16:22:36 +01:00
this . statusWebSocket = new WebSocket ( ` ${ environment . webSocketProtocol } // ${ environment . webSocketHost } /ws/status/ ` ) ;
this . statusWebSocket . onmessage = ( ev ) = > {
2021-01-26 00:51:45 +01:00
let statusMessage : WebsocketConsumerStatusMessage = JSON . parse ( ev [ 'data' ] )
2020-11-07 12:05:15 +01:00
2021-01-27 17:28:11 +01:00
let statusMessageGet = this . get ( statusMessage . task_id , statusMessage . filename )
let status = statusMessageGet . status
let created = statusMessageGet . created
2021-01-26 00:51:45 +01:00
status . updateProgress ( FileStatusPhase . PROCESSING , statusMessage . current_progress , statusMessage . max_progress )
2021-01-28 22:06:02 +01:00
if ( statusMessage . message && statusMessage . message in FILE_STATUS_MESSAGES ) {
status . message = FILE_STATUS_MESSAGES [ statusMessage . message ]
} else if ( statusMessage . message ) {
status . message = statusMessage . message
}
2021-01-26 00:51:45 +01:00
status . documentId = statusMessage . document_id
2020-11-07 12:05:15 +01:00
2021-01-27 17:28:11 +01:00
if ( created && statusMessage . status == 'STARTING' ) {
this . documentDetectedSubject . next ( status )
}
2021-01-26 00:51:45 +01:00
if ( statusMessage . status == "SUCCESS" ) {
status . phase = FileStatusPhase . SUCCESS
this . documentConsumptionFinishedSubject . next ( status )
2020-11-07 12:05:15 +01:00
}
2021-01-26 00:51:45 +01:00
if ( statusMessage . status == "FAILED" ) {
status . phase = FileStatusPhase . FAILED
this . documentConsumptionFailedSubject . next ( status )
2020-11-07 12:05:15 +01:00
}
}
}
2021-01-27 16:04:06 +01:00
fail ( status : FileStatus , message : string ) {
status . message = message
status . phase = FileStatusPhase . FAILED
this . documentConsumptionFailedSubject . next ( status )
}
2020-11-07 12:05:15 +01:00
disconnect() {
2021-02-02 16:22:36 +01:00
if ( this . statusWebSocket ) {
this . statusWebSocket . close ( )
this . statusWebSocket = null
2020-11-07 12:05:15 +01:00
}
}
dismiss ( status : FileStatus ) {
let index = this . consumerStatus . findIndex ( s = > s . filename == status . filename )
if ( index > - 1 ) {
this . consumerStatus . splice ( index , 1 )
}
}
2021-01-26 02:52:16 -08:00
dismissAll() {
2021-01-27 16:04:06 +01:00
this . consumerStatus = this . consumerStatus . filter ( status = > status . phase < FileStatusPhase . SUCCESS )
2021-01-26 02:52:16 -08:00
}
2020-11-07 12:05:15 +01:00
onDocumentConsumptionFinished() {
return this . documentConsumptionFinishedSubject
}
onDocumentConsumptionFailed() {
return this . documentConsumptionFailedSubject
}
2021-01-27 17:28:11 +01:00
onDocumentDetected() {
return this . documentDetectedSubject
}
2020-11-07 12:05:15 +01:00
}