Skip to content

Instantly share code, notes, and snippets.

@lian
Created October 31, 2010 23:52
Show Gist options
  • Select an option

  • Save lian/657336 to your computer and use it in GitHub Desktop.

Select an option

Save lian/657336 to your computer and use it in GitHub Desktop.
# lookup coords by name or mac address via google.. (evented)
require 'cgi'
require 'json'
require 'eventmachine'
module Goog
module Location
class Name < EM::Connection
Head = <<-TEXT
GET /maps/geo?q=%s HTTP/1.0
User-Agent: Surf/0.4.2 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)
Host: maps.google.com
Accept: */*
TEXT
end
class MAC < EM::Connection
Head = <<-TEXT
POST /loc/json HTTP/1.0
User-Agent: Surf/0.4.2 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)
Host: www.google.com
Accept: */*
Content-Length: %i
Content-Type: application/x-www-form-urlencoded
TEXT
end
end
end
module Goog
module Location
class Location::Name < EM::Connection
def self.find(query, &block)
cb = proc{|data| p data }
EM.connect('google.com', 80, self, query, block || cb)
end
def initialize(query, callback)
@query = CGI.escape(query)
@cb = callback
end
def post_init
send_data( Head % [@query] )
end
#def unbind; p 'connection closed'; end
def receive_data(data)
reply = nil
begin
result = JSON.parse( data[data.index("\r\n\r\n")+4..-1] )
if result['Status'].values == [200, 'geocode']
reply = result['Placemark'].map{|i| i['Point'].values.flatten }
end
end
@cb.call(reply) if reply && @cb.respond_to?(:call)
end
end
class Location::MAC < EM::Connection
def self.find(query, &block)
cb = proc{|data| p data }
EM.connect('google.com', 80, self, query, block || cb)
end
def initialize(query=nil, callback)
@query, @cb = (query || scan_for_mac.first), callback
@json = { version: '1.1.0', host: 'maps.google.com', request_address: true,
address_language: 'en_GB', address_language: 'en_GB', wifi_towers: [] }
end
def post_init
return nil unless @query
@json[:wifi_towers].clear
@json[:wifi_towers].push({ mac_address: @query, signal_strength: 8, age: 0 })
p req = JSON.generate(@json)
send_data( (Head % [req.bytesize]) + req )
end
#def unbind; p 'connection closed'; end
def receive_data(data)
reply = nil
begin
reply = JSON.parse( data[data.index("\r\n\r\n")+4..-1] )
end
@cb.call(reply) if reply && @cb.respond_to?(:call)
end
def scan_for_mac
[ `iwlist wlan0 scan | grep Address | head -1 | awk '{print $5}' | sed -e 's/ //g'`.chomp ]
end
end
end
end
EM.run do
query = ARGV.first || "Berlin,Germany"
type = query.match(/([0-9A-Fa-f]{2}:?){6}/) ? 'mac' : 'loc'
p [query, type]
case type
when 'mac' # lookup coords by mac address
Goog::Location::MAC.find(query) do |coords|
p coords
EM.stop
end
when 'loc' # lookup coords by location name
Goog::Location::Name.find(query) do |coords|
p "%s is at %s" % [query, coords.first.inspect]
EM.stop
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment