Ruby Geocoder connection refused - ruby-on-rails

When I search for an IP address, I get the following error:
pry(main)> Geocoder.search("130.132.173.68")
Geocoding API connection refused.
=> []
If I search for anything else eg.
pry(main)> Geocoder.search("new haven")
I get the correct results.
Is there a problem with the freegeoip service?

Make sure you have an initializer setup for Geocoder with all of the config settings. This was the problem for me. Something along the lines like this:
# config/initializers/geocoder.rb
Geocoder.configure(
# geocoding options
:timeout => 7, # geocoding service timeout (secs)
:lookup => :google, # name of geocoding service (symbol)
:language => :en, # ISO-639 language code
:use_https => true, # use HTTPS for lookup requests? (if supported)
:http_proxy => '', # HTTP proxy server (user:pass#host:port)
:https_proxy => '', # HTTPS proxy server (user:pass#host:port)
:api_key => nil, # API key for geocoding service
:cache => nil, # cache object (must respond to #[], #[]=, and #keys)
:cache_prefix => "geocoder:", # prefix (string) to use for all cache keys
# IP address geocoding service (see below for supported options):
#:ip_lookup => :maxmind,
# to use an API key:
#:api_key => "...",
# exceptions that should not be rescued by default
# (if you want to implement custom error handling);
# supports SocketError and TimeoutError
# :always_raise => [],
# calculation options
# :units => :mi, # :km for kilometers or :mi for miles
# :distances => :linear # :spherical or :linear
)

Related

Can't connect to clustered Azure Redis Cache with redis-rb gem and public access

We've provisioned an Azure Redis Cache server using the Premium tier. The server is clustered, with 2 shards, and the server is configured to allow public access over the public internet through a firewall--allow-listing a set of known IPs.
Deploys of our Rails application two any of these known IPs fail with the error:
Redis::CannotConnectError: Redis client could not connect to any cluster nodes
Here is our Rails config:
# application.rb
if Rails.env.test?
config.cache_store = :redis_cache_store, {
url: config.nines[:redis_url],
expires_in: 90.minutes,
namespace: ENV['TEST_ENV_NUMBER'],
}
else
config.cache_store = :redis_store, {
namespace:ENV['TEST_ENV_NUMBER'],
cluster: [ Rails.application.config.nines[:redis_url] ],
replica: true, # allow reads from replicas
compress: true,
compress_threshold: 1024,
expires_in: 90.minutes
}
end
The config.nines[:redis_url] is set like this: rediss://:<pw>#<cache-name>.redis.cache.windows.net:6380/0
Then, we initialize the Redis connection in code like this:
if Rails.env.test?
::Redis.new :url => redis_url, :db => ENV['REDIS_DB']
else
::Redis.new(cluster: [ "#{redis_url}" ], db: ENV['REDIS_DB'])
end
We're using the redis-rb gem and redis-rails gem.
If anyone can point out what we're doing wrong, please do share!
Thank you User Peter Pan - Stack Overflow. Posting your suggestion as answer to help other community members.
You can try below code:
# Import the redis library for Ruby
require "redis"
# Create a redis client instance for connecting Azure Redis Cache
# At here, for enabling SSL, set the `:ssl` symbol with the
# symbol value `:true`, see https://github.com/redis/redis-rb#ssltls-support
redis = Redis.new(
:host => '<azure redis cache name>.redis.cache.windows.net',
:port => 6380,
:db => <the db index you selected like 10>,
:password => "<access key>",
:ssl => :true)
# Then, set key `foo` with value `bar` and return `OK`
status = redis.set('foo', 'bar')
puts status # => OK
# Get the value of key `foo`
foo = redis.get('foo')
puts foo # => bar
Reference: How to setup Azure Redis cache with Rails - Stack Overflow

Ahoy visits not created with after_validation :geocode uncommented

