smartystreets_ruby_sdk 2.0.2 → 3.0.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 +4 -4
- data/Makefile +1 -1
- data/Vagrantfile +4 -2
- data/examples/international_example.rb +31 -0
- data/examples/us_autocomplete_example.rb +38 -0
- data/examples/us_extract_example.rb +52 -0
- data/examples/us_street_multiple_address_example.rb +11 -9
- data/examples/us_street_single_address_example.rb +3 -3
- data/examples/us_zipcode_multiple_lookup_example.rb +7 -5
- data/examples/us_zipcode_single_lookup_example.rb +3 -3
- data/lib/smartystreets_ruby_sdk/batch.rb +7 -3
- data/lib/smartystreets_ruby_sdk/client_builder.rb +118 -0
- data/lib/smartystreets_ruby_sdk/errors.rb +15 -7
- data/lib/smartystreets_ruby_sdk/exceptions.rb +12 -5
- data/lib/smartystreets_ruby_sdk/international_street.rb +10 -0
- data/lib/smartystreets_ruby_sdk/international_street/analysis.rb +13 -0
- data/lib/smartystreets_ruby_sdk/international_street/candidate.rb +33 -0
- data/lib/smartystreets_ruby_sdk/international_street/client.rb +56 -0
- data/lib/smartystreets_ruby_sdk/international_street/components.rb +55 -0
- data/lib/smartystreets_ruby_sdk/international_street/language_mode.rb +5 -0
- data/lib/smartystreets_ruby_sdk/international_street/lookup.rb +80 -0
- data/lib/smartystreets_ruby_sdk/international_street/metadata.rb +14 -0
- data/lib/smartystreets_ruby_sdk/json_able.rb +3 -3
- data/lib/smartystreets_ruby_sdk/native_sender.rb +6 -2
- data/lib/smartystreets_ruby_sdk/request.rb +2 -1
- data/lib/smartystreets_ruby_sdk/retry_sender.rb +5 -7
- data/lib/smartystreets_ruby_sdk/us_autocomplete.rb +7 -0
- data/lib/smartystreets_ruby_sdk/us_autocomplete/client.rb +66 -0
- data/lib/smartystreets_ruby_sdk/us_autocomplete/geolocation_type.rb +5 -0
- data/lib/smartystreets_ruby_sdk/us_autocomplete/lookup.rb +34 -0
- data/lib/smartystreets_ruby_sdk/us_autocomplete/suggestion.rb +14 -0
- data/lib/smartystreets_ruby_sdk/us_extract.rb +8 -0
- data/lib/smartystreets_ruby_sdk/us_extract/address.rb +22 -0
- data/lib/smartystreets_ruby_sdk/us_extract/client.rb +46 -0
- data/lib/smartystreets_ruby_sdk/us_extract/lookup.rb +20 -0
- data/lib/smartystreets_ruby_sdk/us_extract/metadata.rb +15 -0
- data/lib/smartystreets_ruby_sdk/us_extract/result.rb +19 -0
- data/lib/smartystreets_ruby_sdk/us_street.rb +1 -1
- data/lib/smartystreets_ruby_sdk/us_street/analysis.rb +1 -0
- data/lib/smartystreets_ruby_sdk/us_street/candidate.rb +1 -0
- data/lib/smartystreets_ruby_sdk/us_street/client.rb +9 -5
- data/lib/smartystreets_ruby_sdk/us_street/components.rb +3 -0
- data/lib/smartystreets_ruby_sdk/us_street/lookup.rb +6 -0
- data/lib/smartystreets_ruby_sdk/us_street/match_type.rb +5 -0
- data/lib/smartystreets_ruby_sdk/us_street/metadata.rb +1 -0
- data/lib/smartystreets_ruby_sdk/us_zipcode.rb +1 -1
- data/lib/smartystreets_ruby_sdk/us_zipcode/alternate_county.rb +13 -0
- data/lib/smartystreets_ruby_sdk/us_zipcode/city.rb +2 -0
- data/lib/smartystreets_ruby_sdk/us_zipcode/client.rb +12 -4
- data/lib/smartystreets_ruby_sdk/us_zipcode/lookup.rb +4 -0
- data/lib/smartystreets_ruby_sdk/us_zipcode/result.rb +3 -2
- data/lib/smartystreets_ruby_sdk/us_zipcode/zip_code.rb +16 -3
- data/lib/smartystreets_ruby_sdk/version.rb +1 -1
- metadata +28 -7
- data/lib/smartystreets_ruby_sdk/core_client_builder.rb +0 -57
- data/lib/smartystreets_ruby_sdk/match_type.rb +0 -5
- data/lib/smartystreets_ruby_sdk/us_street/client_builder.rb +0 -15
- data/lib/smartystreets_ruby_sdk/us_zipcode/client_builder.rb +0 -15
@@ -4,25 +4,32 @@ end
|
|
4
4
|
class BadCredentialsError < SmartyException
|
5
5
|
end
|
6
6
|
|
7
|
-
class
|
7
|
+
class ForbiddenError < SmartyException
|
8
8
|
end
|
9
9
|
|
10
|
+
class PaymentRequiredError < SmartyException
|
11
|
+
end
|
10
12
|
|
11
13
|
class RequestEntityTooLargeError < SmartyException
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
16
|
class BadRequestError < SmartyException
|
16
17
|
end
|
17
18
|
|
19
|
+
class UnprocessableEntityError < SmartyException
|
20
|
+
end
|
18
21
|
|
19
22
|
class TooManyRequestsError < SmartyException
|
20
23
|
end
|
21
24
|
|
22
|
-
|
23
25
|
class InternalServerError < SmartyException
|
24
26
|
end
|
25
27
|
|
26
|
-
|
27
28
|
class ServiceUnavailableError < SmartyException
|
28
|
-
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class GatewayTimeoutError < SmartyException
|
32
|
+
end
|
33
|
+
|
34
|
+
class BatchFullError < SmartyException
|
35
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative './international_street/lookup'
|
2
|
+
require_relative './international_street/metadata'
|
3
|
+
require_relative './international_street/analysis'
|
4
|
+
require_relative './international_street/components'
|
5
|
+
require_relative './international_street/candidate'
|
6
|
+
require_relative './international_street/client'
|
7
|
+
require_relative './international_street/language_mode'
|
8
|
+
|
9
|
+
module InternationalStreet
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module InternationalStreet
|
2
|
+
# See "https://smartystreets.com/docs/cloud/international-street-api#analysis"
|
3
|
+
class Analysis
|
4
|
+
|
5
|
+
attr_reader :max_address_precision, :verification_status, :address_precision
|
6
|
+
|
7
|
+
def initialize(obj)
|
8
|
+
@verification_status = obj.fetch('verification_status', nil)
|
9
|
+
@address_precision = obj.fetch('address_precision', nil)
|
10
|
+
@max_address_precision = obj.fetch('max_address_precision', nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'components'
|
2
|
+
require_relative 'metadata'
|
3
|
+
require_relative 'analysis'
|
4
|
+
|
5
|
+
module InternationalStreet
|
6
|
+
# A candidate is a possible match for an address that was submitted. A lookup can have multiple
|
7
|
+
# candidates if the address was ambiguous.
|
8
|
+
#
|
9
|
+
# See "https://smartystreets.com/docs/cloud/international-street-api#root"
|
10
|
+
class Candidate
|
11
|
+
attr_reader :metadata, :address3, :address11, :address2, :address12, :address1, :address10,
|
12
|
+
:address9, :address8, :address7, :organization, :address6, :address5, :address4, :components, :analysis
|
13
|
+
|
14
|
+
def initialize(obj)
|
15
|
+
@organization = obj.fetch('organization', nil)
|
16
|
+
@address1 = obj.fetch('address1', nil)
|
17
|
+
@address2 = obj.fetch('address2', nil)
|
18
|
+
@address3 = obj.fetch('address3', nil)
|
19
|
+
@address4 = obj.fetch('address4', nil)
|
20
|
+
@address5 = obj.fetch('address5', nil)
|
21
|
+
@address6 = obj.fetch('address6', nil)
|
22
|
+
@address7 = obj.fetch('address7', nil)
|
23
|
+
@address8 = obj.fetch('address8', nil)
|
24
|
+
@address9 = obj.fetch('address9', nil)
|
25
|
+
@address10 = obj.fetch('address10', nil)
|
26
|
+
@address11 = obj.fetch('address11', nil)
|
27
|
+
@address12 = obj.fetch('address12', nil)
|
28
|
+
@components = Components.new(obj.fetch('components', {}))
|
29
|
+
@metadata = Metadata.new(obj.fetch('metadata', {}))
|
30
|
+
@analysis = Analysis.new(obj.fetch('analysis', {}))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../request'
|
2
|
+
require_relative 'candidate'
|
3
|
+
|
4
|
+
module InternationalStreet
|
5
|
+
# It is recommended to instantiate this class using ClientBuilder.build_international_street_api_client()
|
6
|
+
class Client
|
7
|
+
def initialize(sender, serializer)
|
8
|
+
@sender = sender
|
9
|
+
@serializer = serializer
|
10
|
+
end
|
11
|
+
|
12
|
+
# Sends a Lookup object to the International Street API and stores the result in the Lookup's result field.
|
13
|
+
def send(lookup)
|
14
|
+
lookup.ensure_enough_info
|
15
|
+
request = build_request(lookup)
|
16
|
+
|
17
|
+
response = @sender.send(request)
|
18
|
+
|
19
|
+
candidates = convert_candidates(@serializer.deserialize(response.payload))
|
20
|
+
lookup.result = candidates
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_request(lookup)
|
24
|
+
request = Request.new
|
25
|
+
|
26
|
+
add_parameter(request, 'country', lookup.country)
|
27
|
+
add_parameter(request, 'geocode', lookup.geocode.to_s)
|
28
|
+
add_parameter(request, 'language', lookup.language)
|
29
|
+
add_parameter(request, 'freeform', lookup.freeform)
|
30
|
+
add_parameter(request, 'address1', lookup.address1)
|
31
|
+
add_parameter(request, 'address2', lookup.address2)
|
32
|
+
add_parameter(request, 'address3', lookup.address3)
|
33
|
+
add_parameter(request, 'address4', lookup.address4)
|
34
|
+
add_parameter(request, 'organization', lookup.organization)
|
35
|
+
add_parameter(request, 'locality', lookup.locality)
|
36
|
+
add_parameter(request, 'administrative_area', lookup.administrative_area)
|
37
|
+
add_parameter(request, 'postal_code', lookup.postal_code)
|
38
|
+
|
39
|
+
request
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_parameter(request, key, value)
|
43
|
+
request.parameters[key] = value unless value.nil? or value.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def convert_candidates(raw_candidates)
|
47
|
+
candidates = []
|
48
|
+
|
49
|
+
raw_candidates.each do |candidate|
|
50
|
+
candidates.push(Candidate.new(candidate))
|
51
|
+
end
|
52
|
+
|
53
|
+
candidates
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module InternationalStreet
|
2
|
+
# See "https://smartystreets.com/docs/cloud/international-street-api#components"
|
3
|
+
class Components
|
4
|
+
attr_reader :premise, :thoroughfare_trailing_type, :sub_building, :locality, :post_box_number,
|
5
|
+
:thoroughfare_name, :thoroughfare_postdirection, :dependent_thoroughfare,
|
6
|
+
:thoroughfare, :dependent_thoroughfare_name, :postal_code_short, :dependent_thoroughfare_trailing_type,
|
7
|
+
:administrative_area, :post_box, :building_leading_type, :dependent_locality_name, :thoroughfare_type,
|
8
|
+
:dependent_thoroughfare_postdirection, :double_dependent_locality, :premise_number,
|
9
|
+
:dependent_thoroughfare_type, :post_box_type, :building, :sub_administrative_area, :postal_code_extra,
|
10
|
+
:sub_building_name, :postal_code, :dependent_locality, :premise_type, :sub_building_number,
|
11
|
+
:super_administrative_area, :premise_extra, :dependent_thoroughfare_predirection,
|
12
|
+
:building_trailing_type, :thoroughfare_predirection, :building_name, :country_iso_3, :sub_building_type
|
13
|
+
|
14
|
+
def initialize(obj)
|
15
|
+
@country_iso_3 = obj.fetch('country_iso_3', nil)
|
16
|
+
@super_administrative_area = obj.fetch('super_administrative_area', nil)
|
17
|
+
@administrative_area = obj.fetch('administrative_area', nil)
|
18
|
+
@sub_administrative_area = obj.fetch('sub_administrative_area', nil)
|
19
|
+
@dependent_locality= obj.fetch('dependent_locality', nil)
|
20
|
+
@dependent_locality_name = obj.fetch('dependent_locality_name', nil)
|
21
|
+
@double_dependent_locality = obj.fetch('double_dependent_locality', nil)
|
22
|
+
@locality = obj.fetch('locality', nil)
|
23
|
+
@postal_code = obj.fetch('postal_code', nil)
|
24
|
+
@postal_code_short = obj.fetch('postal_code_short', nil)
|
25
|
+
@postal_code_extra = obj.fetch('postal_code_extra', nil)
|
26
|
+
@premise = obj.fetch('premise', nil)
|
27
|
+
@premise_extra = obj.fetch('premise_extra', nil)
|
28
|
+
@premise_number = obj.fetch('premise_number', nil)
|
29
|
+
@premise_type = obj.fetch('premise_type', nil)
|
30
|
+
@thoroughfare = obj.fetch('thoroughfare', nil)
|
31
|
+
@thoroughfare_predirection = obj.fetch('thoroughfare_predirection', nil)
|
32
|
+
@thoroughfare_postdirection = obj.fetch('thoroughfare_postdirection', nil)
|
33
|
+
@thoroughfare_name = obj.fetch('thoroughfare_name', nil)
|
34
|
+
@thoroughfare_trailing_type = obj.fetch('thoroughfare_trailing_type', nil)
|
35
|
+
@thoroughfare_type = obj.fetch('thoroughfare_type', nil)
|
36
|
+
@dependent_thoroughfare = obj.fetch('dependent_thoroughfare', nil)
|
37
|
+
@dependent_thoroughfare_predirection = obj.fetch('dependent_thoroughfare_predirection', nil)
|
38
|
+
@dependent_thoroughfare_postdirection = obj.fetch('dependent_thoroughfare_postdirection', nil)
|
39
|
+
@dependent_thoroughfare_name = obj.fetch('dependent_thoroughfare_name', nil)
|
40
|
+
@dependent_thoroughfare_trailing_type = obj.fetch('dependent_thoroughfare_trailing_type', nil)
|
41
|
+
@dependent_thoroughfare_type = obj.fetch('dependent_thoroughfare_type', nil)
|
42
|
+
@building = obj.fetch('building', nil)
|
43
|
+
@building_leading_type = obj.fetch('building_leading_type', nil)
|
44
|
+
@building_name = obj.fetch('building_name', nil)
|
45
|
+
@building_trailing_type = obj.fetch('building_trailing_type', nil)
|
46
|
+
@sub_building_type = obj.fetch('sub_building_type', nil)
|
47
|
+
@sub_building_number = obj.fetch('sub_building_number', nil)
|
48
|
+
@sub_building_name = obj.fetch('sub_building_name', nil)
|
49
|
+
@sub_building = obj.fetch('sub_building', nil)
|
50
|
+
@post_box = obj.fetch('post_box', nil)
|
51
|
+
@post_box_type = obj.fetch('post_box_type', nil)
|
52
|
+
@post_box_number = obj.fetch('post_box_number', nil)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module InternationalStreet
|
2
|
+
# In addition to holding all of the input data for this lookup, this class also will contain the
|
3
|
+
# result of the lookup after it comes back from the API.
|
4
|
+
#
|
5
|
+
# Note: Lookups must have certain required fields set with non-blank values.
|
6
|
+
# These can be found at the URL below.
|
7
|
+
#
|
8
|
+
# See "https://smartystreets.com/docs/cloud/international-street-api#http-input-fields"
|
9
|
+
#
|
10
|
+
# @geocode:: Disabled by default. Set to true to enable.
|
11
|
+
# @language:: When not set, the output language will match the language of the input values.
|
12
|
+
# When set to language_mode.NATIVE, the results will always be in the language of the output country.
|
13
|
+
# When set to language_mode.LATIN, the results will always be provided using a Latin character set.
|
14
|
+
class Lookup
|
15
|
+
|
16
|
+
attr_accessor :freeform, :locality, :postal_code, :address3, :address2, :inputId, :address1,
|
17
|
+
:geocode, :administrative_area, :country, :organization, :language, :address4, :result
|
18
|
+
|
19
|
+
def initialize(freeform=nil, country=nil)
|
20
|
+
@result = []
|
21
|
+
|
22
|
+
@inputId = nil
|
23
|
+
@country = country
|
24
|
+
@geocode = nil
|
25
|
+
@language = nil
|
26
|
+
@freeform = freeform
|
27
|
+
@address1 = nil
|
28
|
+
@address2 = nil
|
29
|
+
@address3 = nil
|
30
|
+
@address4 = nil
|
31
|
+
@organization = nil
|
32
|
+
@locality = nil
|
33
|
+
@administrative_area = nil
|
34
|
+
@postal_code = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def missing_country
|
38
|
+
field_is_missing(@country)
|
39
|
+
end
|
40
|
+
|
41
|
+
def has_freeform
|
42
|
+
field_is_set(@freeform)
|
43
|
+
end
|
44
|
+
|
45
|
+
def missing_address1
|
46
|
+
field_is_missing(@address1)
|
47
|
+
end
|
48
|
+
|
49
|
+
def has_postal_code
|
50
|
+
field_is_set(@postal_code)
|
51
|
+
end
|
52
|
+
|
53
|
+
def missing_locality_or_administrative_area
|
54
|
+
field_is_missing(@locality) or field_is_missing(@administrative_area)
|
55
|
+
end
|
56
|
+
|
57
|
+
def field_is_missing(field)
|
58
|
+
field.nil? or field.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
def field_is_set(field)
|
62
|
+
not field_is_missing(field)
|
63
|
+
end
|
64
|
+
|
65
|
+
def ensure_enough_info
|
66
|
+
raise UnprocessableEntityError, 'Country field is required.' if missing_country
|
67
|
+
|
68
|
+
return true if has_freeform
|
69
|
+
|
70
|
+
raise UnprocessableEntityError, 'Either freeform or address1 is required.' if missing_address1
|
71
|
+
|
72
|
+
return true if has_postal_code
|
73
|
+
|
74
|
+
if missing_locality_or_administrative_area
|
75
|
+
raise UnprocessableEntityError, 'Insufficient information:'\
|
76
|
+
'One or more required fields were not set on the lookup.'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module InternationalStreet
|
2
|
+
# See "https://smartystreets.com/docs/cloud/international-street-api#metadata"
|
3
|
+
class Metadata
|
4
|
+
|
5
|
+
attr_reader :longitude, :geocode_precision, :max_geocode_precision, :latitude
|
6
|
+
|
7
|
+
def initialize(obj)
|
8
|
+
@latitude = obj.fetch('latitude', nil)
|
9
|
+
@longitude = obj.fetch('longitude', nil)
|
10
|
+
@geocode_precision = obj.fetch('geocode_precision', nil)
|
11
|
+
@max_geocode_precision = obj.fetch('max_geocode_precision', nil)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -3,15 +3,15 @@ require 'json'
|
|
3
3
|
class JSONAble
|
4
4
|
def to_json(options={})
|
5
5
|
hash = {}
|
6
|
-
|
7
|
-
hash[var.to_s.delete('@')] =
|
6
|
+
instance_variables.each do |var|
|
7
|
+
hash[var.to_s.delete('@')] = instance_variable_get var
|
8
8
|
end
|
9
9
|
hash.to_json
|
10
10
|
end
|
11
11
|
|
12
12
|
def from_json!(string)
|
13
13
|
JSON.load(string).each do |var, val|
|
14
|
-
|
14
|
+
instance_variable_set var, val
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -29,11 +29,15 @@ class NativeSender
|
|
29
29
|
|
30
30
|
def self.build_request(smarty_request)
|
31
31
|
query = create_query(smarty_request)
|
32
|
-
|
32
|
+
if smarty_request.payload.nil?
|
33
|
+
request = Net::HTTP::Get.new(URI.parse("#{smarty_request.url_prefix}?#{query}"))
|
34
|
+
else
|
35
|
+
request = Net::HTTP::Post.new(URI.parse("#{smarty_request.url_prefix}?#{query}"))
|
36
|
+
end
|
33
37
|
request.content_type = 'application/json'
|
34
38
|
request.body = smarty_request.payload
|
35
39
|
request['User-Agent'] = "smartystreets (sdk:ruby@#{SmartystreetsRubySdk::VERSION})"
|
36
|
-
request['Referer'] = smarty_request.referer
|
40
|
+
request['Referer'] = smarty_request.referer unless smarty_request.referer.nil?
|
37
41
|
set_custom_headers(smarty_request.headers, request)
|
38
42
|
request
|
39
43
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Request
|
2
|
-
attr_accessor :parameters, :payload, :url_prefix, :referer, :headers
|
2
|
+
attr_accessor :parameters, :payload, :url_prefix, :referer, :headers, :content_type
|
3
3
|
|
4
4
|
def initialize
|
5
5
|
@parameters = {}
|
@@ -7,5 +7,6 @@ class Request
|
|
7
7
|
@url_prefix = nil
|
8
8
|
@referer = nil
|
9
9
|
@headers = {}
|
10
|
+
@content_type = 'application/json'
|
10
11
|
end
|
11
12
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class RetrySender
|
2
2
|
MAX_BACKOFF_DURATION = 10
|
3
|
-
STATUS_OK = '200'
|
3
|
+
STATUS_OK = '200'.freeze
|
4
4
|
|
5
5
|
def initialize(max_retries, inner, sleeper, logger)
|
6
6
|
@max_retries = max_retries
|
@@ -12,17 +12,15 @@ class RetrySender
|
|
12
12
|
def send(request)
|
13
13
|
response = @inner.send(request)
|
14
14
|
|
15
|
-
(0..@max_retries-1).each
|
16
|
-
if response.status_code == STATUS_OK
|
17
|
-
break
|
18
|
-
end
|
15
|
+
(0..@max_retries-1).each do |i|
|
16
|
+
break if response.status_code == STATUS_OK
|
19
17
|
|
20
18
|
backoff(i)
|
21
19
|
|
22
20
|
response = @inner.send(request)
|
23
|
-
|
21
|
+
end
|
24
22
|
|
25
|
-
|
23
|
+
response
|
26
24
|
end
|
27
25
|
|
28
26
|
def backoff(attempt)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative '../request'
|
2
|
+
require_relative '../exceptions'
|
3
|
+
require_relative 'geolocation_type'
|
4
|
+
require_relative 'suggestion'
|
5
|
+
|
6
|
+
module USAutocomplete
|
7
|
+
# It is recommended to instantiate this class using ClientBuilder.build_us_autocomplete_api_client
|
8
|
+
class Client
|
9
|
+
def initialize(sender, serializer)
|
10
|
+
@sender = sender
|
11
|
+
@serializer = serializer
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sends a Lookup object to the US Autocomplete API and stores the result in the Lookup's result field.
|
15
|
+
def send(lookup)
|
16
|
+
if not lookup or not lookup.prefix
|
17
|
+
raise SmartyException, 'Send() must be passed a Lookup with the prefix field set.'
|
18
|
+
end
|
19
|
+
|
20
|
+
request = build_request(lookup)
|
21
|
+
|
22
|
+
response = @sender.send(request)
|
23
|
+
|
24
|
+
result = @serializer.deserialize(response.payload)
|
25
|
+
suggestions = convert_suggestions(result.fetch('suggestions', []))
|
26
|
+
lookup.result = suggestions
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def build_request(lookup)
|
31
|
+
request = Request.new
|
32
|
+
|
33
|
+
add_parameter(request, 'prefix', lookup.prefix)
|
34
|
+
add_parameter(request, 'suggestions', lookup.max_suggestions.to_s)
|
35
|
+
add_parameter(request, 'city_filter', build_filter_string(lookup.city_filter))
|
36
|
+
add_parameter(request, 'state_filter', build_filter_string(lookup.state_filter))
|
37
|
+
add_parameter(request, 'prefer', build_filter_string(lookup.prefer))
|
38
|
+
if lookup.geolocate_type != GeolocationType::NONE
|
39
|
+
request.parameters['geolocate'] = 'true'
|
40
|
+
request.parameters['geolocate_precision'] = lookup.geolocate_type
|
41
|
+
else
|
42
|
+
request.parameters['geolocate'] = 'false'
|
43
|
+
end
|
44
|
+
|
45
|
+
request
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_filter_string(filter_list)
|
49
|
+
filter_list ? filter_list.join(',') : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def convert_suggestions(suggestion_hashes)
|
53
|
+
converted_suggestions = []
|
54
|
+
|
55
|
+
suggestion_hashes.each do |suggestion|
|
56
|
+
converted_suggestions.push(USAutocomplete::Suggestion.new(suggestion))
|
57
|
+
end
|
58
|
+
|
59
|
+
converted_suggestions
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_parameter(request, key, value)
|
63
|
+
request.parameters[key] = value unless value.nil? or value.empty?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|