import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import { WebsocketConsumerStatusMessage } from '../data/websocket-consumer-status-message'; export enum FileStatusPhase { STARTED = 0, UPLOADING = 1, PROCESSING = 2, SUCCESS = 3, FAILED = 4 } export class FileStatus { filename: string taskId: string phase: FileStatusPhase = FileStatusPhase.STARTED 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: return this.currentPhaseProgress / this.currentPhaseMaxProgress * 0.8 + 0.2 case FileStatusPhase.SUCCESS: case FileStatusPhase.FAILED: return 1.0 } } updateProgress(status: FileStatusPhase, currentProgress?: number, maxProgress?: number) { if (status >= this.phase) { this.phase = status if (currentProgress) { this.currentPhaseProgress = currentProgress } if (maxProgress) { this.currentPhaseMaxProgress = maxProgress } } } } @Injectable({ providedIn: 'root' }) export class ConsumerStatusService { constructor() { } private statusWebSocked: WebSocket consumerStatus: FileStatus[] = [] private documentConsumptionFinishedSubject = new Subject() private documentConsumptionFailedSubject = new Subject() private get(taskId: string, filename?: string) { let status = this.consumerStatus.find(e => e.taskId == taskId) || this.consumerStatus.find(e => e.filename == filename) if (!status) { status = new FileStatus() this.consumerStatus.push(status) } status.taskId = taskId status.filename = filename return status } newFileUpload(): FileStatus { let status = new FileStatus() this.consumerStatus.push(status) return status } connect() { this.disconnect() this.statusWebSocked = new WebSocket("ws://localhost:8000/ws/status/"); this.statusWebSocked.onmessage = (ev) => { let statusMessage: WebsocketConsumerStatusMessage = JSON.parse(ev['data']) let status = this.get(statusMessage.task_id, statusMessage.filename) status.updateProgress(FileStatusPhase.PROCESSING, statusMessage.current_progress, statusMessage.max_progress) status.message = statusMessage.message status.documentId = statusMessage.document_id if (statusMessage.status == "SUCCESS") { status.phase = FileStatusPhase.SUCCESS this.documentConsumptionFinishedSubject.next(status) } if (statusMessage.status == "FAILED") { status.phase = FileStatusPhase.FAILED this.documentConsumptionFailedSubject.next(status) } } } disconnect() { if (this.statusWebSocked) { this.statusWebSocked.close() this.statusWebSocked = null } } dismiss(status: FileStatus) { let index = this.consumerStatus.findIndex(s => s.filename == status.filename) if (index > -1) { this.consumerStatus.splice(index, 1) } } onDocumentConsumptionFinished() { return this.documentConsumptionFinishedSubject } onDocumentConsumptionFailed() { return this.documentConsumptionFailedSubject } }