blob: a55853f60acdb70169c1616abd0c73551eb404e0 [file] [log] [blame]
daniel.teske70445a72018-10-05 09:15:42 +02001class ProgressStats {
2
evansiroky5348a6f2019-01-05 15:39:28 -08003 constructor(trackerName, totalTasks) {
4 this.trackerName = trackerName
5 this.totalTasks = totalTasks
6 this.taskCounter = 0
7 this.referenceLength = 5
daniel.teske70445a72018-10-05 09:15:42 +02008 this.timestamps = []
9 }
10
11 logNext() {
evansiroky5348a6f2019-01-05 15:39:28 -080012 this.taskCounter++
daniel.teske70445a72018-10-05 09:15:42 +020013 this.timestamps.push({
evansiroky5348a6f2019-01-05 15:39:28 -080014 "index": this.taskCounter,
daniel.teske70445a72018-10-05 09:15:42 +020015 "timestamp": Date.now()
16 })
17 }
18
19 /**
evansiroky5348a6f2019-01-05 15:39:28 -080020 * Begin a new task. Print the current progress and then increment the number of tasks.
21 * @param {string} A short message about the current task progress
22 * @param {[boolean]} logTimeLeft whether or not to log the time left.
23 */
24 beginTask (message, logTimeLeft) {
25 this.printStats(message, logTimeLeft)
26 this.logNext()
27 }
28
29 /**
30 * Print the current progress.
31 * @param {string} A short message about the current task progress
32 * @param {[boolean]} logTimeLeft whether or not to log the time left.
33 */
34 printStats (message, logTimeLeft) {
35 message = `${message}; ${this.trackerName} progress: ${this.getPercentage()}% done`
36 if (logTimeLeft) {
37 message = `${message} - ${this.getTimeLeft()} left`
38 }
39 console.log(message)
40 }
41
42 /**
daniel.teske70445a72018-10-05 09:15:42 +020043 * calculates the percentage of finished downloads
44 * @returns {string}
45 */
46 getPercentage() {
evansiroky5348a6f2019-01-05 15:39:28 -080047 var current = (this.taskCounter / this.totalTasks)
daniel.teske70445a72018-10-05 09:15:42 +020048 return Math.round(current * 1000.0) / 10.0
49 }
50
51 /**
52 * calculates the time left and outputs it in human readable format
53 * calculation is based on a reference length, that can be defined.
54 *
55 * @returns {string}
56 */
evansiroky5348a6f2019-01-05 15:39:28 -080057 getTimeLeft () {
58 if(this.taskCounter <= this.referenceLength) {
daniel.teske70445a72018-10-05 09:15:42 +020059 //number of reference downloads must exist before left time can be predicted
60 return "? minutes"
61 }
62 var processDurationInSeconds = (Date.now() - this.timestamps[0].timestamp) / 1000
63 if(processDurationInSeconds < 60){
64 //process must run longer than 60seconds before left time can be predicted
65 return "? minutes"
66 }
67
68 var indexOfStepsBefore = this.timestamps.findIndex((t) => {
evansiroky5348a6f2019-01-05 15:39:28 -080069 return t.index === (this.taskCounter - this.referenceLength)
daniel.teske70445a72018-10-05 09:15:42 +020070 })
71 var lastSteps = this.timestamps[indexOfStepsBefore];
72 var millisOflastSteps = Date.now() - lastSteps.timestamp
evansiroky5348a6f2019-01-05 15:39:28 -080073 var downloadsLeft = this.totalTasks - this.taskCounter
74 var millisecondsLeft = (millisOflastSteps / this.referenceLength) * downloadsLeft
daniel.teske70445a72018-10-05 09:15:42 +020075 return this.formatMilliseconds(millisecondsLeft)
76 }
77
78 /**
79 * inspired from https://stackoverflow.com/questions/19700283/how-to-convert-time-milliseconds-to-hours-min-sec-format-in-javascript
80 * @param millisec
81 * @returns {string}
82 */
83 formatMilliseconds(millisec) {
84 var seconds = (millisec / 1000).toFixed(1);
85 var minutes = (millisec / (1000 * 60)).toFixed(1);
86 var hours = (millisec / (1000 * 60 * 60)).toFixed(1);
87 var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1);
88 if (seconds < 60) {
89 return seconds + " seconds";
90 } else if (minutes < 60) {
91 return minutes + " minutes";
92 } else if (hours < 24) {
93 return hours + " hours";
94 } else {
95 return days + " days"
96 }
97 }
98
99}
100
evansiroky5348a6f2019-01-05 15:39:28 -0800101module.exports = ProgressStats