smartystreets_api 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.
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