Skip to content

Instantly share code, notes, and snippets.

@ColinDKelley
Last active December 12, 2015 13:51
Show Gist options
  • Save ColinDKelley/9499788 to your computer and use it in GitHub Desktop.
Save ColinDKelley/9499788 to your computer and use it in GitHub Desktop.
require 'rubygems'
#require 'rubygems/user_interaction' # Required with some older RubyGems
require 'isolate/now'
require 'eventmachine'
require 'em-websocket'
require 'em-http'
require 'nokogiri'
require 'json'
require 'pp'
class GeoCodeQuery
include EM::Deferrable
def initialize(postal_code)
query = {
:postal => postal_code,
:geoit => :xml
}
req = EM::HttpRequest.new('http://geocoder.ca/').get(:query => query)
req.callback do
doc = Nokogiri.parse(req.response)
lat = doc.search('latt').inner_text
long = doc.search('longt').inner_text
succeed(lat, long)
end
req.errback { fail }
end
end
# http://developer.foursquare.com/docs/venues/search.html
class FourSquareQuery
include EM::Deferrable
def initialize(lat, long)
four_sq_query = {
:ll => "#{lat},#{long}",
:limit => 50,
:intent => :checkin,
:client_id => 'UKPXGFNLVLSH2HDXBCJ5TZQY0PNTNTZARBWGVO4XZM3Q3WA0',
:client_secret => 'JP3Q2OIMBILSOHU0VANN3FA5K1RP1UJFEPPR2O4PAWHC401G'
}
four_sq = EM::HttpRequest.new('https://api.foursquare.com/v2/venues/search').get(
:query => four_sq_query)
four_sq.callback do
locations = []
data = JSON.parse(four_sq.response)['response']['groups'].first
data['items'].each do |item|
locations << {:type => 'foursquare',
:name => item['name'],
:lat => item['location']['lat'],
:lng => item['location']['lng']}
end
succeed(locations)
end
four_sq.errback do
puts "Foursquare Query Failed"
fail('FourSquare')
end
end
end
# http://developers.facebook.com/docs/reference/api/checkin/
class FaceBookQuery
include EM::Deferrable
def initialize(lat, long)
facebook_access_query = {
:client_id => 156713821042399,
:client_secret => 'acf0a9dd669e3c4f42cc8f12221a0163',
:grant_type => 'client_credentials'
}
faq = EM::HttpRequest.new('https://graph.facebook.com/oauth/access_token').get(
:query => facebook_access_query)
faq.callback do
token = faq.response.match(/access_token=(.*)$/)[1]
facebook_query = {
:type => :place,
:center => "#{lat},#{long}",
:distance => 10000,
:access_token => token
}
facebook = EM::HttpRequest.new('https://graph.facebook.com/search').get(:query => facebook_query)
facebook.callback do
locations = []
data = JSON.parse(facebook.response)['data']
data.each do |item|
locations << {:type => 'facebook',
:name => item['name'],
:lat => item['location']['latitude'],
:lng => item['location']['longitude']}
end
succeed(locations)
end
facebook.errback do
puts "Facebook Query Failed"
fail("FaceBook")
end
end
faq.errback do
puts "Facebook access token request failed."
fail("FaceBook")
end
end
end
EM.run do
puts "Server started on 0.0.0.0:8080 (drag index.html to your browser)"
EM::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |websocket|
websocket.onopen { puts "Client connected" }
websocket.onmessage do |msg|
geocode = GeoCode.new(msg)
geocode.callback do |lat, long|
websocket.send({:type => 'location', :lat => lat, :lng => long}.to_json)
[FourSquareQuery, FaceBookQuery].each do |klass|
g = klass.new(lat, long)
g.callback { |locations| locations.each { |location| websocket.send(location.to_json) } }
g.errback { |type| websocket.send({:error => "#{type} call failed."}.to_json) }
end
end
geocode.errback do
puts "Failed on geocode"
websocket.send({:error => "Geocode call failed."}.to_json)
end
end
websocket.onclose { puts "closed" }
websocket.onerror { |e| puts "err #{e.inspect}" }
end
end
require 'em-websocket'
require 'em-synchrony'
require 'em-synchrony/em-http'
require 'nokogiri'
require 'json'
def geocode_query(postal_code)
query = {
:postal => postal_code,
:geoit => :xml
}
req = EM::HttpRequest.new('http://geocoder.ca/').get(:query => query)
req.response_header.status == 200 or raise "Geocode failed with status: #{req.response_header.status} body: #{req.body}"
doc = Nokogiri.parse(req.response)
lat = doc.search('latt').inner_text
long = doc.search('longt').inner_text
[lat, long]
end
# http://developer.foursquare.com/docs/venues/search.html
def foursquare_query(lat, long)
four_sq_query = {
:ll => "#{lat},#{long}",
:limit => 50,
:intent => :checkin,
:client_id => 'UKPXGFNLVLSH2HDXBCJ5TZQY0PNTNTZARBWGVO4XZM3Q3WA0',
:client_secret => 'JP3Q2OIMBILSOHU0VANN3FA5K1RP1UJFEPPR2O4PAWHC401G'
}
four_sq = EM::HttpRequest.new('https://api.foursquare.com/v2/venues/search').get(:query => four_sq_query)
four_sq.response_header.status == 200 or raise "Foursquare failed with status: #{four_sq.response_header.status} body: #{four_sq.body}"
data = JSON.parse(four_sq.response)['response']['groups'].first
data['items'].map do |item|
{
:type => 'foursquare',
:name => item['name'],
:lat => item['location']['lat'],
:lng => item['location']['lng']
}
end
end
# http://developers.facebook.com/docs/reference/api/checkin/
def facebook_query(lat, long)
facebook_access_query = {
:client_id => 156713821042399,
:client_secret => 'acf0a9dd669e3c4f42cc8f12221a0163',
:grant_type => 'client_credentials'
}
faq = EM::HttpRequest.new('https://graph.facebook.com/oauth/access_token').get(:query => facebook_access_query)
faq.response_header.status == 200 or raise "Facebook oauth failed with status: #{faq.response_header.status} body: #{faq.body}"
token = faq.response[/access_token=(.*)/, 1]
facebook_query = {
:type => :place,
:center => "#{lat},#{long}",
:distance => 10000,
:access_token => token
}
facebook = EM::HttpRequest.new('https://graph.facebook.com/search').get(:query => facebook_query)
facebook.response_header.status == 200 or raise "Facebook failed with status: #{facebook.response_header.status} body: #{facebook.body}"
data = JSON.parse(facebook.response)['data']
data.map do |item|
{
:type => 'facebook',
:name => item['name'],
:lat => item['location']['latitude'],
:lng => item['location']['longitude']
}
end
end
EM.synchrony do
puts "Server started on 0.0.0.0:8080 (drag index.html to your browser)"
EM::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |websocket|
websocket.onopen { puts "Client connected" }
websocket.onmessage do |msg|
Fiber.new do
lat, long = geocode_query(msg)
websocket.send({:type => 'location', :lat => lat, :lng => long}.to_json)
[:foursquare_query, :facebook_query].each do |query|
Fiber.new do
locations = send(query, lat, long)
locations.each { |location| websocket.send(location.to_json) }
end.resume
end
end.resume
end
websocket.onclose { puts "closed" }
websocket.onerror { |e| puts "err #{e.message}" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment