Last active
August 29, 2015 14:09
-
-
Save redperadot/189be393a1d7568b403d to your computer and use it in GitHub Desktop.
Monitor network addresses.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# pong.rb v0.1.3 - Monitor network addresses. | |
# Made with ❤︎ by [email protected] | |
module Scripter extend self | |
def clean_exit(message = nil) | |
Signal.trap("INT") { |signo| Scripter.tput('clear'); puts; puts message if message; exit 0 } | |
end | |
def parse_version(ver) | |
ver = ver.to_s.split('.') | |
ver = { major: ver[0].to_i, minor: ver[1].to_i, patch: ver[2].to_i } | |
end | |
def acquire_gems(*gems) | |
gems.each do |_gem| | |
begin require _gem | |
rescue LoadError | |
dep = _gem.split('/')[0] | |
puts "[Info] Installing the dependency '#{dep}'." | |
system("gem install #{dep} > /dev/null 2>&1") | |
require _gem | |
end | |
end | |
end | |
def notify(level, message) | |
case level | |
when :ask # Ask user yes or no | |
print message + ' [y/n]: '.green | |
a = STDIN.getch.downcase.strip | |
a == "y" || a.empty? ? a = true : a = false | |
puts ( a ? 'yes' : 'no' ) | |
return a | |
when :continue # Wait for interaction. | |
print message + " [Press Enter to Continue]".magenta | |
$stdin.noecho(&:gets) | |
puts | |
when :debug # Leave bread crumbs for debugging. | |
return unless $config[:debug] | |
puts "[Debug] ".blue + message | |
when :info # Let the user know what's going on. | |
puts "[Info] ".cyan + message | |
when :warn # Give a warning about something. | |
puts "[Warning] ".yellow.blink + message | |
when :error # Exit 1 when we have an error. | |
abort("[Error] ".red.blink + message) | |
else | |
puts "[#{level.capitalize}] ".white + message | |
end | |
end | |
def tput(set, unset = nil) | |
system 'tput', set | |
at_exit { system 'tput', unset } unless unset.nil? | |
end | |
def clear_screen | |
rows = $stdin.winsize[0] | |
cols = $stdin.winsize[1] | |
chrs = rows * cols - cols | |
self.tput('home') | |
print ' ' * chrs | |
system("tput cup #{cols} 0") | |
end | |
def center(line) | |
cols = $stdin.winsize[1] | |
marg = ' ' * ((cols - line.to_s.length) / 2 ) | |
return marg + line.to_s | |
end | |
end | |
class Pong | |
attr_reader :ball, :addr, :name | |
attr_writer :sleep, :tmout, :colr | |
@@sleep = 2 | |
@@tmout = 3 | |
@@refsh = Time.now.to_i | |
@@scren = lambda {{ rows: $stdin.winsize[0], cols: $stdin.winsize[1] }} | |
@@colrs = [:default, :green, :red, :light_black, :light_red, :light_green, :light_yellow, :light_blue, :light_magenta, :light_cyan, :light_white] | |
def initialize(host) | |
@name = name | |
@host = Net::Ping::External.new(host); @host.timeout = @@tmout | |
@addr = @host.host.to_s | |
@colr = String.colors.sample while @colr.nil? || @@colrs.include?(@colr); @@colrs.push(@colr) | |
@ball = { aval: false, prev: false, chng: Time.now, tabl: Array.new } | |
@padl = Thread.new { | |
loop do | |
sleep(@@sleep) | |
@ball[:aval] = @host.ping? | |
next if @ball[:prev] == @ball[:aval] | |
@ball[:chng] = Time.now | |
@ball[:prev] = @ball[:aval] | |
@ball[:tabl] << [ @ball[:chng].to_i, "#{@ball[:chng].strftime('%y:%m:%d:%H:%M:%S')}" + ' • '.colorize(@colr) + "#{@addr} is #{( @ball[:aval] ? 'up'.green : 'down'.red )}." ] | |
Thread.current[:state] = @ball | |
end | |
} | |
end | |
def status | |
'[' + @addr.colorize(@colr) + '|' + ( @ball[:aval] ? '●'.green : "●".red ) + ']' | |
end | |
def self.table(lines) | |
tables = Array.new | |
hosts.each { |host| tables.concat(host.ball[:tabl]) } | |
tables.sort.map { |item| item[1] }[0..lines] | |
end | |
def self.refresh | |
changes = Array.new | |
hosts.each { |host| changes << host.ball[:chng].to_i } | |
return false if changes.sort.last < @@refsh | |
@@refsh = Time.now.to_i | |
return true | |
end | |
def self.hosts | |
ObjectSpace.each_object(self).to_a | |
end | |
def self.net | |
stat_bar = String.new | |
hosts.each { |host| stat_bar << host.status } | |
return stat_bar | |
end | |
def self.monitor | |
loop do | |
@@scren = { rows: $stdin.winsize[0], cols: $stdin.winsize[1] } | |
Scripter.clear_screen | |
table(@@scren[:rows] - 2).each { |line| puts line } | |
puts '⎓' * (@@scren[:cols] - 1) | |
puts net | |
sleep(@@sleep) until refresh | |
end | |
end | |
def self.splash | |
Scripter.tput('civis', 'cvvis') | |
relnam = %x(dscl . read /Users/`whoami` RealName).split[1..2] | |
aspeed = 0.06 | |
runs = (@@tmout * (aspeed * 100)).round | |
logo = [ | |
' ::::::::: :::::::: :::: ::: ::::::::', | |
' :+: :+: :+: :+: :+:+: :+: :+: :+:', | |
' +:+ +:+ +:+ +:+ :+:+:+ +:+ +:+ ', | |
' +#++:++#+ +#+ +:+ +#+ +:+ +#+ :#: ', | |
' +#+ +#+ +#+ +#+ +#+#+# +#+ +#+# ', | |
' #+# #+# #+# #+# #+#+# #+# #+# ', | |
'### ######## ### #### ######## ', | |
] | |
mesage = [ "Hello #{relnam[0]}, let's start a game of ping pong!", "Loading #{hosts.size} hosts..." ] | |
colors = [ :cyan, :magenta, :yellow ] # [ :gold[:],:black[],:cyan[] ] # String.colors.shuffle | |
header = "\n" * (( $stdin.winsize[0] - logo.size ) / 2 - 2 ) | |
Scripter.tput('clear') | |
(runs).times do |i| | |
print header | |
logo.each do |line| | |
puts Scripter.center(line).colorize(colors[0]) | |
sleep(aspeed) | |
end | |
puts Scripter.center('╍' * (logo[0].length + 2)) | |
mesage.each { |line| puts Scripter.center(line) } | |
colors.rotate! | |
Scripter.tput('home') | |
end | |
end | |
private_class_method :net, :table, :hosts, :refresh | |
end | |
Scripter.clean_exit(' - May the command line live forever. - '.center(`tput cols`.to_i)) | |
Scripter.acquire_gems('optparse', 'io/console', 'colorize', 'net/ping', 'socket') | |
ARGV.each { |host| Pong.new(host) } | |
Pong.splash | |
Pong.monitor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Create a bash alias with:
alias pong='ruby -e "$(curl -fsSL https://gist.githubusercontent.com/redperadot/189be393a1d7568b403d/raw/pong.rb)"'
.Usage:
pong [ ip / hostname ]
.