smartystreets_api 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f25c553f3c60e7dc68b8d55783342d343304f28
4
- data.tar.gz: 21fdcdc401a24a6001804159fa11f16703e9ee57
3
+ metadata.gz: b973ffd95180ed1525bf06779e749cb979bb10b4
4
+ data.tar.gz: 9bbcb1c2d13deb48c17335494114bc203b58f48d
5
5
  SHA512:
6
- metadata.gz: 9e8929c3e343d5789170217bb63dd2bb7024c2f902d20d82d393ba0a8888639011c1e08c449d30a20b5bf04e894f07b9d6ba414bd71ecb81bd5819616ea3b646
7
- data.tar.gz: 2e26a7e7623c47dbc95c20106335102ad5d7f026e2134932cbace55f77eac16bcd3fb080e99915ec3256a9b5565af663cecf19be0aa1b0f5c15e746400760f4c
6
+ metadata.gz: d84d3339812023dad016acac091b8929f034e312b9a4381a7a0734ab9dce0fa6299994fe1026a9dcca2d7bbd8a406c8fabd460e8c8b51792444d2d5334319ba4
7
+ data.tar.gz: a7acbbc26742bb3be1843ca8e8748abcf68f7d7d32f54d48863abca1e938f77e0b011f7620e7fb4faac965ef8f9221d86821d5d9442dac7538a97c3ce4930d27
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.2.0] - 2017-01-04
5
+ ### Added
6
+ - Support for the International Street Address API
7
+
8
+ ### Changed
9
+ - Fix the comparison of the response HTTP code to pass the proper error message to the SevereApiError.
10
+
4
11
  ## [0.1.2] - 2017-01-02
5
12
  ### Changed
6
13
  - Fix the comparison of the response HTTP code to pass the proper error message to the SevereApiError.
@@ -24,7 +24,7 @@ module SmartyStreetsApi
24
24
  def initialize
25
25
  @auth_id = "AUTH-ID"
26
26
  @auth_token = "AUTH-TOKEN"
27
- @base_url = "https://api.smartystreets.com"
27
+ @base_url = "api.smartystreets.com"
28
28
  end
29
29
 
30
30
  def auth_args
@@ -38,5 +38,10 @@ end
38
38
 
39
39
  require "smartystreets_api/monkey_patches"
40
40
  require "smartystreets_api/exceptions"
41
+ require "smartystreets_api/decorators/base_decorator"
41
42
  require "smartystreets_api/decorators/us_format"
43
+ require "smartystreets_api/decorators/international_format"
44
+ require "smartystreets_api/decorators/international_format_2_lines"
45
+ require "smartystreets_api/api_client"
42
46
  require "smartystreets_api/us_street_address"
