demandbase 0.1.4 → 0.1.5
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.
- 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
|