I have integrated Ahoy into our platform and it works great for tracking events etc. I am now trying to extend the functionality with enabling geocoding. The issue I am running into is as soon as I uncomment the
after_validation :geocode
line, visits stop recording in the database.
What am I doing wrong here?
visit.rb
class Ahoy::Visit < ActiveRecord::Base
self.table_name = "ahoy_visits"
# ahoy_visit
geocoded_by :ip
# after_validation :geocode
has_many :events, class_name: "Ahoy::Event"
belongs_to :user
end
ahoy.rb (note the short visit duration for testing):
class Ahoy::Store < Ahoy::DatabaseStore
end
# set to true for JavaScript tracking
Ahoy.api = true
# better user agent parsing
Ahoy.user_agent_parser = :device_detector
Ahoy.geocode = true
# Ahoy.server_side_visits = :when_needed
Ahoy.visit_duration = 10.seconds
# Ahoy.visit_duration = Rails.application.secrets.visit_duration
Ahoy.quiet = false
geocoder.rb
Geocoder.configure(
# Geocoding options
timeout: 15, # geocoding service timeout (secs)
lookup: :google, # name of geocoding service (symbol)
:ip_lookup => :maxmind, # IP address geocoding service (see below for supported options):
language: :en, # ISO-639 language code
use_https: true, # use HTTPS for lookup requests? (if supported)
# http_proxy: nil, # HTTP proxy server (user:pass#host:port)
# https_proxy: nil, # HTTPS proxy server (user:pass#host:port)
api_key: Rails.application.secrets.google_server_api_key, # API key for geocoding service
# cache: nil, # cache object (must respond to #[], #[]=, and #keys)
# cache_prefix: 'geocoder:', # prefix (string) to use for all cache keys
# Exceptions that should not be rescued by default
# (if you want to implement custom error handling);
# supports SocketError and Timeout::Error
# always_raise: [],
# Calculation options
units: :km, # :km for kilometers or :mi for miles
# distances: :linear # :spherical or :linear
)
To re-iterate, when I comment out the geocoding line visits are recorded properly and ahoy works as expected.
Thanks.
EDIT
I am certain there is an exception being thrown but it is not bubbling up in the logs and I have debug logging enabled. Ahoy just states that "[ahoy] Event excluded since visit not created:" yet on the UI we can see that a visit is being started via these log statements from ahoy:
Visit started
ahoy.self-01ef77de70801670c1f7f2f12fea979d59ba70488a77db75270b57ec5b1a2f8e.js?body=1:175
{visit_token: "4c7e0bcb-7afb-48cd-91ed-1bdf0d614767", visitor_token:
"374bf981-d843-45c3-953d-0f0b8fd5a6a7", platform: "Web", landing_page:
"http://localhost:3000/", screen_width: 1680, …}
ahoy.self-01ef77de70801670c1f7f2f12fea979d59ba70488a77db75270b57ec5b1a2f8e.js?body=1:175
{name: "$click", properties: {…}, time: 1533656941.084, id:
"c967b67f-96f7-4f18-a9a8-df3735fdc1c2", js: true}

Ruby on Rails always pointing local redis Server

I am using Redis with my ruby on rails application, To map Ruby object with Redis using redis-objects, dm-core and dm-redis-adapter. Below are the code snipts
Gemfile
gem 'redis-objects'
gem "dm-core", "~> 1.2.1"
gem "dm-redis-adapter"
/config/initializers/redis.rb
// LOCAL REDIS SERVER
Redis.current = Redis.new(:host => '127.0.0.1', :port => 6379)
// REMOTE REDIS SERVER
#Redis.current = Redis.new(:host => '<VM IP>', :port => <VM PORT>, :password => '<PASSWORD>')
Model.rb
DataMapper.setup(:default, {:adapter => "redis"})
class User
include Redis::Objects
include DataMapper::Resource
include ActiveModel::Validations
include ActiveModel::Conversion
# datamapper fields, just used for .create
property :id, Serial
property :name, String
property :email, String
property :des, Text
def id
1
end
end
User.finalize
It's working fine for local redis server. Why app always pointing local redis, Even when providing remote host and port?
SOLVED: checkout my answer.
As per Question:
// LOCAL REDIS SERVER
Redis.current = Redis.new(:host => '127.0.0.1', :port => 6379)
// REMOTE REDIS SERVER
#Redis.current = Redis.new(:host => '<VM IP>', :port => <VM PORT>, :password => '<PASSWORD>')
Model.rb
DataMapper.setup(:default, {:adapter => "redis"})
In above code, I am overloading Redis configuration in User model.
In that case, I need to write remote configuration in model as well.
DataMapper.setup(:default, {:adapter => "redis", :host => '<VM IP>', :port => <VM PORT>, :password => '<PASSWORD>'})
Redis.current is a method which always gives a new connection if the instance variable #current is empty. See https://github.com/redis/redis-rb/blob/master/lib/redis.rb#L19
def self.current
#current ||= Redis.new
end
Try assigning Redis.new to some other global like $redis. This should mostly fix your issue.

How to "crawl" only the root URL with Anemone?

