smartystreets_ruby_sdk 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|