demandbase 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +462 -4
- data/VERSION +1 -1
- data/demandbase.gemspec +6 -2
- data/lib/demandbase.rb +136 -3
- data/lib/demandbase/domain_record.rb +84 -0
- data/lib/demandbase/ip_record.rb +98 -0
- data/lib/demandbase/record.rb +0 -72
- data/test/test_demandbase.rb +54 -35
- data/test/test_domain_record.rb +78 -0
- data/test/test_ip_record.rb +53 -0
- data/test/test_record.rb +61 -61
- metadata +7 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
data/demandbase.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "demandbase"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Lee Reilly"]
|
12
|
-
s.date = "2013-03-
|
12
|
+
s.date = "2013-03-24"
|
13
13
|
s.description = "Ruby wrapper for the Demandbase API"
|
14
14
|
s.email = "lee@leereilly.net"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,10 +26,14 @@ Gem::Specification.new do |s|
|
|
26
26
|
"VERSION",
|
27
27
|
"demandbase.gemspec",
|
28
28
|
"lib/demandbase.rb",
|
29
|
+
"lib/demandbase/domain_record.rb",
|
29
30
|
"lib/demandbase/error.rb",
|
31
|
+
"lib/demandbase/ip_record.rb",
|
30
32
|
"lib/demandbase/record.rb",
|
31
33
|
"test/helper.rb",
|
32
34
|
"test/test_demandbase.rb",
|
35
|
+
"test/test_domain_record.rb",
|
36
|
+
"test/test_ip_record.rb",
|
33
37
|
"test/test_record.rb"
|
34
38
|
]
|
35
39
|
s.homepage = "http://github.com/leereilly/demandbase"
|
data/lib/demandbase.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'public_suffix'
|
3
|
+
require 'resolv'
|
3
4
|
require 'rest_client'
|
4
5
|
|
5
6
|
require 'demandbase/error'
|
6
7
|
require 'demandbase/record'
|
8
|
+
require 'demandbase/ip_record'
|
9
|
+
require 'demandbase/domain_record'
|
7
10
|
|
8
11
|
module Demandbase
|
9
12
|
|
@@ -27,8 +30,95 @@ module Demandbase
|
|
27
30
|
"8299" # schools and educational services, not elsewhere classified
|
28
31
|
]
|
29
32
|
|
33
|
+
# SIC codes for government.
|
34
|
+
GOVERNMENT_SIC_CODES = [
|
35
|
+
"91", # executive, legislative, and general government, except finance
|
36
|
+
"911", # executive offices
|
37
|
+
"9111", # executive offices
|
38
|
+
"912", # legislative bodies
|
39
|
+
"9121", # legislative bodies
|
40
|
+
"913", # executive and legislative offices combined
|
41
|
+
"9131", # executive and legislative offices combined
|
42
|
+
"919", # general government, not elsewhere classified
|
43
|
+
"9199", # general government, not elsewhere classified
|
44
|
+
"92", # justice, public order, and safety
|
45
|
+
"921", # courts
|
46
|
+
"9211", # courts
|
47
|
+
"922", # public order and safety
|
48
|
+
"9221", # police protection
|
49
|
+
"9222", # legal counsel and prosecution
|
50
|
+
"9223", # correctional institutions
|
51
|
+
"9224", # fire protection
|
52
|
+
"9229", # public order and safety, not elsewhere classified
|
53
|
+
"93", # public finance, taxation, and monetary policy
|
54
|
+
"931", # public finance, taxation, and monetary policy
|
55
|
+
"9311", # public finance, taxation, and monetary policy
|
56
|
+
"94", # administration of human resource programs
|
57
|
+
"941", # administration of educational programs
|
58
|
+
"9411", # administration of educational programs
|
59
|
+
"943", # administration of public health programs
|
60
|
+
"9431", # administration of educational programs
|
61
|
+
"944", # administration of social, human resource and income maintenance programs
|
62
|
+
"9441", # administration of social, human resource and income maintenance prorgrams
|
63
|
+
"945", # administration of veterans' affairs, except health and insurance
|
64
|
+
"9451", # administration of veterans' affairs, except health and insurance
|
65
|
+
"95", # administration of environmental quality and housing programs
|
66
|
+
"951", # administration of environmental quality programs
|
67
|
+
"9511", # air and water resource and solid waste management
|
68
|
+
"9512", # land, mineral, wildlife, and forest conservation
|
69
|
+
"953", # administration of housing and urban development progr
|
70
|
+
"9531", # administration of housing programs
|
71
|
+
"9532", # administration of urban planning and community and rural development
|
72
|
+
"96", # administration of economic programs
|
73
|
+
"961", # administration of general economic programs
|
74
|
+
"9611", # administration of general economic programs
|
75
|
+
"962", # regulation and administration of transportation programs
|
76
|
+
"9621", # regulation and administration of transportation programs
|
77
|
+
"963", # regulation and administration of communications, electric, gas, and other utilities
|
78
|
+
"9631", # regulation and administration of communications, electric, gas, and other utilities
|
79
|
+
"964", # regulation of agricultural marketing and commodities
|
80
|
+
"9641", # regulation of agricultural marketing and commodities
|
81
|
+
"965", # regulation, licensing, and inspection of miscellaneous commercial
|
82
|
+
"9561", # regulation, licensing, and inspection of miscellaneous commercial
|
83
|
+
"966", # space research and technology
|
84
|
+
"9661", # space research and technology
|
85
|
+
"977", # national security and international affairs
|
86
|
+
"971", # national security
|
87
|
+
"9711", # national security
|
88
|
+
"972", # international affairs
|
89
|
+
"9721" # international affairs
|
90
|
+
]
|
91
|
+
|
92
|
+
# SIC codes for registered nonprofits.
|
93
|
+
NONPROFIT_SIC_CODES = [
|
94
|
+
"6732", # Educational, religious, and charitable Trusts
|
95
|
+
"864", # Civic, social, and fraternal associations
|
96
|
+
"8641", # Civic, social, and fraternal associations
|
97
|
+
"865", # Political organizations
|
98
|
+
"8651", # Political organizations
|
99
|
+
"866", # Religious organizations
|
100
|
+
"8661", # Religious organizations
|
101
|
+
"869", # Membership organizations, not elsewhere classified
|
102
|
+
"8699" # Membership organizations, not elsewhere classified
|
103
|
+
]
|
104
|
+
|
30
105
|
class << self
|
31
106
|
|
107
|
+
def lookup_ip(query)
|
108
|
+
Demandbase::IPRecord.new(query)
|
109
|
+
end
|
110
|
+
alias_method :lookup_ip_address, :lookup_ip
|
111
|
+
|
112
|
+
def lookup_domain(query)
|
113
|
+
Demandbase::DomainRecord.new(query)
|
114
|
+
end
|
115
|
+
alias_method :lookup_domain_name, :lookup_domain
|
116
|
+
|
117
|
+
def lazy_lookup
|
118
|
+
|
119
|
+
end
|
120
|
+
alias_method :lookup, :lazy_lookup
|
121
|
+
|
32
122
|
# Look up a Demandbase record for a given domain name.
|
33
123
|
#
|
34
124
|
# Returns a Demandbase::Record if the record is found; nil otherwise.
|
@@ -37,8 +127,14 @@ module Demandbase
|
|
37
127
|
# Raises a Demandbase::ParseError if the domain doesn't look legit.
|
38
128
|
# Raises a Demandbase::ServerError if the Demandbase server is unresponsive.
|
39
129
|
#
|
40
|
-
def lookup(
|
41
|
-
Demandbase::
|
130
|
+
def lookup(query)
|
131
|
+
if Demandbase::IPRecord.is_ip(query)
|
132
|
+
Demandbase::IPRecord.new(query)
|
133
|
+
elsif Demandbase::DomainRecord.is_domain(query)
|
134
|
+
Demandbase::DomainRecord.new(query)
|
135
|
+
else
|
136
|
+
raise Demandbase::ParseError
|
137
|
+
end
|
42
138
|
end
|
43
139
|
|
44
140
|
# Find out if a particular domain is associated with an academic institution.
|
@@ -50,12 +146,49 @@ module Demandbase
|
|
50
146
|
# Raises a Demandbase::ServerError if the Demandbase server is unresponsive.
|
51
147
|
#
|
52
148
|
def is_academic?(domain)
|
53
|
-
record = Demandbase::
|
149
|
+
record = Demandbase::DomainRecord.new(domain)
|
150
|
+
|
54
151
|
if record && ACADEMIC_SIC_CODES.include?(record.primary_sic)
|
55
152
|
return true
|
56
153
|
else
|
57
154
|
return false
|
58
155
|
end
|
59
156
|
end
|
157
|
+
|
158
|
+
# Find out if a particular domain is associated with an government agency.
|
159
|
+
#
|
160
|
+
# Returns true if it looks like an government agency; false otherwise.
|
161
|
+
#
|
162
|
+
# Raises a Demandbase::RTIDNotSetError if a RTID key is not set.
|
163
|
+
# Raises a Demandbase::ParseError if the domain doesn't look legit.
|
164
|
+
# Raises a Demandbase::ServerError if the Demandbase server is unresponsive.
|
165
|
+
#
|
166
|
+
def is_government?(domain)
|
167
|
+
record = Demandbase::DomainRecord.new(domain)
|
168
|
+
|
169
|
+
if record && GOVERNMENT_SIC_CODES.include?(record.primary_sic)
|
170
|
+
return true
|
171
|
+
else
|
172
|
+
return false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Find out if a particular domain is associated with a nonprofit.
|
177
|
+
#
|
178
|
+
# Returns true if it looks like a nonprofit; false otherwise.
|
179
|
+
#
|
180
|
+
# Raises a Demandbase::RTIDNotSetError if a RTID key is not set.
|
181
|
+
# Raises a Demandbase::ParseError if the domain doesn't look legit.
|
182
|
+
# Raises a Demandbase::ServerError if the Demandbase server is unresponsive.
|
183
|
+
#
|
184
|
+
def is_nonprofit?(domain)
|
185
|
+
record = Demandbase::DomainRecord.new(domain)
|
186
|
+
|
187
|
+
if record && NONPROFIT_SIC_CODES.include?(record.primary_sic)
|
188
|
+
return true
|
189
|
+
else
|
190
|
+
return false
|
191
|
+
end
|
192
|
+
end
|
60
193
|
end
|
61
194
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Demandbase
|
2
|
+
class DomainRecord < Demandbase::Record
|
3
|
+
|
4
|
+
# Return the base URL for the Demandbase domain API
|
5
|
+
def api_url
|
6
|
+
"http://api.demandbase.com/api/v1/domain.json?key=#{rtid_key}"
|
7
|
+
end
|
8
|
+
|
9
|
+
# Ascertain whether the given query string is a valid domain name.
|
10
|
+
#
|
11
|
+
# Returns true if it's a valid domain name; false otherwise.
|
12
|
+
def self.is_domain(query)
|
13
|
+
begin
|
14
|
+
result = PublicSuffix.valid?((Demandbase::DomainRecord.cleanse_domain(query)))
|
15
|
+
result
|
16
|
+
rescue => e
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Instantiate a new Demandbase Domain Record from a domain name.
|
22
|
+
def initialize(domain)
|
23
|
+
raise Demandbase::RTIDNotSetError if rtid_key.nil?
|
24
|
+
|
25
|
+
begin
|
26
|
+
query = Demandbase::DomainRecord.cleanse_domain(domain)
|
27
|
+
url = api_url + "&query=#{query}"
|
28
|
+
rescue => e
|
29
|
+
raise Demandbase::ParseError
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
response = JSON.parse(RestClient.get(url))
|
34
|
+
|
35
|
+
return nil unless response["domain"]
|
36
|
+
|
37
|
+
@company_name = response["domain"]["company_name"]
|
38
|
+
@demandbase_sid = response["domain"]["demandbase_sid"]
|
39
|
+
@marketing_alias = response["domain"]["marketing_alias"]
|
40
|
+
@industry = response["domain"]["industry"]
|
41
|
+
@sub_industry = response["domain"]["sub_industry"]
|
42
|
+
@employee_count = response["domain"]["employee_count"]
|
43
|
+
@primary_sic = response["domain"]["primary_sic"]
|
44
|
+
@street_address = response["domain"]["street_address"]
|
45
|
+
@city = response["domain"]["city"]
|
46
|
+
@state = response["domain"]["state"]
|
47
|
+
@zip = response["domain"]["zip"]
|
48
|
+
@country = response["domain"]["country"]
|
49
|
+
@country_name = response["domain"]["country_name"]
|
50
|
+
@phone = response["domain"]["phone"]
|
51
|
+
@stock_ticker = response["domain"]["stock_ticker"]
|
52
|
+
@web_site = response["domain"]["web_site"]
|
53
|
+
@annual_sales = response["domain"]["annual_sales"]
|
54
|
+
@revenue_range = response["domain"]["revenue_range"]
|
55
|
+
@employee_range = response["domain"]["employee_range"]
|
56
|
+
@b2b = response["domain"]["b2b"]
|
57
|
+
@b2c = response["domain"]["b2c"]
|
58
|
+
@traffic = response["domain"]["traffic"]
|
59
|
+
@latitude = response["domain"]["latitude"]
|
60
|
+
@longitude = response["domain"]["longitude"]
|
61
|
+
@fortune_1000 = response["domain"]["fortune_1000"]
|
62
|
+
@forbes_2000 = response["domain"]["forbes_2000"]
|
63
|
+
rescue => e
|
64
|
+
raise ServerError
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Clean the domain of things like 'http(s)://', 'www',
|
69
|
+
# '?foo=bar', etc.
|
70
|
+
#
|
71
|
+
# Return the domain string.
|
72
|
+
def self.cleanse_domain(domain)
|
73
|
+
domain.downcase!
|
74
|
+
domain = domain.sub(/^https?\:\/\//, '').sub(/^www./,'')
|
75
|
+
domain = domain.split( "/").first
|
76
|
+
domain = domain.split("@").last
|
77
|
+
|
78
|
+
domain = PublicSuffix.parse(domain)
|
79
|
+
domain = "#{domain.sld}.#{domain.tld}"
|
80
|
+
domain
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Demandbase
|
2
|
+
class IPRecord < Demandbase::Record
|
3
|
+
attr_accessor :registry_company_name
|
4
|
+
attr_accessor :registry_city
|
5
|
+
attr_accessor :registry_state
|
6
|
+
attr_accessor :registry_zip_code
|
7
|
+
attr_accessor :registry_area_code
|
8
|
+
attr_accessor :registry_country
|
9
|
+
attr_accessor :registry_country_code
|
10
|
+
attr_accessor :registry_latitude
|
11
|
+
attr_accessor :registry_longitude
|
12
|
+
attr_accessor :ip
|
13
|
+
attr_accessor :information_level
|
14
|
+
attr_accessor :audience
|
15
|
+
attr_accessor :audience_segment
|
16
|
+
attr_accessor :information_level
|
17
|
+
attr_accessor :worldhq_sid
|
18
|
+
attr_accessor :domestichq_sid
|
19
|
+
attr_accessor :hq_sid
|
20
|
+
attr_accessor :isp
|
21
|
+
|
22
|
+
# Return the base URL for the Demandbase IP API
|
23
|
+
def api_url
|
24
|
+
"http://api.demandbase.com/api/v2/ip.json?key=#{rtid_key}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Ascertain whether the given query string is a valid IP address.
|
28
|
+
#
|
29
|
+
# Returns true if it's a valid IP address; false otherwise.
|
30
|
+
def self.is_ip(query)
|
31
|
+
!!(query =~ Resolv::IPv4::Regex)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Instantiate a new Demandbase IP Record from an IP address.
|
35
|
+
def initialize(ip)
|
36
|
+
raise Demandbase::RTIDNotSetError if rtid_key.nil?
|
37
|
+
|
38
|
+
begin
|
39
|
+
url = api_url + "&query=#{ip}"
|
40
|
+
rescue => e
|
41
|
+
raise Demandbase::ParseError
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
response = JSON.parse(RestClient.get(url))
|
46
|
+
return nil unless response
|
47
|
+
|
48
|
+
@registry_company_name = response["registry_company_name"]
|
49
|
+
@registry_city = response["registry_city"]
|
50
|
+
@registry_state = response["registry_state"]
|
51
|
+
@registry_zip_code = response["registry_zip_code"]
|
52
|
+
@registry_area_code = response["registry_area_code"]
|
53
|
+
@registry_country = response["registry_country"]
|
54
|
+
@registry_country_code = response["registry_country_code"]
|
55
|
+
@registry_latitude = response["registry_latitude"]
|
56
|
+
@registry_longitude = response["registry_longitude"]
|
57
|
+
@company_name = response["company_name"]
|
58
|
+
@demandbase_sid = response["demandbase_sid"]
|
59
|
+
@marketing_alias = response["marketing_alias"]
|
60
|
+
@industry = response["industry"]
|
61
|
+
@sub_industry = response["sub_industry"]
|
62
|
+
@employee_count = response["employee_count"]
|
63
|
+
@primary_sic = response["primary_sic"]
|
64
|
+
@street_address = response["street_address"]
|
65
|
+
@city = response["city"]
|
66
|
+
@state = response["state"]
|
67
|
+
@zip = response["zip"]
|
68
|
+
@country = response["country"]
|
69
|
+
@country_name = response["country_name"]
|
70
|
+
@phone = response["phone"]
|
71
|
+
@stock_ticker = response["stock_ticker"]
|
72
|
+
@web_site = response["web_site"]
|
73
|
+
@annual_sales = response["annual_sales"]
|
74
|
+
@revenue_range = response["revenue_range"]
|
75
|
+
@employee_range = response["employee_range"]
|
76
|
+
@b2b = response["b2b"]
|
77
|
+
@b2c = response["b2c"]
|
78
|
+
@traffic = response["traffic"]
|
79
|
+
@latitude = response["latitude"]
|
80
|
+
@longitude = response["longitude"]
|
81
|
+
@fortune_1000 = response["fortune_1000"]
|
82
|
+
@forbes_2000 = response["forbes_2000"]
|
83
|
+
@ip = response["ip"]
|
84
|
+
@audience = response["audience"]
|
85
|
+
@audience_segment = response["audience_segment"]
|
86
|
+
@information_level = response["information_level"]
|
87
|
+
@worldhq_sid = response["worldhq_sid"]
|
88
|
+
@domestichq_sid = response["domestichq_sid"]
|
89
|
+
@hq_sid = response["hq_sid"]
|
90
|
+
@isp = response["isp"]
|
91
|
+
rescue RestClient::ResourceNotFound => rcrnf
|
92
|
+
return nil
|
93
|
+
rescue
|
94
|
+
raise ServerError
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/demandbase/record.rb
CHANGED
@@ -27,81 +27,9 @@ module Demandbase
|
|
27
27
|
attr_accessor :fortune_1000
|
28
28
|
attr_accessor :forbes_2000
|
29
29
|
|
30
|
-
# Instantiate a new Demandbase Record from a domain name.
|
31
|
-
def initialize(domain)
|
32
|
-
raise Demandbase::RTIDNotSetError if rtid_key.nil?
|
33
|
-
|
34
|
-
begin
|
35
|
-
query = cleanse_domain(domain)
|
36
|
-
url = domain_api_url + "&query=#{query}"
|
37
|
-
rescue => e
|
38
|
-
raise Demandbase::ParseError
|
39
|
-
end
|
40
|
-
|
41
|
-
begin
|
42
|
-
response = JSON.parse(RestClient.get(url))
|
43
|
-
|
44
|
-
return nil unless response["domain"]
|
45
|
-
|
46
|
-
@company_name = response["domain"]["company_name"]
|
47
|
-
@demandbase_sid = response["domain"]["demandbase_sid"]
|
48
|
-
@marketing_alias = response["domain"]["marketing_alias"]
|
49
|
-
@industry = response["domain"]["industry"]
|
50
|
-
@sub_industry = response["domain"]["sub_industry"]
|
51
|
-
@employee_count = response["domain"]["employee_count"]
|
52
|
-
@primary_sic = response["domain"]["primary_sic"]
|
53
|
-
@street_address = response["domain"]["street_address"]
|
54
|
-
@city = response["domain"]["city"]
|
55
|
-
@state = response["domain"]["state"]
|
56
|
-
@zip = response["domain"]["zip"]
|
57
|
-
@country = response["domain"]["country"]
|
58
|
-
@country_name = response["domain"]["country_name"]
|
59
|
-
@phone = response["domain"]["phone"]
|
60
|
-
@stock_ticker = response["domain"]["stock_ticker"]
|
61
|
-
@web_site = response["domain"]["web_site"]
|
62
|
-
@annual_sales = response["domain"]["annual_sales"]
|
63
|
-
@revenue_range = response["domain"]["revenue_range"]
|
64
|
-
@employee_range = response["domain"]["employee_range"]
|
65
|
-
@b2b = response["domain"]["b2b"]
|
66
|
-
@b2c = response["domain"]["b2c"]
|
67
|
-
@traffic = response["domain"]["traffic"]
|
68
|
-
@latitude = response["domain"]["latitude"]
|
69
|
-
@longitude = response["domain"]["longitude"]
|
70
|
-
@fortune_1000 = response["domain"]["fortune_1000"]
|
71
|
-
@forbes_2000 = response["domain"]["forbes_2000"]
|
72
|
-
rescue => e
|
73
|
-
raise ServerError
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Clean the domain of things like 'http(s)://', 'www',
|
78
|
-
# '?foo=bar', etc.
|
79
|
-
#
|
80
|
-
# Return the domain string.
|
81
|
-
def cleanse_domain(domain)
|
82
|
-
domain.downcase!
|
83
|
-
domain = domain.sub(/^https?\:\/\//, '').sub(/^www./,'')
|
84
|
-
domain = domain.split( "/").first
|
85
|
-
domain = domain.split("@").last
|
86
|
-
|
87
|
-
domain = PublicSuffix.parse(domain)
|
88
|
-
domain = "#{domain.sld}.#{domain.tld}"
|
89
|
-
domain
|
90
|
-
end
|
91
|
-
|
92
30
|
# Return the Demandbase RTID from the environment.
|
93
31
|
def rtid_key
|
94
32
|
ENV['DEMANDBASE_RTID_KEY']
|
95
33
|
end
|
96
|
-
|
97
|
-
# Return the base URL for the Demandbase domain API
|
98
|
-
def domain_api_url
|
99
|
-
"http://api.demandbase.com/api/v1/domain.json?key=#{rtid_key}"
|
100
|
-
end
|
101
|
-
|
102
|
-
# Return the base URL for the Demandbase IP API
|
103
|
-
def ip_api_url
|
104
|
-
"http://api.demandbase.com/api/v1/ip.json?key=#{rtid_key}"
|
105
|
-
end
|
106
34
|
end
|
107
35
|
end
|