usps_standardizer 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -5,4 +5,5 @@ pkg/*
5
5
  .rvmrc
6
6
  *~
7
7
  docs
8
+ .idea/
8
9
 
data/README.rdoc CHANGED
@@ -5,6 +5,17 @@
5
5
  $ require 'usps_standardizer'
6
6
  $ gem install usps_standardizer
7
7
 
8
+ == Configuration
9
+
10
+ === Caching
11
+
12
+ It’s a good idea, when relying on any external service, to cache retrieved data.
13
+ When implemented correctly it improves your app’s response time and stability.
14
+ It’s easy to cache usps results with USPSStandardizer, just configure a cache store:
15
+
16
+ $ USPSStandardizer::Configuration.cache = Redis.new
17
+ $ USPSStandardizer::Configuration.cache_prefix = "wyw"
18
+
8
19
  == Usage
9
20
 
10
21
  $ result = USPSStandardizer.lookup_for(:address => '6216 eddington drive', :state => 'oh', :city => 'middletown')
@@ -0,0 +1,50 @@
1
+ module USPSStandardizer
2
+ class Cache
3
+
4
+ def initialize(store, prefix)
5
+ @store = store
6
+ @prefix = prefix
7
+ end
8
+
9
+ def [](url)
10
+ interpret store[key_for(url)]
11
+ end
12
+
13
+ def []=(url, value)
14
+ store[key_for(url)] = value
15
+ end
16
+
17
+ def expire(url)
18
+ if url == :all
19
+ urls.each{ |u| expire(u) }
20
+ else
21
+ expire_single_url(url)
22
+ end
23
+ end
24
+
25
+
26
+ private
27
+
28
+ attr_reader :prefix, :store
29
+
30
+ def key_for(url)
31
+ [prefix, url].join
32
+ end
33
+
34
+ def keys
35
+ store.keys.select{ |k| k.match /^#{prefix}/ and interpret(store[k]) }
36
+ end
37
+
38
+ def urls
39
+ keys.map{ |k| k[/^#{prefix}(.*)/, 1] }
40
+ end
41
+
42
+ def interpret(value)
43
+ value == "" ? nil : value
44
+ end
45
+
46
+ def expire_single_url(url)
47
+ store.del(key_for(url))
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module USPSStandardizer
2
+ class Configuration
3
+
4
+ def self.options_and_defaults
5
+ [
6
+ [:timeout, 5],
7
+
8
+ # cache object (must respond to #[], #[]=, and #keys)
9
+ [:cache, nil],
10
+
11
+ # prefix (string) to use for all cache keys
12
+ [:cache_prefix, "usps:"]
13
+ ]
14
+ end
15
+
16
+ # define getters and setters for all configuration settings
17
+ self.options_and_defaults.each do |option, default|
18
+ class_eval(<<-END, __FILE__, __LINE__ + 1)
19
+
20
+ @@#{option} = default unless defined? @@#{option}
21
+
22
+ def self.#{option}
23
+ @@#{option}
24
+ end
25
+
26
+ def self.#{option}=(obj)
27
+ @@#{option} = obj
28
+ end
29
+
30
+ END
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,8 @@
1
1
  module USPSStandardizer
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 1
5
- PATCH = 2
4
+ MINOR = 2
5
+ PATCH = 0
6
6
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
@@ -4,6 +4,9 @@ require 'mechanize'
4
4
 
5
5
  module USPSStandardizer
6
6
 
7
+ #TODO: Change from 'mechanize' to 'net/hhtp'
8
+ #TODO: Implement 'timeout'
9
+
7
10
  class ZipLookup
8
11
 
9
12
  attr_accessor :address, :state, :city, :zipcode
@@ -17,6 +20,12 @@ module USPSStandardizer
17
20
  end
18
21
 
19
22
  def std_address
23
+
24
+ if(cache and response = cache[redis_key(@address)])
25
+ address, city, state, county, zipcode = response.split('::')
26
+ return {:address => address, :city => city, :state => state, :county => county, :zipcode => zipcode}
27
+ end
28
+
20
29
  return {} unless (content = get_std_address_content)
21
30
 
22
31
  content.gsub!(/\t|\n|\r/, '')
@@ -26,18 +35,21 @@ module USPSStandardizer
26
35
 
27
36
  raw_matches.inject({}) do |results, raw_match|
28
37
  if raw_match[0] =~ /mailingIndustryPopup2\(([^\)]*)/i
29
- @county = $1.split(',')[1].gsub(/'/, '')
38
+ @r_county = $1.split(',')[1].gsub(/'/, '')
30
39
  end
31
40
 
32
- @address, city_state_zipcode = Sanitize.clean(raw_match[0],
41
+ @r_address, city_state_zipcode = Sanitize.clean(raw_match[0],
33
42
  :remove_contents => true,
34
43
  :elements => %w[br]
35
44
  ).strip.split('<br>')
36
45
  if city_state_zipcode.sub_nonascii(' ').squeeze!(' ') =~ /^(.*)\s+(\w\w)\s(\d{5})(-\d{4})?/i
37
- @city, @state, @zipcode = $1, $2, $3
46
+ @r_city, @r_state, @r_zipcode = $1, $2, $3
38
47
  end
39
48
 
40
- results = {:address => @address, :city => @city, :state => @state, :county => @county, :zipcode => @zipcode}
49
+ results = {:address => @r_address, :city => @r_city, :state => @r_state, :county => @r_county, :zipcode => @r_zipcode}
50
+ if cache
51
+ cache[redis_key(@address)] = "#{@r_address}::#{@r_city}::#{@r_state}::#{@r_county}::#{@r_zipcode}"
52
+ end
41
53
  results
42
54
  end
43
55
  end
@@ -56,6 +68,15 @@ module USPSStandardizer
56
68
  return false unless @mechanize.page.search('p.mainRed').empty?
57
69
  @mechanize.page.body
58
70
  end
71
+
72
+ def cache
73
+ USPSStandardizer.cache
74
+ end
75
+
76
+ private
77
+ def redis_key(address)
78
+ address.downcase.gsub(' ', '_')
79
+ end
59
80
  end
60
81
  end
61
82
 
@@ -1,12 +1,27 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'mechanize'
3
+
4
+ #TODO: Improve documentation
3
5
  module USPSStandardizer
4
6
  autoload :Version, "usps_standardizer/version"
5
7
  autoload :ZipLookup, "usps_standardizer/zip_lookup"
8
+ autoload :Configuration, "usps_standardizer/configuration"
9
+ autoload :Cache, "usps_standardizer/cache"
10
+
11
+ class << self
12
+
13
+ def lookup_for(options, mechanize = Mechanize.new)
14
+ z = ZipLookup.new(options, mechanize)
15
+ z.std_address
16
+ end
17
+
18
+ def cache
19
+ if @cache.nil? and store = Configuration.cache
20
+ @cache = Cache.new(store, Configuration.cache_prefix)
21
+ end
22
+ @cache
23
+ end
6
24
 
7
- def self.lookup_for(options, mechanize = Mechanize.new)
8
- z = USPSStandardizer::ZipLookup.new(options, mechanize)
9
- z.std_address
10
25
  end
11
26
 
12
27
  end
@@ -6,6 +6,24 @@ describe USPSStandardizer do
6
6
  USPSStandardizer::Version::STRING.should match(/^\d+\.\d+\.\d+$/)
7
7
  end
8
8
 
9
+ describe "configuration" do
10
+ context "cache" do
11
+ it " should be nil as default" do
12
+ USPSStandardizer::Configuration.cache.should == nil
13
+ end
14
+ end
15
+ context "cache prefix" do
16
+ it "should be usps: as default" do
17
+ USPSStandardizer::Configuration.cache_prefix.should == 'usps:'
18
+ end
19
+ end
20
+ context "timeout" do
21
+ it "should be 5 seconds as default" do
22
+ USPSStandardizer::Configuration.timeout.should == 5
23
+ end
24
+ end
25
+ end
26
+
9
27
  it "standards an address on usps website" do
10
28
  result = USPSStandardizer.lookup_for(:address => '6216 eddington drive', :state => 'oh', :city => 'middletown')
11
29
  result[:address].should == '6216 EDDINGTON ST'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps_standardizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-17 00:00:00.000000000Z
12
+ date: 2011-10-31 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
16
- requirement: &71382600 !ruby/object:Gem::Requirement
16
+ requirement: &72995970 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.0.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *71382600
24
+ version_requirements: *72995970
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sanitize
27
- requirement: &71382350 !ruby/object:Gem::Requirement
27
+ requirement: &72995720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.0.3
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *71382350
35
+ version_requirements: *72995720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &71382120 !ruby/object:Gem::Requirement
38
+ requirement: &72995490 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 2.6.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *71382120
46
+ version_requirements: *72995490
47
47
  description: Ruby class to standardize U.S. postal addresses by referencing the U.S.
48
48
  Postal Service's web site
49
49
  email:
@@ -58,6 +58,8 @@ files:
58
58
  - README.rdoc
59
59
  - Rakefile
60
60
  - lib/usps_standardizer.rb
61
+ - lib/usps_standardizer/cache.rb
62
+ - lib/usps_standardizer/configuration.rb
61
63
  - lib/usps_standardizer/version.rb
62
64
  - lib/usps_standardizer/zip_lookup.rb
63
65
  - spec/fixtures/content.html