47
+ require "smartystreets_api/international_street_address"
@@ -0,0 +1,72 @@
1
+ class SmartyStreetsApi::ApiClient
2
+ def self.get_single(options)
3
+ uri = URI(endpoint)
4
+
5
+ args = options.select do |name, value|
6
+ whitelisted_input_fields.include?(name.to_s)
7
+ end.merge!(auth_args)
8
+
9
+ uri.query = URI.encode_www_form(args)
10
+
11
+ response = Net::HTTP.get_response(uri)
12
+
13
+ raise_error!(response.code) if severe_error?(response.code)
14
+
15
+ parse(response)
16
+ end
17
+
18
+ private
19
+
20
+ def self.parse(response)
21
+ parsed_response = JSON.parse(response.body)
22
+
23
+ parse_response(parsed_response)
24
+ end
25
+
26
+ def self.parse_response(response)
27
+ response.map do |address|
28
+ {
29
+ lines: address_lines(address).symbolize_keys!,
30
+ indexes: address_indexes(address).symbolize_keys!,
31
+ components: address["components"].symbolize_keys!,
32
+ metadata: address["metadata"].symbolize_keys!,
33
+ analysis: address["analysis"].symbolize_keys!
34
+ }
35
+ end
36
+ end
37
+
38
+ def self.address_lines(address)
39
+ address.select { |field| output_address_lines_fields.include?(field) }.symbolize_keys!
40
+ end
41
+
42
+ def self.address_indexes(address)
43
+ address.select { |field| output_address_indexes_fields.include?(field) }.symbolize_keys!
44
+ end
45
+
46
+ def self.severe_error?(response_status_code)
47
+ response_status_code.to_i != 200
48
+ end
49
+
50
+ def self.raise_error!(response_status_code)
51
+ reason = case response_status_code.to_i
52
+ when 401
53
+ "Unauthorized"
54
+ when 402
55
+ "Payment Required"
56
+ when 413
57
+ "Request Entity Too Large"
58
+ when 400
59
+ "Bad Request (Malformed Payload)"
60
+ when 429
61
+ "Too Many Requests"
62
+ else
63
+ "Unknown error: #{response_status_code}"
64
+ end
65
+
66
+ raise SmartyStreetsApi::Exceptions::SevereApiError.new(reason)
67
+ end
68
+
69
+ def self.auth_args
70
+ SmartyStreetsApi.configuration.auth_args
71
+ end
72
+ end
@@ -0,0 +1,21 @@
1
+ class SmartyStreetsApi::Decorators::BaseDecorator
2
+ def call(address_object)
3
+ return if !address_object || !address_object[:components]
4
+
5
+ self.class.private_instance_methods(false).inject({}) do |decorated_address, attribute|
6
+ components = self.send(attribute.to_sym)
7
+
8
+ array_values = components.map do |component_name|
9
+ if address_object[:components] && address_object[:components][component_name]
10
+ address_object[:components][component_name]
11
+ else
12
+ nil
13
+ end
14
+ end.compact
15
+
16
+ decorated_address[attribute] = array_values.empty? ? nil : array_values.join(" ")
17
+
18
+ decorated_address
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ class SmartyStreetsApi::Decorators::InternationalFormat < SmartyStreetsApi::Decorators::BaseDecorator
2
+ def call(address_object)
3
+ return unless (decorated_address = super)
4
+
5
+ decorated_address[:organization] = address_object[:lines][:organization]
6
+
7
+ unless decorated_address[:address2]
8
+ decorated_address[:address2] = decorated_address[:address3]
9
+ decorated_address[:address3] = nil
10
+ end
11
+
12
+ unless decorated_address[:address1]
13
+ decorated_address[:address1] = decorated_address[:address2]
14
+ decorated_address[:address2] = decorated_address[:address3]
15
+ decorated_address[:address3] = nil
16
+ end
17
+
18
+ decorated_address
19
+ end
20
+
21
+ private
22
+
23
+ def organization
24
+ [:organization]
25
+ end
26
+
27
+ def address1
28
+ [:building]
29
+ end
30
+
31
+ def address2
32
+ [
33
+ :premise,
34
+ :thoroughfare
35
+ ]
36
+ end
37
+
38
+ def address3
39
+ [
40
+ :sub_building_name,
41
+ :sub_building_type,
42
+ :sub_building_number,
43
+ :post_box
44
+ ]
45
+ end
46
+
47
+ def locality
48
+ [:locality]
49
+ end
50
+
51
+ def postal_code
52
+ [:postal_code_short]
53
+ end
54
+
55
+ def administrative_area
56
+ [:administrative_area]
57
+ end
58
+
59
+ def country
60
+ [:country_iso_3]
61
+ end
62
+ end
@@ -0,0 +1,74 @@
1
+ class SmartyStreetsApi::Decorators::InternationalFormat2Lines < SmartyStreetsApi::Decorators::BaseDecorator
2
+ def call(address_object)
3
+ return unless (decorated_address = super)
4
+
5
+ decorated_address[:organization] = address_object[:lines][:organization]
6
+
7
+ unless decorated_address[:address1]
8
+ decorated_address[:address1] = decorated_address[:address_1_alternative]
9
+ decorated_address[:address2] = decorated_address[:address_2_alternative]
10
+ end
11
+
12
+ decorated_address.delete(:address_1_alternative)
13
+ decorated_address.delete(:address_2_alternative)
14
+
15
+ decorated_address
16
+ end
17
+
18
+ private
19
+
20
+ def organization
21
+ [:organization]
22
+ end
23
+
24
+ def address1
25
+ [:building]
26
+ end
27
+
28
+ def address_1_alternative
29
+ [
30
+ :premise,
31
+ :thoroughfare
32
+ ]
33
+ end
34
+
35
+ def address2
36
+ [
37
+ :premise,
38
+ :thoroughfare,
39
+ :sub_building_name,
40
+ :sub_building_type,
41
+ :sub_building_number,
42
+ :post_box
43
+ ]
44
+ end
45
+
46
+ def address_2_alternative
47
+ [
48
+ :sub_building_name,
49
+ :sub_building_type,
50
+ :sub_building_number,
51
+ :post_box
52
+ ]
53
+ end
54
+
55
+ def locality
56
+ [:locality]
57
+ end
58
+
59
+ def postal_code
60
+ [:postal_code]
61
+ end
62
+
63
+ def postal_code_short
64
+ [:postal_code_short]
65
+ end
66
+
67
+ def administrative_area
68
+ [:administrative_area]
69
+ end
70
+
71
+ def country
72
+ [:country_iso_3]
73
+ end
74
+ end
@@ -1,24 +1,4 @@
1
- class SmartyStreetsApi::Decorators::UsFormat
2
- def call(address_object)
3
- return if !address_object || !address_object[:components]
4
-
5
- self.class.private_instance_methods(false).inject({}) do |decorated_address, attribute|
6
- components = self.send(attribute.to_sym)
7
-
8
- array_values = components.map do |component_name|
9
- if address_object[:components] && address_object[:components][component_name]
10
- address_object[:components][component_name]
11
- else
12
- nil
13
- end
14
- end.compact
15
-
16
- decorated_address[attribute] = array_values.empty? ? nil : array_values.join(" ")
17
-
18
- decorated_address
19
- end
20
- end
21
-
1
+ class SmartyStreetsApi::Decorators::UsFormat < SmartyStreetsApi::Decorators::BaseDecorator
22
2
  private
23
3
 
24
4
  def street
@@ -0,0 +1,45 @@
1
+ class SmartyStreetsApi::InternationalStreetAddress < SmartyStreetsApi::ApiClient
2
+ def self.whitelisted_input_fields
3
+ %w(
4
+ input_id
5
+ country
6
+ geocode
7
+ language
8
+ freeform
9
+ address1
10
+ address2
11
+ address3
12
+ address4
13
+ organization
14
+ locality
15
+ administrative_area
16
+ postal_code
17
+ )
18
+ end
19
+
20
+ def self.output_address_lines_fields
21
+ %w(
22
+ organization
23
+ address1
24
+ address2
25
+ address3
26
+ address4
27
+ address5
28
+ address6
29
+ address7
30
+ address8
31
+ address9
32
+ address10
33
+ address11
34
+ address12
35
+ )
36
+ end
37
+
38
+ def self.output_address_indexes_fields
39
+ %w(input_id)
40
+ end
41
+
42
+ def self.endpoint
43
+ "https://international-street.#{SmartyStreetsApi.configuration.base_url}/verify"
44
+ end
45
+ end
@@ -1,79 +1,39 @@
1
- class SmartyStreetsApi::UsStreetAddress
2
- AUTH_ARGS = %w(auth-id auth-token)
3
- INPUTS = %w(street street2 secondary city state zipcode lastline addressee urbanization candidates)
4
- OUTPUT_ADDRESS_LINES = %w(addressee delivery_line_1 delivery_line_2 last_line)
5
- OUTPUT_ADDRESS_INDEXES = %w(input_id input_index candidate_index delivery_point_barcode)
6
-
7
- def self.get_single(options)
8
- uri = URI("#{host}/street-address")
9
-
10
- args = options.select { |name, value| INPUTS.include?(name.to_s) && (value && !value.empty?) }.merge!(auth_args)
11
-
12
- uri.query = URI.encode_www_form(args)
13
-
14
- response = Net::HTTP.get_response(uri)
15
-
16
- raise_error!(response.code) if severe_error?(response.code)
17
-
18
- parse(response)
19
- end
20
-
21
- private
22
-
23
- def self.parse(response)
24
- json_response = JSON.parse(response.body)
25
-
26
- parse_response(json_response)
27
- end
28
-
29
- def self.parse_response(response)
30
- response.map do |address|
31
- {
32
- lines: address_lines(address).symbolize_keys!,
33
- indexes: address_indexes(address).symbolize_keys!,
34
- components: address["components"].symbolize_keys!,
35
- metadata: address["metadata"].symbolize_keys!,
36
- analysis: address["analysis"].symbolize_keys!
37
- }
38
- end
39
- end
40
-
41
- def self.address_lines(address)
42
- address.select { |field| OUTPUT_ADDRESS_LINES.include?(field) }.symbolize_keys!
43
- end
44
-
45
- def self.address_indexes(address)
46
- address.select { |field| OUTPUT_ADDRESS_INDEXES.include?(field) }.symbolize_keys!
47
- end
48
-
49
- def self.severe_error?(response_status_code)
50
- response_status_code.to_i != 200
51
- end
52
-
53
- def self.raise_error!(response_status_code)
54
- reason = case response_status_code.to_i
55
- when 401
56
- "Unauthorized"
57
- when 402
58
- "Payment Required"
59
- when 413
60
- "Request Entity Too Large"
61
- when 400
62
- "Bad Request (Malformed Payload)"
63
- when 429
64
- "Too Many Requests"
65
- else
66
- "Unknown error: #{response_status_code}"
67
- end
68
-
69
- raise SmartyStreetsApi::Exceptions::SevereApiError.new(reason)
70
- end
71
-
72
- def self.host
73
- SmartyStreetsApi.configuration.base_url
74
- end
75
-
76
- def self.auth_args
77
- SmartyStreetsApi.configuration.auth_args
1
+ class SmartyStreetsApi::UsStreetAddress < SmartyStreetsApi::ApiClient
2
+ def self.whitelisted_input_fields
3
+ %w(
4
+ input_id
5
+ street
6
+ street2
7
+ secondary
8
+ city
9
+ state
10
+ zipcode
11
+ lastline
12
+ addressee
13
+ urbanization
14
+ candidates
15
+ )
16
+ end
17
+
18
+ def self.output_address_lines_fields
19
+ %w(
20
+ addressee
21
+ delivery_line_1
22
+ delivery_line_2
23
+ last_line
24
+ )
25
+ end
26
+
27
+ def self.output_address_indexes_fields
28
+ %w(
29
+ input_id
30
+ input_index
31
+ candidate_index
32
+ delivery_point_barcode
33
+ )
34
+ end
35
+
36
+ def self.endpoint
37
+ "https://#{SmartyStreetsApi.configuration.base_url}/street-address"
78
38
  end
79
39
  end
@@ -1,3 +1,3 @@
1
1
  module SmartyStreetsApi
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartystreets_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - florrain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-02 00:00:00.000000000 Z
11
+ date: 2017-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -98,8 +98,13 @@ files:
98
98
  - README.md
99
99
  - Rakefile
100
100
  - lib/smartystreets_api.rb
101
+ - lib/smartystreets_api/api_client.rb
102
+ - lib/smartystreets_api/decorators/base_decorator.rb
103
+ - lib/smartystreets_api/decorators/international_format.rb
104
+ - lib/smartystreets_api/decorators/international_format_2_lines.rb
101
105
  - lib/smartystreets_api/decorators/us_format.rb
102
106
  - lib/smartystreets_api/exceptions.rb
107
+ - lib/smartystreets_api/international_street_address.rb
103
108
  - lib/smartystreets_api/monkey_patches.rb
104
109
  - lib/smartystreets_api/us_street_address.rb
105
110
  - lib/smartystreets_api/version.rb