Skip to content

Instantly share code, notes, and snippets.

@ma11hew28
Created October 22, 2010 21:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ma11hew28/641363 to your computer and use it in GitHub Desktop.
Save ma11hew28/641363 to your computer and use it in GitHub Desktop.
Address standardization via USPS Webtools API
require 'rubygems'
require 'nokogiri'
require 'open-uri'
module USPS
SERVER = "http://production.shippingapis.com/ShippingAPITest.dll"
USERNAME = 'username-here' # username from http://www.usps.com/webtools/
class Address
# requres ruby-1.9, which keeps hashes ordered
# @@attr_tags = {}
# [:firm_name, :address1, :address2, :city, :state, :zip5, :zip4].each do |a|
# attr_accessor a
# @@attr_tags[a] = a.to_s.capitalize.gsub(/_(.)/) { $1.upcase }
# end
@@attr_tags = []
[:firm_name, :address1, :address2, :city, :state, :zip5, :zip4].each do |a|
attr_accessor a
@@attr_tags << [a, a.to_s.capitalize.gsub(/_(.)/) { $1.upcase }]
end
def initialize(options = {})
options.each_pair do |k, v|
self.send("#{k}=", v)
end
end
def standardize
# Generate the URI from this Address.
uri = USPS::SERVER + '?API=Verify&XML=<AddressValidateRequest ' +
'USERID="' + USPS::USERNAME + '"><Address ID="0">'
@@attr_tags.each do |a, t|
val = self.instance_variable_get "@#{a}"
uri += '<' + t + '>' + val.to_s + '</' + t + '>'
end
uri += '</Address></AddressValidateRequest>'
# Send the request synchronously and parse the response document.
doc = Nokogiri::XML(open(URI.encode(uri)))
if (error = doc.at_css('Error')) # handle error
message = error.at_css("Description").text
code = error.at_css('Number').text
source = error.at_css('Source').text
raise StandardError, "#{message} #{code} #{source}"
else # handle OK responses
address = Address.new
root = doc.at_css('Address')
@@attr_tags.each do |a, t|
if (node = root.at_css(t)) then address.send("#{a}=", node.text) end
end
address # return address
end
end
end
end
puts USPS::Address.new({
:address2 => '6406 Ivy Lane',
:city => 'Greenbelt',
:state => 'MD'
}).standardize.inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment