Created
April 21, 2009 01:29
-
-
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.
This file contains 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
# 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