-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
123 lines (105 loc) · 4.17 KB
/
index.js
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const q = require('daskeyboard-applet');
const childprocess = require('child_process');
const tinygradient = require('tinygradient');
const logger = q.logger;
const ICMPPingDefaults = {
PollingIntervalSeconds: 60, // Number of seconds between polling sessions
PingCount: 5, // Number of pings to send per polling session
MinimumPing: 30, // Threshold below which everything is considered 'green'
ColorScalingInterval: 30, // Time gap in milliseconds between colors
GradientStops: 8, // Default granularity of gradient to be calculated
SuccessColor: '#00ff00', // Default color where an action has been successful
FailureColor: '#ff0000' // Default color when there has been a failure
};
class ICMPPing extends q.DesktopApp {
constructor() {
super();
}
async run() {
return new Promise((resolve, reject) => {
this.ping(this.config.pingAddress)
.then(avgResponseTime => resolve(ICMPPing.buildSignal(this.config.pingAddress, this.getColor(avgResponseTime), avgResponseTime)))
.catch(err => {
logger.error(`Error while pinging ${this.config.pingAddress}: ${err}`);
return reject(ICMPPing.buildSignal(this.config.pingAddress, ICMPPingDefaults.FailureColor, null, err));
});
});
}
async applyConfig() {
this.pollingInterval = 1000 * this.pollingIntervalSeconds;
this.gradientArray = this.generateGradientArray();
}
get pollingIntervalSeconds(){
return JSON.parse(this.config.pollingIntervalSeconds || ICMPPingDefaults.PollingIntervalSeconds);
}
get pingCount(){
return JSON.parse(this.config.pingCount || ICMPPingDefaults.PingCount);
}
get minPing(){
return JSON.parse(this.config.minimumPing || ICMPPingDefaults.MinimumPing);
}
get colorScalingInterval(){
return JSON.parse(this.config.colorScalingInterval || ICMPPingDefaults.ColorScalingInterval);
}
get gradientStops(){
return JSON.parse(this.config.gradientStops || ICMPPingDefaults.GradientStops);
}
get fastColor(){
return this.config.fastColor || ICMPPingDefaults.SuccessColor;
}
get slowColor(){
return this.config.slowColor || ICMPPingDefaults.FailureColor;
}
get isXClockwiseGradient(){
return !!this.config.counterClockwiseGradient;
}
get isWindows(){
return process.platform == 'win32';
}
getColor(avgResponseTime) {
const minPing = this.minPing;
const scalingInterval = this.colorScalingInterval;
let arrIndx = Math.floor(Math.abs(((avgResponseTime - minPing) / scalingInterval) + 1));
return this.gradientArray[arrIndx < this.gradientArray.length ? arrIndx : this.gradientArray.length - 1];
}
generateGradientArray(){
let gradient = tinygradient([ // Define a simple gradient between the two colors
{ color: this.fastColor, pos: 0 }, // Fast color first as we calculate
{ color: this.slowColor, pos: 1 } // from fast->slow when selecting colors
]);
// Calculate array of points on gradient for key colors and convert them to hex
return gradient.hsv(this.gradientStops, this.isXClockwiseGradient).map((el) => el.toHexString());
}
async ping(address, count){
let pingCount = !!count ? count : this.pingCount;
let pingCountArg = this.isWindows ? '-n' : '-c';
return new Promise((resolve, reject) => {
childprocess.exec(`ping ${address} ${pingCountArg} ${pingCount}`, (err, stdout, stderr) => {
if (err){
logger.warn(`Error while executing ping: ${err}`);
return reject(err);
}
let pingTimes = [], times = stdout.match(/time=\d+(\.\d+)*/g);
times.forEach((el) => pingTimes.push(el.replace('time=', '')));
let pingAverage = pingTimes.reduce((a, b) => JSON.parse(a) + JSON.parse(b), 0) / pingTimes.length;
if (!pingAverage)
return reject(`Unable to calculate ping due to invalid ping time data: ${times.replace(/(?:\r\n|\r|\n)/g, ' ')}`);
return resolve(pingAverage);
});
});
}
static buildSignal(address, color, avgResponseTime, err) {
if (typeof err !== 'undefined' || avgResponseTime == null){
return q.Signal.error([`Error while pinging ${address}`]);
}
return new q.Signal({
points: [[new q.Point(color)]],
name: 'ICMP Ping',
message: `Average response time for ${address}: ${avgResponseTime.toFixed(2)}ms`
});
}
}
module.exports = {
ICMPPing: ICMPPing
};
const icmpPing = new ICMPPing();