In the example below I would like anemone to only execute on the root URL (example.com). I am unsure if I should apply the on_page_like method and if so what pattern I would need.
require 'anemone'
Anemone.crawl("http://www.example.com/") do |anemone|
anemone.on_pages_like(???) do |page|
# some code to execute
end
end
require 'anemone'
Anemone.crawl("http://www.example.com/", :depth_limit => 1) do |anemone|
# some code to execute
end
You can also specify the following in the options hash, below are the defaults:
# run 4 Tentacle threads to fetch pages
:threads => 4,
# disable verbose output
:verbose => false,
# don't throw away the page response body after scanning it for links
:discard_page_bodies => false,
# identify self as Anemone/VERSION
:user_agent => "Anemone/#{Anemone::VERSION}",
# no delay between requests
:delay => 0,
# don't obey the robots exclusion protocol
:obey_robots_txt => false,
# by default, don't limit the depth of the crawl
:depth_limit => false,
# number of times HTTP redirects will be followed
:redirect_limit => 5,
# storage engine defaults to Hash in +process_options+ if none specified
:storage => nil,
# Hash of cookie name => value to send with HTTP requests
:cookies => nil,
# accept cookies from the server and send them back?
:accept_cookies => false,
# skip any link with a query string? e.g. http://foo.com/?u=user
:skip_query_strings => false,
# proxy server hostname
:proxy_host => nil,
# proxy server port number
:proxy_port => false,
# HTTP read timeout in seconds
:read_timeout => nil
My personal experience is that Anemone was not very fast and had a lot of corner cases. The docs are lacking (as you have experienced) and the author doesn't seem to be maintaining the project. YMMV. I tried Nutch shortly but didn't play aroud as much but it seemed faster. No benchmarks, sorry.

Are there any open-source examples of using LocationLabs or Loc-Aid through Ruby?

LocationLabs and Loc-Aid are location aggregation services that expose REST APIs. They currently offer Java, .NET and PHP SDKs. The API is not complex but, still, as a learning tool, it would be nice to have a Ruby tutorial or example to play with, extent, etc.
After further analysis, I built my application on Loc-Aid's infrastructure. Since there weren't many Ruby examples I could find, I'm sharing a snippet from my app.
# Get SAVON soap client locaid location services
# Parameters:
# - none
# Returns: SOAP client for locaid location services
def get_location_client
Savon::Client.new do
wsdl.document = LOCAID_CONFIG['use_local_wsdl'] ?
File.expand_path(LOCAID_CONFIG['get_location_wsdl'].to_s, ::Rails.root.to_s) :
LOCAID_CONFIG['get_location_wsdl'].to_s
wsdl.endpoint = LOCAID_CONFIG['get_location_endpoint'].to_s
end
end
# Strip the return result from locaid response as a hash
# Parameters:
# - raw_response: Raw response XMLfrom locaid services
# - response_name: Response name which wrap the response return result in locaid response XML
# Returns: Hash corresponding to the key "return" in locaid soap response hash.
# Sample Raw Response:
# {:subscribe_phone_response=>{:return=>{:error=>{:error_code=>"00001", :error_message=>"Invalid or inactive user"}, :transaction_id=>"14028251"},
# :"#xmlns:ns2"=>"http://webservice.portico.locaid.net/"}}
def strip_locaid_return(raw_response, response_name)
unless raw_response.to_hash.has_key?(response_name)
raise TropoExceptions::ExternalError
end
raw_response[response_name][:return]
end
# Get location from locaid by the caller id
# Parameters:
# - #caller_id: Caller id get from scope value
# Returns: none
def location_from_locaid
client = get_location_client
client.http.read_timeout = LOCAID_CONFIG['get_location_timeout'].to_i
# Call locaider service to get location
response = client.request :wsdl, :get_locations_x do |soap|
soap.body = {
:login => LOCAID_CONFIG['login'],
:password => LOCAID_CONFIG['password'],
:class_id => LOCAID_CONFIG['class_id'],
:msisdn_list => ["1#{#caller_id}"],
:coor_type => "DECIMAL",
:location_method => LOCAID_CONFIG['location_method'],
:sync_type => "SYN",
:overage => "1"
}
end
result_hash = strip_locaid_return(response, :get_locations_x_response)
if result_hash.has_key?(:error)
raise TropoExceptions::ExternalError
end
yield result_hash[:location_response].is_a?(Array) ?
result_hash[:location_response][0] :
result_hash[:location_response]
rescue Savon::Error, Timeout::Error => e
logger.error e
yield nil
end
end

Resources