├── .gitignore ├── History.md ├── package.json ├── Readme.md ├── LICENSE.md └── bin └── cping /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | ## v1.0.0 - Mar 28, 2015 2 | 3 | * Fix strange timeout lines 4 | * Add license file 5 | 6 | ## v0.9.9 - July 21, 2014 7 | 8 | * Initial release. 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cping", 3 | "version": "1.0.0", 4 | "description": "Continuous ping utility for the CLI.", 5 | "main": "index.js", 6 | "bin": { 7 | "cping": "./bin/cping" 8 | }, 9 | "scripts": { 10 | "test": "mocha" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/rstacruz/cping.git" 15 | }, 16 | "keywords": [ 17 | "ping" 18 | ], 19 | "author": "Rico Sta. Cruz ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/rstacruz/cping/issues" 23 | }, 24 | "homepage": "https://github.com/rstacruz/cping", 25 | "dependencies": { 26 | "split": "^0.3.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # cping 2 | 3 | Screencast 4 | 5 | Continuous ping utility for monitoring your net connection. 6 | 7 | * `npm install -g cping` 8 | * `cping [hostname]` 9 | 10 | The `hostname` defaults to *8.8.8.8*. 11 | 12 |
13 | 14 | :copyright: 15 | 16 | **cping** © 2014+, Rico Sta. Cruz. Released under the [MIT] License.
17 | Authored and maintained by Rico Sta. Cruz with help from contributors 18 | ([list][contributors]). 19 | 20 | > [ricostacruz.com](http://ricostacruz.com)  ·  21 | > GitHub [@rstacruz](https://github.com/rstacruz)  ·  22 | > Twitter [@rstacruz](https://twitter.com/rstacruz) 23 | 24 | [MIT]: http://mit-license.org/ 25 | [contributors]: http://github.com/rstacruz/cping/contributors 26 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Rico Sta. Cruz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/cping: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var split = require('split'); 3 | /* 4 | * Continuous ping 5 | */ 6 | 7 | function App (host) { 8 | this.host = host; 9 | } 10 | 11 | App.prototype.run = function () { 12 | console.log('\033[2J\033[0;0H'); 13 | 14 | function print(left, color, right) { 15 | console.log(c(color, align(left, -5)) + " " + right); 16 | } 17 | 18 | Ticker.start(); 19 | pinger(this.host, function (type, data) { 20 | Ticker.stop(); 21 | var id = data.id; 22 | 23 | if (type === 'ping') { 24 | var bar = drawBar(data.time, { max: 5000, len: 50 }); 25 | var ms = Math.floor(data.time) + ""; 26 | var color = (data.time < 1000) ? 32 : 31; 27 | 28 | print(ms, color, bar); 29 | } 30 | else if (type === 'failed') { 31 | print("✗", 31, c(31, data.message)); 32 | } 33 | else if (type === 'err') { 34 | console.error("ERR: ", data); 35 | } 36 | Ticker.start(); 37 | }); 38 | }; 39 | 40 | /** 41 | * Ping runner 42 | * 43 | * ping('8.8.8.8', function (event, options) { 44 | * arguments 45 | * //=> [ 'ping', { time: 382.82 } ] 46 | * //=> [ 'failed', { message: "request timed out" } ] 47 | * //=> [ 'err', "no route to host" ] 48 | * }) 49 | */ 50 | 51 | function pinger(host, callback) { 52 | var bin = 'ping'; 53 | 54 | var spawn = require('child_process').spawn; 55 | var proc = spawn(bin, [ host ], { stdio: 'pipe' }); 56 | 57 | function ondata (stream, line) { 58 | if (line === '') return; 59 | 60 | var m; 61 | 62 | var seq = (m = line.match(/icmp_seq[= ](\d+)/)) && parseInt(m[1], 10); 63 | 64 | if (m = line.match(/time=([0-9\.]+) ms/)) { 65 | callback('ping', { time: parseFloat(m[1], 10), id: seq }); 66 | } 67 | else if ((stream === 'err') || (m = line.match(/Request timeout/))) { 68 | if (line.match(/Request timeout/)) line = 'timeout'; 69 | else line = line.replace(/^ping: (sendto: )?/, ''); 70 | callback('failed', { message: line.toLowerCase(), id: seq }); 71 | } 72 | }; 73 | 74 | proc.stdout.pipe(split()).on('data', function (line) { ondata('out', line); }); 75 | proc.stderr.pipe(split()).on('data', function (line) { ondata('err', line); }); 76 | proc.on('error', function (err) { callback('err', err); }); 77 | proc.on('exit', function (code) { process.exit(code); }); 78 | } 79 | 80 | /** 81 | * Bar helper 82 | */ 83 | 84 | function drawBar (n, options) { 85 | var perc = Math.max(0, n / options.max); 86 | if (options.cap === false) perc = Math.min(1, perc); 87 | var count = Math.round(perc * options.len); 88 | var rest = options.len - count; 89 | var fill = '❘'; 90 | var space = ''; 91 | var str = repeat(fill, count) + repeat(space, rest); 92 | return str.substr(0, options.len); 93 | } 94 | 95 | /** 96 | * Alignment helper 97 | */ 98 | 99 | function align(str, n) { 100 | var count = Math.abs(n); 101 | var spaces = Math.max(0, count - str.length); 102 | var pad = repeat(" ", spaces); 103 | 104 | return (n > 0) ? str+pad : pad+str; 105 | } 106 | 107 | /** 108 | * Color helper 109 | */ 110 | 111 | function c(color, str) { 112 | return "\033["+color+"m"+str+"\033[0m"; 113 | } 114 | 115 | function repeat(str, n) { 116 | return Array(Math.max(0, 1+n)).join(str); 117 | } 118 | 119 | /** 120 | * Lol 121 | */ 122 | 123 | var Ticker = { 124 | interval: 80, 125 | i: 0, 126 | frames: '◜◠◝◞◡◟'.split(''), 127 | dot: '·', 128 | maxLength: 20, 129 | timeout: 2000, 130 | 131 | start: function () { 132 | var ticker = this; 133 | this.i = 0; 134 | ticker.stop(); 135 | ticker.frame(); 136 | }, 137 | 138 | frame: function () { 139 | var ticker = this; 140 | var char = ticker.frames[ticker.i % ticker.frames.length]; 141 | var count = Math.min(this.maxLength, Math.floor(ticker.i / 2)); 142 | 143 | var elapsed = ticker.interval * ticker.i; 144 | var timeout = elapsed >= ticker.timeout; 145 | 146 | var color = timeout ? 31 : 32; 147 | 148 | var bar = c(timeout ? 31 : 30, repeat(ticker.dot, count)); 149 | ticker.i++; 150 | 151 | process.stdout.write("\033[2K\r" + " " + c(color, char) + " " + bar + "\r"); 152 | ticker.id = setTimeout(function () { ticker.frame(); }, ticker.interval); 153 | }, 154 | 155 | stop: function () { 156 | if (this.id) { 157 | process.stdout.write("\033[2K\r"); 158 | clearTimeout(this.id); 159 | delete this.id; 160 | } 161 | } 162 | }; 163 | 164 | /** 165 | * Run it 166 | */ 167 | 168 | var args = process.argv.slice(2).join(' '); 169 | if (args === '-h' || args === '--help') { 170 | console.log('Usage: cping [HOST]'); 171 | } else if (args === '-v' || args === '--version') { 172 | console.log('v' + require('../package.json').version); 173 | } else { 174 | var host = args || '8.8.8.8'; 175 | var app = new App(host); 176 | app.run(); 177 | } 178 | --------------------------------------------------------------------------------