Skip to content

Instantly share code, notes, and snippets.

@jphastings
Created April 21, 2009 01:29
Show Gist options
  • Save jphastings/98878 to your computer and use it in GitHub Desktop.
Save jphastings/98878 to your computer and use it in GitHub Desktop.
A ruby-processing tool that lets you visualize where on the planet your network traffic is coming from.
# Soooooo. Its hacky, and I'm sure there are improvements (shout if you have any) but...
# # # # # # # # # # # # # # # # # # # # # # # #
# - - - Where On The Web - - -
# A ruby-processing tool that lets you visualize where your network traffic is coming from.
#
# My thanks to jashkenas for his excellence - not only in releasing ruby-processing
# but also for his rapid help in the forums when Java and Ruby fell out.
#
# Code as art,
# JP - jphastings.tumblr.com
#
# - - Additions - -
# Now uses the OpenGL library. This means there's no shiny antialiasing (yet). It is
# considerably faster though!
#
# - - Notes for use - -
# You need to have an equirectangular map of the earth in the same directory as this script.
# (http://www.adobe.com/devnet/flex/samples/fig_panzoom/images/earth-map_small.jpg - it lies,
# it is not small. At all. You'll need to shrink this one to prevent your computer from crying)
#
# I'd recommend having the size of the processing app the same as your image, to save on resizes
# and things, the code for that is on the very last line.
require 'ruby-processing'
require "socket"
require "open-uri"
require "fileutils"
# Eww, its not a nice cache, but sqlite3 was playing havock with the processing envirnment
FileUtils.mkdir_p("ips/")
# Interesting Functions
def getLatLong(ip)
return nil if ip.nil? or ip == "67.159.20.108" # The hostip.info address, don't plot it
return $here if !(ip.match(/^192\.168\.|^10\.|^172\.(?:1[6789]|2\d|3[12])\./).nil?)
if File.exists?("ips/#{ip}.location")
pos = open("ips/#{ip}.location") {|f|f.read.split(",").collect{|s| s.to_f}}
return (pos[0].nil? or pos[1].nil?) ? nil : pos
else
# Anyone got a better IP->lat,long webservice?
pos = open("http://api.hostip.info/get_html.php?ip=#{ip}&position=true").read.scan(/itude:\ (-?\d+\.\d+)/).collect{|i| i[0].to_f}
if pos == []
pos = nil
end
open("ips/#{ip}.location","w") {|f|
if (not pos.nil?)
f.write(pos.join(","))
end
}
return pos
end
end
# From http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
def local_ip
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
UDPSocket.open do |s|
s.connect '64.233.187.99', 1 #This is google :P
s.addr.last
end
ensure
Socket.do_not_reverse_lookup = orig
end
def mapFromLatLong(point)
return nil if point.nil?
lat = point[0]
long = point[1]
#Equirectangular
return (long+180)/360.0,(90-lat)/180.0
end
class WhereOnTheWeb < Processing::App
load_library 'carnivore'
load_ruby_library "control_panel"
load_java_library "opengl"
include_package "processing.opengl"
require 'packet_listener'
include Java::PacketListener
def setup
render_mode OPENGL
hint(ENABLE_OPENGL_2X_SMOOTH)
smooth
# Thanks! http://snippets.dzone.com/posts/show/3947
me = open("http://myip.dk") {|f|f.read.scan(/([0-9]{1,3}\.){3}[0-9]{1,3}/);puts $~}
$here = getLatLong(me)
# If you'd rather hardcode your position, comment out the previous two lines and uncomment this:
#$here = [lat_as_float,long_as_float] # eg [52.0,-3.0] for south-west england
puts (($here.nil?) ? "We couldn't find where you are!" : "You are at #{$here[0]}, #{$here[1]}")
control_panel do |c|
c.slider(:fade, 0.01..0.02)
end
@fade = 0.005
#smooth
@carnivore = org.rsg.carnivore.CarnivoreP5.new(self)
@carnivore.setVolumeLimit(20)
frame_rate = 25
@img = load_image("#{@width}.jpg")
@data = []
end
def draw
image @img,0,0,@width,@height
@data.delete_if{|point| point[0] <= 0}
if $here.nil?
@data.each do |point|
v = 1-point[0]
no_stroke
x,y = mapFromLatLong(point[1],point[2])
fill 255,0,0, v*164
ellipse x*@width,y*@height, v*point[3]*2,v*point[3]*2
point[0] -= @fade
end
else
# Lines
@data.collect { |point| [point[1],point[2],point[3],point[4]] }.uniq.each do |point|
stroke 0,0,64,128
line point[0]*@width,point[1]*@height,point[2]*@width,point[3]*@height
no_stroke
fill 0,0,64,128
ellipse point[0]*@width,point[1]*@height, 3,3
ellipse point[2]*@width,point[3]*@height, 3,3
end
@data.each do |point|
v = 1-point[0]
fill 200,0,0
sx,sy = point[1],point[2]
ex,ey = point[3],point[4]
stroke 128,0,0
ellipse (sx+v*(ex - sx))*@width,(sy+v*(ey - sy))*@height, point[5],point[5]
point[0] -= @fade
end
end
end
def packetEvent(packet)
from = mapFromLatLong(getLatLong(packet.senderAddress.ip.to_s[1..-1]))
to = mapFromLatLong(getLatLong(packet.receiverAddress.ip.to_s[1..-1]))
if $here.nil?
@data.push([1,to[0],to[1]],Math.log(packet.data.length + 1)*1.5+2) if not to.nil?
@data.push([1,from[0],from[1],Math.log(packet.data.length + 1)*1.5+2]) if not from.nil?
else
@data.push([1,from[0],from[1],to[0],to[1],Math.log(packet.data.length + 1)*1.5+2]) if not to.nil? and not from.nil? and to != from
end
end
end
WhereOnTheWeb.new :title => "Where On The Web?", :width => 1280, :height => 640
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment