~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/js/swfupload/plugins/swfupload.speed.js

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        Speed Plug-in
 
3
        
 
4
        Features:
 
5
                *Adds several properties to the 'file' object indicated upload speed, time left, upload time, etc.
 
6
                        - currentSpeed -- String indicating the upload speed, bytes per second
 
7
                        - averageSpeed -- Overall average upload speed, bytes per second
 
8
                        - movingAverageSpeed -- Speed over averaged over the last several measurements, bytes per second
 
9
                        - timeRemaining -- Estimated remaining upload time in seconds
 
10
                        - timeElapsed -- Number of seconds passed for this upload
 
11
                        - percentUploaded -- Percentage of the file uploaded (0 to 100)
 
12
                        - sizeUploaded -- Formatted size uploaded so far, bytes
 
13
                
 
14
                *Adds setting 'moving_average_history_size' for defining the window size used to calculate the moving average speed.
 
15
                
 
16
                *Adds several Formatting functions for formatting that values provided on the file object.
 
17
                        - SWFUpload.speed.formatBPS(bps) -- outputs string formatted in the best units (Gbps, Mbps, Kbps, bps)
 
18
                        - SWFUpload.speed.formatTime(seconds) -- outputs string formatted in the best units (x Hr y M z S)
 
19
                        - SWFUpload.speed.formatSize(bytes) -- outputs string formatted in the best units (w GB x MB y KB z B )
 
20
                        - SWFUpload.speed.formatPercent(percent) -- outputs string formatted with a percent sign (x.xx %)
 
21
                        - SWFUpload.speed.formatUnits(baseNumber, divisionArray, unitLabelArray, fractionalBoolean)
 
22
                                - Formats a number using the division array to determine how to apply the labels in the Label Array
 
23
                                - factionalBoolean indicates whether the number should be returned as a single fractional number with a unit (speed)
 
24
                                    or as several numbers labeled with units (time)
 
25
        */
 
26
 
 
27
var SWFUpload;
 
