towerdata_api 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 53f6bd6c8d2b1d232fdf12fd6506031c51a74d9f
4
+ data.tar.gz: 36bdb7c4537e8f0b7272b3c0c0ff24ec299abb09
5
+ SHA512:
6
+ metadata.gz: 7498f850f77e5d0af26dc927d889813f8d3d47a088d55e3d83c27e503d71c49ff97c75a034e203ddfd5db0309cbeb7befd07ac7fc4fd49f1d1efd7bed2a30e36
7
+ data.tar.gz: ef19b0a10d17c05b47d421ab5874452a0986855b9c7c28d36ec757e9d4d547f4eb9a512e111e8c0af2a7a7810764ea4dc72089103178b6dee69d2274f324ea8b
@@ -0,0 +1,13 @@
1
+ v1.2.3. Bulk API support
2
+
3
+ v1.2.2. Downcase emails before hashing
4
+
5
+ v1.2.1. Support ca_file instead of ca_path in constructor
6
+
7
+ v1.2.0. Bump version number to match User-Agent
8
+
9
+ v0.1.1. Bug fixes
10
+
11
+ v0.1.0. Added support for show_available
12
+
13
+ v0.0.1. Initial version
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ * The Rapleaf Personalization API has separate terms and conditions, which can
2
+ be found at http://www.rapleaf.com/developers/api_usage.
3
+ * If you send us code, please keep in mind that it will be distributed under
4
+ the same license as the rest of the project.
5
+ * This code is licensed under the Apache License which follows...
6
+
7
+ Copyright 2011 Rapleaf
8
+
9
+ Licensed under the Apache License, Version 2.0 (the "License");
10
+ you may not use this file except in compliance with the License.
11
+ You may obtain a copy of the License at
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+
15
+ Unless required by applicable law or agreed to in writing, software
16
+ distributed under the License is distributed on an "AS IS" BASIS,
17
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ See the License for the specific language governing permissions and
19
+ limitations under the License.
@@ -0,0 +1,7 @@
1
+ CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.md
5
+ Rakefile
6
+ lib/towerdata_api.rb
7
+ towerdata_api.gemspec
@@ -0,0 +1,86 @@
1
+ How to Use
2
+ ==========
3
+
4
+ Installation
5
+ ------------
6
+ > gem install towerdata_api
7
+
8
+ This gem depends on the "json" gem.
9
+
10
+ Usage
11
+ -----
12
+ require 'towerdata_api'
13
+ api = TowerDataApi::Api.new('my secret API key')
14
+ h = api.query_by_email('test@rapleaf.com')
15
+ => {"gender"=>"Male", "age"=>"25-34"}
16
+
17
+ Or using global configuration
18
+
19
+ require 'towerdata_api'
20
+ TowerDataApi::Configuration.begin do |config|
21
+ config.api_key= 'my secret API key'
22
+ config.timeout= 10
23
+ end
24
+ api = TowerDataApi::Api.new
25
+ h = api.query_by_email('test@rapleaf.com')
26
+ => {"gender"=>"Male", "age"=>"25-34"}
27
+
28
+
29
+
30
+ Constructor Options
31
+ -------------------
32
+ You can pass in an options hash to the API constructor, like so:
33
+
34
+ api = TowerData::Api.new('my secret API key', :timeout => 10)
35
+
36
+ The possible options/keys accepted by the constructor are:
37
+
38
+ - :timeout => The max amount of time to wait for a request to finish. Defaults to 2.
39
+ - :ca_file => Set this to your system-wide root CA cert path if you're having SSL verification issues. Defaults to nil.
40
+
41
+ Query Options
42
+ -------------
43
+ The gem supports several ways to query TowerData's API: email, hashed email (either MD5 or SHA1 hash), name and postal (NAP), or name and ZIP+4 (NAZ).
44
+
45
+ ### query_by_email(email, options)
46
+
47
+ This method queries TowerData's API with the specified email. The options hash accepts the following keys:
48
+
49
+ - :hash_email => Whether to (SHA1) hash the email before querying TowerData's API with it. Defaults to nil.
50
+
51
+ ### query_by_md5(md5_email, options)
52
+ ### query_by_sha1(sha1_email, options)
53
+
54
+ ### query_by_nap(first, last, street, city, state, options)
55
+
56
+ This method queries TowerData's API with a name and postal address: first name, last name, street, city, and state acronym (i.e., the state's 2-character postal code). It also accepts the following options hash:
57
+
58
+ - :email => You can include an email in your NAP query to increase the hit rate. Defaults to nil.
59
+
60
+ ### query_by_naz(first, last, zip4, options)
61
+
62
+ This method queries TowerData's API with a name and ZIP+4 code. The ZIP+4 is a string with a 5-digit ZIP code and 4-digit extension separated by a dash. This method accepts the following options:
63
+
64
+ - :email => You can include an email in your NAP query to increase the hit rate. Defaults to nil.
65
+
66
+ ### email_validation(email)
67
+
68
+ This method queries TowerData's API with email and return email_validation object. Raise error if email_validation is not enabled.
69
+
70
+ ### valid_email?(email)
71
+
72
+ This method queries TowerData's API with email and return boolean or nil if response is timeout. Raise error if email_validation is not enabled.
73
+
74
+
75
+ Contributing
76
+ ============
77
+ If you have suggestions or patches, feel free to email us at
78
+ [developer at towerdata dot com]. We look forward to hearing from you!
79
+
80
+
81
+ Contributors
82
+ ============
83
+ - Greg Poulos [greg at rapleaf dot com]
84
+ - Sean Carr [sean at rapleaf dot com]
85
+ - Vlad Shulman [vlad at rapleaf dot com]
86
+ - Bojan Milosavljevic [milboj at gmail dot com]
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ #require 'echoe'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new('spec')
7
+
8
+ # If you want to make this the default task
9
+ task :default => :spec
10
+
@@ -0,0 +1,200 @@
1
+ # Copyright 2011 Rapleaf
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "json"
16
+ require "net/https"
17
+ require "timeout"
18
+ require "digest"
19
+ require "open-uri"
20
+ require "towerdata_api/configuration"
21
+ require "towerdata_api/errors"
22
+ require "towerdata_api/email_validation"
23
+
24
+ module TowerDataApi
25
+ HOST= "api.towerdata.com".freeze
26
+ PORT= 443.freeze
27
+ HEADERS = {'User-Agent' => 'TowerDataApi/Ruby/1.3'}.freeze
28
+ API_VERSION= 5.freeze
29
+ BASE_PATH= '/td'.freeze
30
+ BULK_PATH= '/ei/bulk'.freeze
31
+
32
+ class Api
33
+
34
+ def initialize(api_key=nil, options = {})
35
+ @api_key = api_key.nil? ? Configuration.api_key : api_key
36
+ options.each do |key, value|
37
+ Configuration.send("#{key}=", value)
38
+ end
39
+ end
40
+
41
+ # Takes an e-mail and returns a hash which maps attribute fields onto attributes
42
+ # Options:
43
+ # :hash_email - the email will be hashed before it's sent to Rapleaf
44
+ def query_by_email(email, options = {})
45
+ if options[:hash_email]
46
+ query_by_sha1(Digest::SHA1.hexdigest(email.downcase))
47
+ else
48
+ get_json_response("#{base_path}&email=#{url_encode(email)}")
49
+ end
50
+ end
51
+
52
+ # Takes an e-mail that has already been hashed by md5
53
+ # and returns a hash which maps attribute fields onto attributes,
54
+ # optionally showing available data in the response
55
+ def query_by_md5(md5_email, options = {})
56
+ get_json_response("#{base_path}&md5_email=#{url_encode(md5_email)}")
57
+ end
58
+
59
+ # Takes an e-mail that has already been hashed by sha1
60
+ # and returns a hash which maps attribute fields onto attributes,
61
+ # optionally showing available data in the response
62
+ def query_by_sha1(sha1_email, options = {})
63
+ get_json_response("#{base_path}&sha1_email=#{url_encode(sha1_email)}")
64
+ end
65
+
66
+ # Takes first name, last name, and postal (street, city, and state acronym),
67
+ # and returns a hash which maps attribute fields onto attributes
68
+ # Options:
69
+ # :email - query with an email to increase the hit rate
70
+ def query_by_nap(first, last, street, city, state, options = {})
71
+ if options[:email]
72
+ url = "#{base_path}&email=#{url_encode(options[:email])}&first=#{url_encode(first)}&last=#{url_encode(last)}" +
73
+ "&street=#{url_encode(street)}&city=#{url_encode(city)}&state=#{url_encode(state)}"
74
+ else
75
+ url = "#{base_path}&first=#{url_encode(first)}&last=#{url_encode(last)}" +
76
+ "&street=#{url_encode(street)}&city=#{url_encode(city)}&state=#{url_encode(state)}"
77
+ end
78
+ get_json_response(url)
79
+ end
80
+
81
+ # Takes first name, last name, and zip4 code (5-digit zip
82
+ # and 4-digit extension separated by a dash as a string),
83
+ # and returns a hash which maps attribute fields onto attributes
84
+ # Options:
85
+ # :email - query with an email to increase the hit rate
86
+ def query_by_naz(first, last, zip4, options = {})
87
+ if options[:email]
88
+ url = "#{base_path}&email=#{url_encode(options[:email])}&first=#{url_encode(first)}&last=#{url_encode(last)}&zip4=#{zip4}"
89
+ else
90
+ url = "#{base_path}&first=#{url_encode(first)}&last=#{url_encode(last)}&zip4=#{zip4}"
91
+ end
92
+ get_json_response(url)
93
+ end
94
+
95
+
96
+ # For given email returns EmailValidation object
97
+ # This method will rise TowerDataApi::Error::Unsupported
98
+ # if yours api key doesn't have email validation field
99
+ #
100
+ def email_validation email
101
+ begin
102
+ result = query_by_email email
103
+ rescue TowerDataApi::Error::BadRequest
104
+ result = {'email_validation' => {'ok' => false}}
105
+ end
106
+
107
+ if result.has_key? 'email_validation'
108
+ EmailValidation.new result['email_validation']
109
+ else
110
+ raise TowerDataApi::Error::Unsupported, 'Email validation is not supported with yours api key.'
111
+ end
112
+ end
113
+
114
+ # Check is email valid
115
+ # This method will rise TowerDataApi::Error::Api
116
+ # if yours api key doesn't have email validation field
117
+ # Value can be true, false and nil
118
+ def valid_email? email
119
+ email_validation(email).valid?
120
+ end
121
+
122
+
123
+ # Get bulk request
124
+ # set - is array of hashes in format
125
+ #
126
+ # [{email: 'first_email'}, {email: 'second_email'}]
127
+ #
128
+ def bulk_query(set)
129
+ get_bulk_response(bulk_path, JSON.generate(set))
130
+ end
131
+
132
+ private
133
+
134
+ def url_encode value
135
+ URI::encode value
136
+ end
137
+
138
+ def get_bulk_response(path, data)
139
+ response = Timeout::timeout(@BULK_TIMEOUT) do
140
+ begin
141
+ http_client.post(path, data, HEADERS.merge('Content-Type' => 'application/json'))
142
+ rescue EOFError # Connection cut out. Just try a second time.
143
+ http_client.post(path, data, HEADERS.merge('Content-Type' => 'application/json'))
144
+ end
145
+ end
146
+
147
+ if response.code =~ /^2\d\d/
148
+ (response.body && response.body != "") ? JSON.parse(response.body) : []
149
+ else
150
+ raise TowerDataApi::Error::Api, "Error Code #{response.code}: \"#{response.body}\""
151
+ end
152
+ end
153
+
154
+ # Takes a url and returns a hash mapping attribute fields onto attributes
155
+ # Note that an exception is raised in the case that
156
+ # an HTTP response code other than 200 is sent back
157
+ # The error code and error body are put in the exception's message
158
+ def get_json_response(path)
159
+ response = Timeout::timeout(Configuration.timeout) do
160
+ begin
161
+ http_client.get(path, HEADERS)
162
+ rescue EOFError # Connection cut out. Just try a second time.
163
+ http_client.get(path, HEADERS)
164
+ end
165
+ end
166
+
167
+ if response.code =~ /^2\d\d/
168
+ (response.body && response.body != "") ? JSON.parse(response.body) : {}
169
+ elsif response.code == '400'
170
+ raise TowerDataApi::Error::BadRequest, "Bad request#{response.code}: \"#{response.body}\""
171
+ else
172
+ raise TowerDataApi::Error::Api, "Error Code #{response.code}: \"#{response.body}\""
173
+ end
174
+ end
175
+
176
+ # Returns http connection to HOST on PORT
177
+ def http_client
178
+ unless defined?(@http_client)
179
+ @http_client = Net::HTTP.new(HOST, PORT)
180
+ @http_client.use_ssl = true
181
+ @http_client.ca_file = Configuration.ca_file if Configuration.ca_file
182
+ #@http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
183
+ @http_client.start
184
+ end
185
+ @http_client
186
+ end
187
+
188
+ def bulk_path
189
+ "#{api_path}#{BULK_PATH}?api_key=#{@api_key}"
190
+ end
191
+
192
+ def base_path
193
+ "#{api_path}#{BASE_PATH}?api_key=#{@api_key}"
194
+ end
195
+
196
+ def api_path
197
+ "/v#{API_VERSION}"
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,46 @@
1
+ module TowerDataApi
2
+ class Configuration
3
+
4
+ @@api_key = nil
5
+ @@ca_file = nil
6
+ @@bulk_timeout = 30
7
+ @@timeout = 2
8
+
9
+ def self.api_key= api_key
10
+ @@api_key = api_key
11
+ end
12
+
13
+ def self.api_key
14
+ @@api_key
15
+ end
16
+
17
+ def self.ca_file= ca_file
18
+ @@ca_file = ca_file
19
+ end
20
+
21
+ def self.ca_file
22
+ @@ca_file
23
+ end
24
+
25
+ def self.timeout= timeout
26
+ @@timeout = timeout
27
+ end
28
+
29
+ def self.timeout
30
+ @@timeout
31
+ end
32
+
33
+ def self.bulk_timeout= timeout
34
+ @@bulk_timeout = timeout
35
+ end
36
+
37
+ def self.timeout
38
+ @@timeout
39
+ end
40
+
41
+ def self.begin
42
+ yield self
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ module TowerDataApi
2
+ class EmailValidation
3
+ attr_accessor :status_code, :status, :ok, :domain_type, :email_correction
4
+ alias_method :valid?, :ok
5
+
6
+ def initialize values
7
+ values.each do |key, value|
8
+ self.send("#{key}=", value)
9
+ end
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,9 @@
1
+ module TowerDataApi
2
+ module Error
3
+ class Base < StandardError; end
4
+ class Configuration < Base; end
5
+ class Api < Base; end
6
+ class BadRequest < Base; end
7
+ class Unsupported < Base; end
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{towerdata_api}
5
+ s.version = "1.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["TowerData"]
9
+ s.date = %q{2014-12-17}
10
+ s.description = %q{A library for interacting with TowerData's Personalization and Utilities APIs.}
11
+ s.email = %q{developer @nospam@ towerdata.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/towerdata_api.rb"]
13
+ s.files = Dir["{lib}/**/*"] + ["CHANGELOG", "LICENSE", "Manifest", "README.md", "Rakefile", "towerdata_api.gemspec"]
14
+ s.homepage = %q{http://www.towerdata.com}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rapleaf_api", "--main", "README.md"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{towerdata_api}
18
+ s.license = 'Apache-2.0'
19
+
20
+ s.rubygems_version = ">=1.6.1"
21
+ s.summary = %q{A library for interacting with TowerData's Personalization API.}
22
+ s.add_development_dependency "rspec", '~>3.1'
23
+
24
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: towerdata_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.1
5
+ platform: ruby
6
+ authors:
7
+ - TowerData
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ description: A library for interacting with TowerData's Personalization and Utilities
28
+ APIs.
29
+ email: developer @nospam@ towerdata.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - CHANGELOG
34
+ - LICENSE
35
+ - README.md
36
+ - lib/towerdata_api.rb
37
+ files:
38
+ - CHANGELOG
39
+ - LICENSE
40
+ - Manifest
41
+ - README.md
42
+ - Rakefile
43
+ - lib/towerdata_api.rb
44
+ - lib/towerdata_api/configuration.rb
45
+ - lib/towerdata_api/email_validation.rb
46
+ - lib/towerdata_api/errors.rb
47
+ - towerdata_api.gemspec
48
+ homepage: http://www.towerdata.com
49
+ licenses:
50
+ - Apache-2.0
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options:
54
+ - "--line-numbers"
55
+ - "--inline-source"
56
+ - "--title"
57
+ - Rapleaf_api
58
+ - "--main"
59
+ - README.md
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '1.2'
72
+ requirements: []
73
+ rubyforge_project: towerdata_api
74
+ rubygems_version: 2.2.2
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: A library for interacting with TowerData's Personalization API.
78
+ test_files: []