Created
November 20, 2013 10:24
-
-
Save timrwilliams/7560918 to your computer and use it in GitHub Desktop.
A rake task to geocode all objects of a particular class using the Ruby Geocoder gem, retrying 3 times if unsuccessful. This is primarily targetted at the Google Maps API which limits the number of requests per second. By building in an increasing back off before each retry we can ensure we recover from these temporary bans.
This file contains hidden or 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
namespace :geocoder do | |
desc "Geocode all objects without coordinates." | |
task :all_with_retry => :environment do | |
class_name = ENV['CLASS'] || ENV['class'] | |
sleep_timer = ENV['SLEEP'] || ENV['sleep'] | |
raise "Please specify a CLASS (model)" unless class_name | |
klass = class_from_string(class_name) | |
klass.not_geocoded.each do |obj| | |
geocode_with_retry obj | |
sleep(sleep_timer.to_f) unless sleep_timer.nil? | |
end | |
end | |
end | |
def geocode_with_retry(obj) | |
tries ||= 3 | |
puts "Trying again, #{tries} tries left..." if tries < 3 | |
puts Time.now.strftime("%Y%m%d%H%M%S")+": Geocoding " + obj.to_s | |
obj.geocode | |
if obj.geocoded? | |
obj.save | |
else | |
sleep(3.0/tries) #Back off in 1s, 2s, 3s intervals | |
raise Geocoder::OverQueryLimitError | |
end | |
rescue Geocoder::OverQueryLimitError => e | |
retry unless (tries -= 1).zero? | |
end | |
## | |
# Get a class object from the string given in the shell environment. | |
# Similar to ActiveSupport's +constantize+ method. | |
# | |
def class_from_string(class_name) | |
parts = class_name.split("::") | |
constant = Object | |
parts.each do |part| | |
constant = constant.const_get(part) | |
end | |
constant | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Based on https://github.com/alexreisner/geocoder/blob/master/lib/tasks/geocoder.rake