28
if (typeof(SWFUpload) === "function") {
 
29
        SWFUpload.speed = {};
 
30
        
 
31
        SWFUpload.prototype.initSettings = (function (oldInitSettings) {
 
32
                return function () {
 
33
                        if (typeof(oldInitSettings) === "function") {
 
34
                                oldInitSettings.call(this);
 
35
                        }
 
36
                        
 
37
                        this.ensureDefault = function (settingName, defaultValue) {
 
38
                                this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
 
39
                        };
 
40
 
 
41
                        // List used to keep the speed stats for the files we are tracking
 
42
                        this.fileSpeedStats = {};
 
43
                        this.speedSettings = {};
 
44
 
 
45
                        this.ensureDefault("moving_average_history_size", "10");
 
46
                        
 
47
                        this.speedSettings.user_file_queued_handler = this.settings.file_queued_handler;
 
48
                        this.speedSettings.user_file_queue_error_handler = this.settings.file_queue_error_handler;
 
49
                        this.speedSettings.user_upload_start_handler = this.settings.upload_start_handler;
 
50
                        this.speedSettings.user_upload_error_handler = this.settings.upload_error_handler;
 
51
                        this.speedSettings.user_upload_progress_handler = this.settings.upload_progress_handler;
 
52
                        this.speedSettings.user_upload_success_handler = this.settings.upload_success_handler;
 
53
                        this.speedSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
 
54
                        
 
55
                        this.settings.file_queued_handler = SWFUpload.speed.fileQueuedHandler;
 
56
                        this.settings.file_queue_error_handler = SWFUpload.speed.fileQueueErrorHandler;
 
57
                        this.settings.upload_start_handler = SWFUpload.speed.uploadStartHandler;
 
58
                        this.settings.upload_error_handler = SWFUpload.speed.uploadErrorHandler;
 
59
                        this.settings.upload_progress_handler = SWFUpload.speed.uploadProgressHandler;
 
60
                        this.settings.upload_success_handler = SWFUpload.speed.uploadSuccessHandler;
 
61
                        this.settings.upload_complete_handler = SWFUpload.speed.uploadCompleteHandler;
 
62
                        
 
63
                        delete this.ensureDefault;
 
64
                };
 
65
        })(SWFUpload.prototype.initSettings);
 
66
 
 
67
        
 
68
        SWFUpload.speed.fileQueuedHandler = function (file) {
 
69
                if (typeof this.speedSettings.user_file_queued_handler === "function") {
 
70
                        file = SWFUpload.speed.extendFile(file);
 
71
                        
 
72
                        return this.speedSettings.user_file_queued_handler.call(this, file);
 
73
                }
 
74
        };
 
75
        
 
76
        SWFUpload.speed.fileQueueErrorHandler = function (file, errorCode, message) {
 
77
                if (typeof this.speedSettings.user_file_queue_error_handler === "function") {
 
78
                        file = SWFUpload.speed.extendFile(file);
 
79
                        
 
80
                        return this.speedSettings.user_file_queue_error_handler.call(this, file, errorCode, message);
 
81
                }
 
82
        };
 
83
 
 
84
        SWFUpload.speed.uploadStartHandler = function (file) {
 
85
                if (typeof this.speedSettings.user_upload_start_handler === "function") {
 
86
                        file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
 
87
                        return this.speedSettings.user_upload_start_handler.call(this, file);
 
88
                }
 
89
        };
 
90
        
 
91
        SWFUpload.speed.uploadErrorHandler = function (file, errorCode, message) {
 
92
                file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
 
93
                SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
 
94
 
 
95
                if (typeof this.speedSettings.user_upload_error_handler === "function") {
 
96
                        return this.speedSettings.user_upload_error_handler.call(this, file, errorCode, message);
 
97
                }
 
98
        };
 
99
        SWFUpload.speed.uploadProgressHandler = function (file, bytesComplete, bytesTotal) {
 
100
                this.updateTracking(file, bytesComplete);
 
101
                file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
 
102
 
 
103
                if (typeof this.speedSettings.user_upload_progress_handler === "function") {
 
104
                        return this.speedSettings.user_upload_progress_handler.call(this, file, bytesComplete, bytesTotal);
 
105
                }
 
106
        };
 
107
        
 
108
        SWFUpload.speed.uploadSuccessHandler = function (file, serverData) {
 
109
                if (typeof this.speedSettings.user_upload_success_handler === "function") {
 
110
                        file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
 
111
                        return this.speedSettings.user_upload_success_handler.call(this, file, serverData);
 
112
                }
 
113
        };
 
114
        SWFUpload.speed.uploadCompleteHandler = function (file) {
 
115
                file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
 
116
                SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
 
117
 
 
118
                if (typeof this.speedSettings.user_upload_complete_handler === "function") {
 
119
                        return this.speedSettings.user_upload_complete_handler.call(this, file);
 
120
                }
 
121
        };
 
122
        
 
123
        // Private: extends the file object with the speed plugin values
 
124
        SWFUpload.speed.extendFile = function (file, trackingList) {
 
125
                var tracking;
 
126
                
 
127
                if (trackingList) {
 
128
                        tracking = trackingList[file.id];
 
129
                }
 
130
                
 
131
                if (tracking) {
 
132
                        file.currentSpeed = tracking.currentSpeed;
 
133
                        file.averageSpeed = tracking.averageSpeed;
 
134
                        file.movingAverageSpeed = tracking.movingAverageSpeed;
 
135
                        file.timeRemaining = tracking.timeRemaining;
 
136
                        file.timeElapsed = tracking.timeElapsed;
 
137
                        file.percentUploaded = tracking.percentUploaded;
 
138
                        file.sizeUploaded = tracking.bytesUploaded;
 
139
 
 
140
                } else {
 
141
                        file.currentSpeed = 0;
 
142
                        file.averageSpeed = 0;
 
143
                        file.movingAverageSpeed = 0;
 
144
                        file.timeRemaining = 0;
 
145
                        file.timeElapsed = 0;
 
146
                        file.percentUploaded = 0;
 
147
                        file.sizeUploaded = 0;
 
148
                }
 
149
                
 
150
                return file;
 
151
        };
 
152
        
 
153
        // Private: Updates the speed tracking object, or creates it if necessary
 
154
        SWFUpload.prototype.updateTracking = function (file, bytesUploaded) {
 
155
                var tracking = this.fileSpeedStats[file.id];
 
156
                if (!tracking) {
 
157
                        this.fileSpeedStats[file.id] = tracking = {};
 
158
                }
 
159
                
 
160
                // Sanity check inputs
 
161
                bytesUploaded = bytesUploaded || tracking.bytesUploaded || 0;
 
162
                if (bytesUploaded < 0) {
 
163
                        bytesUploaded = 0;
 
164
                }
 
165
                if (bytesUploaded > file.size) {
 
166
                        bytesUploaded = file.size;
 
167
                }
 
168
                
 
169
                var tickTime = (new Date()).getTime();
 
170
                if (!tracking.startTime) {
 
171
                        tracking.startTime = (new Date()).getTime();
 
172
                        tracking.lastTime = tracking.startTime;
 
173
                        tracking.currentSpeed = 0;
 
174
                        tracking.averageSpeed = 0;
 
175
                        tracking.movingAverageSpeed = 0;
 
176
                        tracking.movingAverageHistory = [];
 
177
                        tracking.timeRemaining = 0;
 
178
                        tracking.timeElapsed = 0;
 
179
                        tracking.percentUploaded = bytesUploaded / file.size;
 
180
                        tracking.bytesUploaded = bytesUploaded;
 
181
                } else if (tracking.startTime > tickTime) {
 
182
                        this.debug("When backwards in time");
 
183
                } else {
 
184
                        // Get time and deltas
 
185
                        var now = (new Date()).getTime();
 
186
                        var lastTime = tracking.lastTime;
 
187
                        var deltaTime = now - lastTime;
 
188
                        var deltaBytes = bytesUploaded - tracking.bytesUploaded;
 
189
                        
 
190
                        if (deltaBytes === 0 || deltaTime === 0) {
 
191
                                return tracking;
 
192
                        }
 
193
                        
 
194
                        // Update tracking object
 
195
                        tracking.lastTime = now;
 
196
                        tracking.bytesUploaded = bytesUploaded;
 
197
                        
 
198
                        // Calculate speeds
 
199
                        tracking.currentSpeed = (deltaBytes * 8 ) / (deltaTime / 1000);
 
200
                        tracking.averageSpeed = (tracking.bytesUploaded * 8) / ((now - tracking.startTime) / 1000);
 
201
 
 
202
                        // Calculate moving average
 
203
                        tracking.movingAverageHistory.push(tracking.currentSpeed);
 
204
                        if (tracking.movingAverageHistory.length > this.settings.moving_average_history_size) {
 
205
                                tracking.movingAverageHistory.shift();
 
206
                        }
 
207
                        
 
208
                        tracking.movingAverageSpeed = SWFUpload.speed.calculateMovingAverage(tracking.movingAverageHistory);
 
209
                        
 
210
                        // Update times
 
211
                        tracking.timeRemaining = (file.size - tracking.bytesUploaded) * 8 / tracking.movingAverageSpeed;
 
212
                        tracking.timeElapsed = (now - tracking.startTime) / 1000;
 
213
                        
 
214
                        // Update percent
 
215
                        tracking.percentUploaded = (tracking.bytesUploaded / file.size * 100);
 
216
                }
 
217
                
 
218
                return tracking;
 
219
        };
 
220
        SWFUpload.speed.removeTracking = function (file, trackingList) {
 
221
                try {
 
222
                        trackingList[file.id] = null;
 
223
                        delete trackingList[file.id];
 
224
                } catch (ex) {
 
225
                }
 
226
        };
 
227
        
 
228
        SWFUpload.speed.formatUnits = function (baseNumber, unitDivisors, unitLabels, singleFractional) {
 
229
                var i, unit, unitDivisor, unitLabel;
 
230
 
 
231
                if (baseNumber === 0) {
 
232
                        return "0 " + unitLabels[unitLabels.length - 1];
 
233
                }
 
234
                
 
235
                if (singleFractional) {
 
236
                        unit = baseNumber;
 
237
                        unitLabel = unitLabels.length >= unitDivisors.length ? unitLabels[unitDivisors.length - 1] : "";
 
238
                        for (i = 0; i < unitDivisors.length; i++) {
 
239
                                if (baseNumber >= unitDivisors[i]) {
 
240
                                        unit = (baseNumber / unitDivisors[i]).toFixed(2);
 
241
                                        unitLabel = unitLabels.length >= i ? " " + unitLabels[i] : "";
 
242
                                        break;
 
243
                                }
 
244
                        }
 
245
                        
 
246
                        return unit + unitLabel;
 
247
                } else {
 
248
                        var formattedStrings = [];
 
249
                        var remainder = baseNumber;
 
250
                        
 
251
                        for (i = 0; i < unitDivisors.length; i++) {
 
252
                                unitDivisor = unitDivisors[i];
 
253
                                unitLabel = unitLabels.length > i ? " " + unitLabels[i] : "";
 
254
                                
 
255
                                unit = remainder / unitDivisor;
 
256
                                if (i < unitDivisors.length -1) {
 
257
                                        unit = Math.floor(unit);
 
258
                                } else {
 
259
                                        unit = unit.toFixed(2);
 
260
                                }
 
261
                                if (unit > 0) {
 
262
                                        remainder = remainder % unitDivisor;
 
263
                                        
 
264
                                        formattedStrings.push(unit + unitLabel);
 
265
                                }
 
266
                        }
 
267
                        
 
268
                        return formattedStrings.join(" ");
 
269
                }
 
270
        };
 
271
        
 
272
        SWFUpload.speed.formatBPS = function (baseNumber) {
 
273
                var bpsUnits = [1073741824, 1048576, 1024, 1], bpsUnitLabels = ["Gbps", "Mbps", "Kbps", "bps"];
 
274
                return SWFUpload.speed.formatUnits(baseNumber, bpsUnits, bpsUnitLabels, true);
 
275
        
 
276
        };
 
277
        SWFUpload.speed.formatTime = function (baseNumber) {
 
278
                var timeUnits = [86400, 3600, 60, 1], timeUnitLabels = ["d", "h", "m", "s"];
 
279
                return SWFUpload.speed.formatUnits(baseNumber, timeUnits, timeUnitLabels, false);
 
280
        
 
281
        };
 
282
        SWFUpload.speed.formatBytes = function (baseNumber) {
 
283
                var sizeUnits = [1073741824, 1048576, 1024, 1], sizeUnitLabels = ["GB", "MB", "KB", "bytes"];
 
284
                return SWFUpload.speed.formatUnits(baseNumber, sizeUnits, sizeUnitLabels, true);
 
285
        
 
286
        };
 
287
        SWFUpload.speed.formatPercent = function (baseNumber) {
 
288
                return baseNumber.toFixed(2) + " %";
 
289
        };
 
290
        
 
291
        SWFUpload.speed.calculateMovingAverage = function (history) {
 
292
                var vals = [], size, sum = 0.0, mean = 0.0, varianceTemp = 0.0, variance = 0.0, standardDev = 0.0;
 
293
                var i;
 
294
                var mSum = 0, mCount = 0;
 
295
                
 
296
                size = history.length;
 
297
                
 
298
                // Check for sufficient data
 
299
                if (size >= 8) {
 
300
                        // Clone the array and Calculate sum of the values 
 
301
                        for (i = 0; i < size; i++) {
 
302
                                vals[i] = history[i];
 
303
                                sum += vals[i];
 
304
                        }
 
305
 
 
306
                        mean = sum / size;
 
307
 
 
308
                        // Calculate variance for the set
 
309
                        for (i = 0; i < size; i++) {
 
310
                                varianceTemp += Math.pow((vals[i] - mean), 2);
 
311
                        }
 
312
 
 
313
                        variance = varianceTemp / size;
 
314
                        standardDev = Math.sqrt(variance);
 
315
                        
 
316
                        //Standardize the Data
 
317
                        for (i = 0; i < size; i++) {
 
318
                                vals[i] = (vals[i] - mean) / standardDev;
 
319
                        }
 
320
 
 
321
                        // Calculate the average excluding outliers
 
322
                        var deviationRange = 2.0;
 
323
                        for (i = 0; i < size; i++) {
 
324
                                
 
325
                                if (vals[i] <= deviationRange && vals[i] >= -deviationRange) {
 
326
                                        mCount++;
 
327
                                        mSum += history[i];
 
328
                                }
 
329
                        }
 
330
                        
 
331
                } else {
 
332
                        // Calculate the average (not enough data points to remove outliers)
 
333
                        mCount = size;
 
334
                        for (i = 0; i < size; i++) {
 
335
                                mSum += history[i];
 
336
                        }
 
337
                }
 
338
 
 
339
                return mSum / mCount;
 
340
        };
 
341
        
 
342
}
 
 
b'\\ No newline at end of file'