netprospex-ruby 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +4 -0
  7. data/fixtures/cassettes/acl-error.yml +45 -0
  8. data/fixtures/cassettes/auth-error.yml +45 -0
  9. data/fixtures/cassettes/incomplete-organization.yml +55 -0
  10. data/fixtures/cassettes/incomplete-person.yml +52 -0
  11. data/fixtures/cassettes/industries.yml +136 -0
  12. data/fixtures/cassettes/pag-error.yml +45 -0
  13. data/fixtures/cassettes/person-by-email.yml +55 -0
  14. data/fixtures/cassettes/person-by-id.yml +55 -0
  15. data/fixtures/cassettes/person-list.yml +619 -0
  16. data/fixtures/cassettes/req-error.yml +45 -0
  17. data/lib/netprospex.rb +8 -0
  18. data/lib/netprospex/api/address.rb +9 -0
  19. data/lib/netprospex/api/organization.rb +10 -0
  20. data/lib/netprospex/api/person.rb +10 -0
  21. data/lib/netprospex/api/phone.rb +9 -0
  22. data/lib/netprospex/api/sub_objects.rb +52 -0
  23. data/lib/netprospex/client.rb +53 -0
  24. data/lib/netprospex/configuration.rb +28 -0
  25. data/lib/netprospex/exceptions.rb +13 -0
  26. data/lib/netprospex/helpers/formatters.rb +67 -0
  27. data/lib/netprospex/middleware/raise_exceptions.rb +34 -0
  28. data/lib/netprospex/middleware/rubyize.rb +16 -0
  29. data/lib/netprospex/query_methods.rb +41 -0
  30. data/lib/netprospex/version.rb +3 -0
  31. data/netprospex.gemspec +31 -0
  32. data/spec/netprospex/api/organization_spec.rb +51 -0
  33. data/spec/netprospex/api/person_spec.rb +45 -0
  34. data/spec/netprospex/client_spec.rb +34 -0
  35. data/spec/netprospex/configuration_spec.rb +21 -0
  36. data/spec/netprospex/helpers/formatters_spec.rb +78 -0
  37. data/spec/netprospex/middleware/raise_exceptions_spec.rb +92 -0
  38. data/spec/netprospex/query_methods_spec.rb +68 -0
  39. data/spec/netprospex_spec.rb +5 -0
  40. data/spec/spec_helper.rb +7 -0
  41. data/spec/vcr_helper.rb +12 -0
  42. metadata +236 -0
@@ -0,0 +1,45 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://api.netprospex.com/1.1/person/list.json
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.7
12
+ Authorization:
13
+ - OAuth oauth_consumer_key="<NETPROSPEX_KEY>", oauth_nonce="2e2556d88815db3044d263110492c76d",
14
+ oauth_signature="MX5V81z3L50m1oIYkNYYn%2BgLT18%3D", oauth_signature_method="HMAC-SHA1",
15
+ oauth_timestamp="1366302031", oauth_token="<NETPROSPEX_USER_TOKEN>", oauth_version="1.0"
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - ! '*/*'
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Thu, 18 Apr 2013 16:20:32 GMT
27
+ Server:
28
+ - Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/1.0.0-fips DAV/2 mod_wsgi/3.3
29
+ Python/2.7.2 PHP/5.3.10
30
+ X-Powered-By:
31
+ - PHP/5.3.10
32
+ Connection:
33
+ - close
34
+ Content-Length:
35
+ - '484'
36
+ Content-Type:
37
+ - application/json
38
+ body:
39
+ encoding: US-ASCII
40
+ string: ! '{"response":{"version":"1.1","responseId":"CB93209F-A577-A249-8714-7849B42E325F","responseType":"error","request":{"startTime":"2013-04-18
41
+ 12:20:32","requestType":"person_list","url":"\/1.1\/person\/list.json","userId":"d5c72b79-a2ed-11e2-8c42-00259059ba92"},"transaction":{"accountId":"d5c51e5f-a2ed-11e2-8c42-00259059ba92","accountStartBalance":7120,"accountEndBalance":null},"error":{"message":"no
42
+ valid arguments were found","code":"REQ"},"debug":{"requestTime":0.0180189609528}}}'
43
+ http_version:
44
+ recorded_at: Thu, 18 Apr 2013 16:20:32 GMT
45
+ recorded_with: VCR 2.4.0
data/lib/netprospex.rb ADDED
@@ -0,0 +1,8 @@
1
+ Dir[File.dirname(__FILE__) + '/netprospex/helpers/*.rb'].each {|file| require file }
2
+ Dir[File.dirname(__FILE__) + '/netprospex/middleware/*.rb'].each {|file| require file }
3
+ Dir[File.dirname(__FILE__) + '/netprospex/api/*.rb'].each {|file| require file }
4
+ Dir[File.dirname(__FILE__) + '/netprospex/*.rb'].each {|file| require file }
5
+
6
+ module NetProspex
7
+ extend Configuration
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'ostruct'
2
+
3
+ module NetProspex::Api
4
+ class Address < OpenStruct
5
+ def to_s
6
+ self.formatted_address
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'netprospex/api/sub_objects.rb'
2
+ require 'ostruct'
3
+
4
+ module NetProspex::Api
5
+ class Organization < OpenStruct
6
+ include HasAddress
7
+ include HasPhones
8
+ include HasDomains
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'netprospex/api/sub_objects.rb'
2
+ require 'ostruct'
3
+
4
+ module NetProspex::Api
5
+ class Person < OpenStruct
6
+ include HasAddress
7
+ include HasPhones
8
+ include HasOrganization
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'ostruct'
2
+
3
+ module NetProspex::Api
4
+ class Phone < OpenStruct
5
+ def to_s
6
+ self.formatted_number
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,52 @@
1
+ module NetProspex::Api
2
+ module HasPhones
3
+ def initialize(*args)
4
+ super(*args)
5
+ self.phones ||= []
6
+ self.phones.map! do |phone|
7
+ if phone.is_a? Hash
8
+ if phone[:national_number] && !phone[:national_number].empty?
9
+ NetProspex::Api::Phone.new(phone)
10
+ else
11
+ nil
12
+ end
13
+ else
14
+ phone
15
+ end
16
+ end
17
+ self.phones.compact!
18
+ end
19
+ end
20
+ module HasAddress
21
+ def initialize(*args)
22
+ super(*args)
23
+ if self.postal_address.is_a? Hash
24
+ formatted_address = self.postal_address[:formatted_address]
25
+ if formatted_address && !formatted_address.empty?
26
+ self.postal_address = NetProspex::Api::Address.new(self.postal_address)
27
+ else
28
+ self.postal_address = nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+ module HasOrganization
34
+ def initialize(*args)
35
+ super(*args)
36
+ if self.organization.is_a? Hash
37
+ self.organization = NetProspex::Api::Organization.new(self.organization)
38
+ end
39
+ end
40
+ end
41
+ module HasDomains
42
+ def initialize(*args)
43
+ super(*args)
44
+ if self.domains.is_a? Hash
45
+ domain = self.domains.fetch(:domain, {})[:url]
46
+ self.domains = domain ? [domain] : []
47
+ elsif self.domains.is_a? Array #TODO: I'm just guessing at this formatting
48
+ self.domains.map! {|h| h[:domain][:url]}
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ require "netprospex/query_methods"
2
+ require "faraday"
3
+ require "faraday_middleware"
4
+
5
+ module NetProspex
6
+ class Client
7
+ include NetProspex::Helpers::Formatters
8
+ include NetProspex::QueryMethods
9
+ attr_reader :account_balance
10
+
11
+ def initialize(token, secret)
12
+ @token = token
13
+ @secret = secret
14
+ end
15
+
16
+ def get(path, query={})
17
+ http.get(api_url(path, query)).body
18
+ end
19
+
20
+ def post(path, params={})
21
+ http.post(api_url(path), params).body
22
+ end
23
+
24
+ protected
25
+
26
+ def api_base
27
+ @api_base = "#{NetProspex.scheme}://api.netprospex.com/#{NetProspex.version}"
28
+ end
29
+
30
+ def api_url(path, query={})
31
+ api_base + path + stringify_query(query)
32
+ end
33
+
34
+ def http
35
+ raise NetProspex::ConfigurationError if api_base.nil?
36
+
37
+ @http ||= Faraday.new do |builder|
38
+ builder.use Faraday::Request::OAuth, {
39
+ consumer_key: NetProspex.consumer_key,
40
+ consumer_secret: NetProspex.consumer_secret,
41
+ token: @token,
42
+ token_secret: @secret
43
+ }
44
+
45
+ builder.use NetProspex::Middleware::RaiseExceptions
46
+ builder.use NetProspex::Middleware::Rubyize, content_type: /\bjson$/
47
+ builder.use FaradayMiddleware::ParseJson, content_type: /\bjson$/
48
+
49
+ builder.adapter :net_http
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ module NetProspex
2
+ module Configuration
3
+ attr_accessor :consumer_key, :consumer_secret, :scheme
4
+ attr_reader :version
5
+
6
+ def version=(v)
7
+ @version = v
8
+ end
9
+
10
+ def scheme
11
+ @scheme || 'http'
12
+ end
13
+
14
+ def self.extended(base)
15
+ base.reset
16
+ end
17
+
18
+ def reset
19
+ self.consumer_key = nil
20
+ self.consumer_secret = nil
21
+ self.version = "1.1"
22
+ end
23
+
24
+ def configure
25
+ yield self
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module NetProspex
2
+ class Error < StandardError; end
3
+ class ConfigurationError < Error; end
4
+
5
+ class ApiError < Error; end
6
+ class AccessDenied < ApiError; end
7
+ class AuthenticationError < ApiError; end
8
+ class DatabaseError < ApiError; end
9
+ class SearchError < ApiError; end
10
+ class PaginationError < ApiError; end
11
+ class ArgumentMissing < ApiError; end
12
+ class ZeroBalanceError < ApiError; end
13
+ end
@@ -0,0 +1,67 @@
1
+ require "active_support/all"
2
+ require "uri"
3
+
4
+ module NetProspex
5
+ module Helpers
6
+ module Formatters
7
+ def stringify_query(query)
8
+ return "" if query.blank?
9
+ components = []
10
+ unrubyize_keys(query).each do |k,v|
11
+ if v.is_a? Array
12
+ v.each do |w|
13
+ components << [k+'[]', w]
14
+ end
15
+ else
16
+ components << [k,v]
17
+ end
18
+ end
19
+ "?" + URI.encode_www_form(components)
20
+ end
21
+
22
+ def unrubyize_keys(hash)
23
+ new_hash = {}
24
+ hash.each do |k,v|
25
+ new_k = case k
26
+ when Symbol
27
+ k.to_s.camelize(:lower)
28
+ else
29
+ k
30
+ end
31
+ new_v = case v
32
+ when Hash
33
+ unrubyize_keys(v)
34
+ when Array
35
+ v.map {|w| (Hash === w) ? unrubyize_keys(w) : w}
36
+ else
37
+ v
38
+ end
39
+ new_hash[new_k] = new_v
40
+ end
41
+ new_hash
42
+ end
43
+
44
+ def rubyize_keys(hash)
45
+ new_hash = {}
46
+ hash.each do |k,v|
47
+ new_k = case k
48
+ when String
49
+ k.underscore.to_sym
50
+ else
51
+ k
52
+ end
53
+ new_v = case v
54
+ when Hash
55
+ rubyize_keys(v)
56
+ when Array
57
+ v.map {|w| (Hash === w) ? rubyize_keys(w) : w}
58
+ else
59
+ v
60
+ end
61
+ new_hash[new_k] = new_v
62
+ end
63
+ new_hash
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,34 @@
1
+ require 'faraday_middleware/response_middleware'
2
+
3
+ module NetProspex
4
+ module Middleware
5
+ class RaiseExceptions < Faraday::Middleware
6
+ def call(environment)
7
+ @app.call(environment).on_complete do |env|
8
+ next unless env[:body].is_a?(Hash) && env[:body][:response][:error]
9
+ error = env[:body][:response][:error]
10
+ case error[:code]
11
+ when "ACL"
12
+ raise NetProspex::AccessDenied.new(error[:message])
13
+ when "AUTH"
14
+ raise NetProspex::AuthenticationError.new(error[:message])
15
+ when "DB"
16
+ raise NetProspex::DatabaseError.new(error[:message])
17
+ when "SS"
18
+ raise NetProspex::SearchError.new(error[:message])
19
+ when "PAG"
20
+ raise NetProspex::PaginationError.new(error[:message])
21
+ when "REQ"
22
+ raise NetProspex::ArgumentMissing.new(error[:message])
23
+ when "ZBAL"
24
+ raise NetProspex::ZeroBalanceError.new(error[:message])
25
+ when "FAULT","UNX"
26
+ raise NetProspex::ApiError.new(error[:message])
27
+ else
28
+ raise NetProspex::ApiError.new(error[:message])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ require 'faraday_middleware/response_middleware'
2
+ module NetProspex
3
+ module Middleware
4
+ class Rubyize < FaradayMiddleware::ResponseMiddleware
5
+ extend NetProspex::Helpers::Formatters
6
+
7
+ define_parser do |body|
8
+ rubyize_keys(body) if body.is_a? Hash
9
+ end
10
+
11
+ def parse_response?(env)
12
+ env[:body].is_a? Hash
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ module NetProspex
2
+ module QueryMethods
3
+ def find_person(query)
4
+ response = get('/person/profile.json', query)
5
+ store_balance(response)
6
+ if p = response.fetch(:response,{}).fetch(:person_profile,{})[:person]
7
+ return NetProspex::Api::Person.new(p)
8
+ else
9
+ return nil
10
+ end
11
+ end
12
+
13
+ def find_person_by_id(id)
14
+ find_person(person_id: id)
15
+ end
16
+
17
+ def find_person_by_email(email)
18
+ find_person(email: email)
19
+ end
20
+
21
+ def find_people(query)
22
+ # these are boolean but the API wants 0 or 1
23
+ [:calc_found_rows, :preview].each do |k|
24
+ query[k] = 1 if query[k]
25
+ end
26
+ response = get('/person/list.json', query)
27
+ store_balance(response)
28
+ if persons = response.fetch(:response,{}).fetch(:person_list,{})[:persons]
29
+ return persons.map{|p| NetProspex::Api::Person.new(p)}
30
+ else
31
+ return [] #TODO should this raise an error?
32
+ end
33
+ end
34
+
35
+ protected
36
+ def store_balance(hash)
37
+ balance = hash.fetch(:response,{}).fetch(:transaction,{})[:account_end_balance]
38
+ @account_balance = balance if balance
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module NetProspex
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'netprospex/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'netprospex-ruby'
8
+ gem.version = NetProspex::VERSION
9
+ gem.authors = ['Michael Limiero']
10
+ gem.email = ['mike5713@gmail.com']
11
+ gem.homepage = 'https://github.com/SalesLoft/netprospex-ruby'
12
+ gem.summary = %q{Ruby bindings for NetProspex API}
13
+ gem.description = %q{The NetProspex API provides search and lookup for detailed information on people and companies.}
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ['lib']
20
+
21
+ gem.add_development_dependency 'bundler', '~> 1.3'
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'rspec'
24
+ gem.add_development_dependency 'webmock'
25
+ gem.add_development_dependency 'vcr'
26
+ gem.add_runtime_dependency 'activesupport'
27
+ gem.add_runtime_dependency 'faraday'
28
+ gem.add_runtime_dependency 'faraday_middleware'
29
+ gem.add_runtime_dependency 'json'
30
+ gem.add_runtime_dependency 'simple_oauth'
31
+ end