aboutsummaryrefslogtreecommitdiff
path: root/progressStats.js
blob: a55853f60acdb70169c1616abd0c73551eb404e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
class ProgressStats {

    constructor(trackerName, totalTasks) {
        this.trackerName = trackerName
        this.totalTasks = totalTasks
        this.taskCounter = 0
        this.referenceLength = 5
        this.timestamps = []
    }

    logNext() {
        this.taskCounter++
        this.timestamps.push({
            "index": this.taskCounter,
            "timestamp": Date.now()
        })
    }

    /**
     * Begin a new task.  Print the current progress and then increment the number of tasks.
     * @param  {string}    A short message about the current task progress
     * @param  {[boolean]} logTimeLeft whether or not to log the time left.
     */
    beginTask (message, logTimeLeft) {
      this.printStats(message, logTimeLeft)
      this.logNext()
    }

    /**
     * Print the current progress.
     * @param  {string}    A short message about the current task progress
     * @param  {[boolean]} logTimeLeft whether or not to log the time left.
     */
    printStats (message, logTimeLeft) {
      message = `${message}; ${this.trackerName} progress: ${this.getPercentage()}% done`
      if (logTimeLeft) {
        message = `${message} - ${this.getTimeLeft()} left`
      }
      console.log(message)
    }

    /**
     * calculates the percentage of finished downloads
     * @returns {string}
     */
    getPercentage() {
        var current = (this.taskCounter / this.totalTasks)
        return Math.round(current * 1000.0) / 10.0
    }

    /**
     * calculates the time left and outputs it in human readable format
     * calculation is based on a reference length, that can be defined.
     *
     * @returns {string}
     */
    getTimeLeft () {
        if(this.taskCounter <= this.referenceLength) {
            //number of reference downloads must exist before left time can be predicted
            return "? minutes"
        }
        var processDurationInSeconds = (Date.now() - this.timestamps[0].timestamp) / 1000
        if(processDurationInSeconds < 60){
            //process must run longer than 60seconds before left time can be predicted
            return "? minutes"
        }

        var indexOfStepsBefore = this.timestamps.findIndex((t) => {
            return t.index === (this.taskCounter - this.referenceLength)
        })
        var lastSteps = this.timestamps[indexOfStepsBefore];
        var millisOflastSteps = Date.now() - lastSteps.timestamp
        var downloadsLeft = this.totalTasks - this.taskCounter
        var millisecondsLeft = (millisOflastSteps / this.referenceLength) * downloadsLeft
        return this.formatMilliseconds(millisecondsLeft)
    }

    /**
     * inspired from https://stackoverflow.com/questions/19700283/how-to-convert-time-milliseconds-to-hours-min-sec-format-in-javascript
     * @param millisec
     * @returns {string}
     */
    formatMilliseconds(millisec) {
        var seconds = (millisec / 1000).toFixed(1);
        var minutes = (millisec / (1000 * 60)).toFixed(1);
        var hours = (millisec / (1000 * 60 * 60)).toFixed(1);
        var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1);
        if (seconds < 60) {
            return seconds + " seconds";
        } else if (minutes < 60) {
            return minutes + " minutes";
        } else if (hours < 24) {
            return hours + " hours";
        } else {
            return days + " days"
        }
    }

}

module.exports = ProgressStats