domain_tools 0.0.1
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/examples/1_prepare.rb +49 -0
- data/examples/2_response.rb +31 -0
- data/examples/3_browsing.rb +36 -0
- data/examples/4_error.rb +40 -0
- data/examples/5_complete.rb +49 -0
- data/lib/domain_tools/core.rb +137 -0
- data/lib/domain_tools/error.rb +40 -0
- data/lib/domain_tools/error_parser.rb +19 -0
- data/lib/domain_tools/exceptions.rb +34 -0
- data/lib/domain_tools/json_parser.rb +10 -0
- data/lib/domain_tools/request.rb +173 -0
- data/lib/domain_tools/response.rb +78 -0
- data/lib/domain_tools/util.rb +12 -0
- data/lib/domain_tools/xml_parser.rb +31 -0
- data/lib/domain_tools.rb +28 -0
- metadata +81 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
# 1. PREPARE THE ENVIRONMENT
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
# 1.A Define settings step by step
|
6
|
+
# This a a clear way to define each settings
|
7
|
+
DomainTools::use(DOMAINTOOLS_USERNAME,DOMAINTOOLS_KEY)
|
8
|
+
DomainTools::get("whois")
|
9
|
+
DomainTools::as("json")
|
10
|
+
DomainTools::on("domaintools.com")
|
11
|
+
DomainTools::where("var1=value1&var2=value2")
|
12
|
+
|
13
|
+
# 1.B All in one with a hash
|
14
|
+
# Useful to separate in a settings file your default configuration
|
15
|
+
DomainTools::with({
|
16
|
+
:username => DOMAINTOOLS_USERNAME,
|
17
|
+
:key => DOMAINTOOLS_KEY,
|
18
|
+
:service => "whois",
|
19
|
+
:format => "json",
|
20
|
+
:domain => "domaintools.com",
|
21
|
+
:parameters => "var1=value1&var2=value2"
|
22
|
+
})
|
23
|
+
|
24
|
+
# 1.C Inline
|
25
|
+
# Each call can be chained, useful in some case to gain spaces in your code
|
26
|
+
DomainTools::use(DOMAINTOOLS_USERNAME,DOMAINTOOLS_KEY)
|
27
|
+
DomainTools::get("whois")::as("json")::on("domaintools.com")
|
28
|
+
|
29
|
+
# -----------------------------------------------------------------------------
|
30
|
+
# TIPS
|
31
|
+
# -----------------------------------------------------------------------------
|
32
|
+
# The parameters (set with the static call "where" or with the hash
|
33
|
+
# key "parameters") can either be a string or a Hash.
|
34
|
+
# If a hash is provided, it will be merged in a string before request execution
|
35
|
+
|
36
|
+
# Using the "where" call to specify the parameters
|
37
|
+
DomainTools::where({
|
38
|
+
:var1 => "value1",
|
39
|
+
:var2 => "value2"
|
40
|
+
})
|
41
|
+
|
42
|
+
# Or using the "with" (hash) settiings method and the key "parameters"
|
43
|
+
DomainTools::with({
|
44
|
+
# ...
|
45
|
+
:parameters => {
|
46
|
+
:var1 => "value1",
|
47
|
+
:var2 => "value2"
|
48
|
+
}
|
49
|
+
})
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
# 2. GET RAW API RESULT (JSON, XML or HTML)
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
# Note: each of these examples assume that "prepare" step (see example 1.)
|
5
|
+
# has been done with valid credentials
|
6
|
+
|
7
|
+
|
8
|
+
# 2.A The "step by step" way
|
9
|
+
request = DomainTools.request # Get a request object
|
10
|
+
request.format = "json" #xml,html # Define the response format
|
11
|
+
request.domain = "domaintools.com" # Define the domain
|
12
|
+
response = request.do # Execute the request
|
13
|
+
@example1 = response.to_s # Save the raw result in a variable
|
14
|
+
|
15
|
+
# 2.B You can do the same but inline
|
16
|
+
@example2 = DomainTools::as("json")::on("domaintools.com").do.to_s
|
17
|
+
|
18
|
+
# -----------------------------------------------------------------------------
|
19
|
+
# TIPS
|
20
|
+
# -----------------------------------------------------------------------------
|
21
|
+
# There are aliases for each method on each DomainTools related object.
|
22
|
+
# It allows you to use great shortcuts to quickly write requests
|
23
|
+
|
24
|
+
# Here is 3 line doing exactly the same thing :
|
25
|
+
# - Create a request (with default settings provided)
|
26
|
+
# - Execute the request
|
27
|
+
# - Return a Response object
|
28
|
+
|
29
|
+
@example3 = DomainTools.request.response
|
30
|
+
@example4 = DomainTools.request.do
|
31
|
+
@example5 = DomainTools.do
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
# 3. BROWSE AN API RESPONSE
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
# Note: each of these examples assume that "prepare" step (see example 1.)
|
5
|
+
# has been done with valid credentials
|
6
|
+
|
7
|
+
|
8
|
+
# 3.A The "do it yourself" way
|
9
|
+
# get the raw result (json)
|
10
|
+
request = DomainTools.request
|
11
|
+
request.format = "json" # (or xml)
|
12
|
+
response = request.response
|
13
|
+
# Use JSON.decode to parse the result (REXML for xml, for example)
|
14
|
+
hash = ActiveSupport::JSON.decode(response.content)
|
15
|
+
# Simply use it as a Hash
|
16
|
+
@example1 = hash["response"]["registration"]["registrar"]
|
17
|
+
|
18
|
+
|
19
|
+
# 3.B The "auto parse" way
|
20
|
+
# get the response (without even knowing the request format!)
|
21
|
+
response = DomainTools.request.response
|
22
|
+
# The DomainTools wrapper will parse the result automaticaly
|
23
|
+
# You can now use to_hash method to get a hash and use it
|
24
|
+
@example2 = response.to_hash["response"]["registration"]["registrar"]
|
25
|
+
|
26
|
+
|
27
|
+
# 3.C The short way, inline
|
28
|
+
# Like always, you can do this inline!
|
29
|
+
@example3 = DomainTools.request.do["response"]["registration"]["registrar"]
|
30
|
+
|
31
|
+
|
32
|
+
# -----------------------------------------------------------------------------
|
33
|
+
# TIPS
|
34
|
+
# -----------------------------------------------------------------------------
|
35
|
+
# Using the direct browsing of the hash assumes you are sure of the response
|
36
|
+
# structure. Some tests for nil values can be useful!
|
data/examples/4_error.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
# 4. ERROR HANDLING
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
# Note: each of these examples assume that "prepare" step (see example 1.)
|
5
|
+
# has been done with valid credentials
|
6
|
+
|
7
|
+
# 4.A When you execute a request, it can raise an exception, you need
|
8
|
+
# to be ready to catch it.
|
9
|
+
begin
|
10
|
+
request = DomainTools.request
|
11
|
+
request.domain = "domaintoolscom" # This is not a valid domain
|
12
|
+
request.response # Execute the request
|
13
|
+
# here an execption will be thrown, we'll fallback to the rescue part
|
14
|
+
@example1 = "I will never be seen"
|
15
|
+
rescue DomainTools::ServiceException => e
|
16
|
+
if request.error? # test if there is an error
|
17
|
+
@example1 = "#{e.class}: #{request.error}"
|
18
|
+
# you can also get the error code with request.error.code
|
19
|
+
# and the error message with request.error.message
|
20
|
+
else
|
21
|
+
@example1 = "The request has no error but raises an exception. Unlikely to hapenned"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# -----------------------------------------------------------------------------
|
26
|
+
# TIPS
|
27
|
+
# -----------------------------------------------------------------------------
|
28
|
+
# Here is the list of possible exceptions (and their inheritance)
|
29
|
+
|
30
|
+
# ServiceException < StandardError
|
31
|
+
# NoSettingsException < ServiceException
|
32
|
+
# NoCredentialsException < ServiceException
|
33
|
+
# BadRequestException < ServiceException
|
34
|
+
# NotAuthorizedException < ServiceException
|
35
|
+
# NotFoundException < ServiceException
|
36
|
+
# InternalServerErrorException < ServiceException
|
37
|
+
# ServiceUnavailableException < ServiceException
|
38
|
+
# WrongParmatersException < ServiceException
|
39
|
+
# NoDomainException < ServiceException
|
40
|
+
# UnknownException < ServiceException
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
# 5. SYNTAX & FORMAT FLEXIBILITY
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
# The idea behind this wrapper is to allow you to choose the syntax that feets your style.
|
6
|
+
# The lib will assume for you that you need to start a request only when you print or browse a response.
|
7
|
+
# You can use the module itself, the request or the response and ask for format changes or object browsing,
|
8
|
+
# it will just do the effort for you and prepare/execute/parse the whole request
|
9
|
+
# Here down a complete example of requests, responses, tests...
|
10
|
+
|
11
|
+
|
12
|
+
# Set credentials and create a new request
|
13
|
+
request = DomainTools::use(DOMAINTOOLS_USERNAME,DOMAINTOOLS_KEY).request
|
14
|
+
# Set the domain
|
15
|
+
request.domain = "domaintools.com"
|
16
|
+
# Set the format
|
17
|
+
request.format = "json"
|
18
|
+
# Execute the request (and then get a json result)
|
19
|
+
begin
|
20
|
+
@example1 = request.do.to_s
|
21
|
+
# Recreate a valid xml with the parsed json (no new request made)
|
22
|
+
@example2 = request.to_xml!
|
23
|
+
# print some debug as yaml
|
24
|
+
puts request.to_yaml
|
25
|
+
# finally just get a specific data
|
26
|
+
begin
|
27
|
+
@example3 = request["response"]["registrant"]["name"]
|
28
|
+
rescue NoMethodError => e # If you try to browse nil
|
29
|
+
@example3 = "Unable to find registrant name"
|
30
|
+
end
|
31
|
+
# Note: Despite all manipulations, only ONE API request has been made
|
32
|
+
# We change the service
|
33
|
+
request.service = "hosting-history"
|
34
|
+
# And the response format
|
35
|
+
request.format = "xml"
|
36
|
+
# And we force a new request with ("do!" instead of "do")
|
37
|
+
@example4 = request.do!
|
38
|
+
begin
|
39
|
+
@example5 = request["response"]["ip_history"].first["actiondate"]
|
40
|
+
rescue NoMethodError => e
|
41
|
+
@example5 = "No IP history"
|
42
|
+
end
|
43
|
+
rescue DomainTools::ServiceException => e
|
44
|
+
if request && request.error?
|
45
|
+
@error = "#{e.class}: #{request.error}"
|
46
|
+
else
|
47
|
+
@error = "Unknown error: #{e.message}"
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module DomainTools
|
2
|
+
extend self
|
3
|
+
include Exceptions
|
4
|
+
|
5
|
+
# Authentication of the user
|
6
|
+
# can be set with a hash {:username,:password} as one param
|
7
|
+
# or with two string params
|
8
|
+
def self.use(credentials,key=false)
|
9
|
+
if credentials.kind_of? Hash
|
10
|
+
self.set_data :username, credentials[:username]
|
11
|
+
self.set_data :key, credentials[:key]
|
12
|
+
else
|
13
|
+
self.set_data :username, credentials
|
14
|
+
self.set_data :key, key
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.clear
|
20
|
+
@data = {}
|
21
|
+
@request = nil
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Select which service must be called for this request
|
26
|
+
def self.get(service)
|
27
|
+
self.set_data :service, service
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.sign(active)
|
31
|
+
self.set_data :signed, active
|
32
|
+
end
|
33
|
+
|
34
|
+
# change the format of the response (only XML or JSON)
|
35
|
+
def self.as(format)
|
36
|
+
self.set_data :format, format
|
37
|
+
end
|
38
|
+
|
39
|
+
# to specify parameters to the service
|
40
|
+
def self.where(parameters)
|
41
|
+
self.set_data :parameters, parameters
|
42
|
+
end
|
43
|
+
|
44
|
+
# to overide settings, only for specific cases or for testing
|
45
|
+
def self.with(settings={})
|
46
|
+
settings.each{|key, value| set_data(key,value)}
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Param of the request, usually a domain name or sometime the first part of a domain
|
51
|
+
def self.on(domain)
|
52
|
+
self.set_data :domain, domain
|
53
|
+
end
|
54
|
+
|
55
|
+
# check first, raise exception if needed, execute the HTTP request
|
56
|
+
def self.do
|
57
|
+
self.request.do
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.response
|
61
|
+
self.do
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.request
|
65
|
+
raise DomainTools::NoSettingsException unless @request
|
66
|
+
@request
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.counter
|
70
|
+
return 0 unless @counter
|
71
|
+
@counter
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.counter!
|
75
|
+
@counter = 0 unless @counter
|
76
|
+
@counter+=1
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.[](key)
|
80
|
+
self.do unless self.done?
|
81
|
+
self.request[key]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Request aliases
|
85
|
+
|
86
|
+
def self.done?
|
87
|
+
self.request.done?
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.error?
|
91
|
+
self.request.error?
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.success?
|
95
|
+
self.request.success?
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.to_s
|
99
|
+
self.request.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.to_hash
|
103
|
+
self.request.to_hash
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.to_json
|
107
|
+
self.request.to_json
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.to_json!
|
111
|
+
self.request.to_json!
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.to_xml
|
115
|
+
self.request.to_xml
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.to_xml!
|
119
|
+
self.request.to_xml!
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.to_yaml
|
123
|
+
self.request.to_yaml
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def self.set_data(key,val)
|
129
|
+
@data = {} unless @data
|
130
|
+
@data[key.to_sym] = val
|
131
|
+
# Update data for future request
|
132
|
+
@request = DomainTools::Request.new @data
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module DomainTools
|
2
|
+
class Error
|
3
|
+
|
4
|
+
def initialize(request,service_excepton)
|
5
|
+
@request = request
|
6
|
+
@exception = service_excepton
|
7
|
+
parse
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse
|
11
|
+
if @request.format=="xml"
|
12
|
+
error = DomainTools::ErrorParser.from_xml(@request.content)
|
13
|
+
else
|
14
|
+
error = DomainTools::ErrorParser.from_json(@request.content)
|
15
|
+
end
|
16
|
+
@code, @message = error["code"], error["message"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"[#{@code}] #{@message}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def code
|
24
|
+
@code
|
25
|
+
end
|
26
|
+
|
27
|
+
def message
|
28
|
+
@message
|
29
|
+
end
|
30
|
+
|
31
|
+
def request
|
32
|
+
@request
|
33
|
+
end
|
34
|
+
|
35
|
+
def exception
|
36
|
+
@exception
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DomainTools
|
2
|
+
class ErrorParser
|
3
|
+
|
4
|
+
def self.default_error
|
5
|
+
{:code => 0, :message => "Unknown error message"}
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.from_json(source)
|
9
|
+
hash = JSONParser::parse(source)
|
10
|
+
hash["error"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_xml(source)
|
14
|
+
hash = XMLParser::parse(source)
|
15
|
+
hash["error"]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DomainTools
|
2
|
+
module Exceptions
|
3
|
+
|
4
|
+
class ServiceException < StandardError; end
|
5
|
+
class NoSettingsException < ServiceException; end
|
6
|
+
class NoCredentialsException < ServiceException; end
|
7
|
+
class BadRequestException < ServiceException; end
|
8
|
+
class NotAuthorizedException < ServiceException; end
|
9
|
+
class NotFoundException < ServiceException; end
|
10
|
+
class InternalServerErrorException < ServiceException; end
|
11
|
+
class ServiceUnavailableException < ServiceException; end
|
12
|
+
class WrongParmatersException < ServiceException; end
|
13
|
+
class NoDomainException < ServiceException; end
|
14
|
+
class UnknownException < ServiceException; end
|
15
|
+
|
16
|
+
def self.raise_by_code(code)
|
17
|
+
case code.to_i
|
18
|
+
when 400
|
19
|
+
raise DomainTools::BadRequestException
|
20
|
+
when 401, 403
|
21
|
+
raise DomainTools::NotAuthorizedException
|
22
|
+
when 404
|
23
|
+
raise DomainTools::NotFoundException
|
24
|
+
when 500
|
25
|
+
raise DomainTools::InternalServerErrorException
|
26
|
+
when 503
|
27
|
+
raise DomainTools::ServiceUnavailableException
|
28
|
+
else
|
29
|
+
raise DomainTools::UnknownException
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module DomainTools
|
2
|
+
class Request
|
3
|
+
attr_accessor :domain, :format, :service, :parameters
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
data.each{|key, value| set_data(key,value)}
|
7
|
+
end
|
8
|
+
|
9
|
+
def sign(active)
|
10
|
+
@signed = active
|
11
|
+
end
|
12
|
+
|
13
|
+
def done?
|
14
|
+
return @done
|
15
|
+
end
|
16
|
+
|
17
|
+
def error?
|
18
|
+
return !@error.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def success?
|
22
|
+
return @error.nil? && @http && @http.body
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](key)
|
26
|
+
self.do unless done?
|
27
|
+
@response[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
# build service url
|
31
|
+
def build_url
|
32
|
+
parts = []
|
33
|
+
uri = ""
|
34
|
+
parts << "/#{@version}" if @version
|
35
|
+
parts << "/#{@domain}" if @domain
|
36
|
+
parts << "/#{@service}" if @service
|
37
|
+
uri = parts.join("")
|
38
|
+
parts << "?"
|
39
|
+
parts << "format=#{@format}"
|
40
|
+
parts << "&#{authentication_params(uri)}"
|
41
|
+
parts << "#{format_parameters}" if @parameters
|
42
|
+
@url = parts.join("")
|
43
|
+
end
|
44
|
+
|
45
|
+
def authentication_params(uri)
|
46
|
+
return "&api_username=#{@username}&api_key=#{@key}" unless @signed
|
47
|
+
timestamp = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
48
|
+
data = @username+timestamp+uri
|
49
|
+
require 'openssl'
|
50
|
+
digester = OpenSSL::Digest::Digest.new(DomainTools::DIGEST)
|
51
|
+
signature = OpenSSL::HMAC.hexdigest(digester, @key, data)
|
52
|
+
["api_username=#{@username}","signature=#{signature}","timestamp=#{timestamp}"].join("&")
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def validate
|
57
|
+
raise DomainTools::NoDomainException unless @domain || @parameters
|
58
|
+
raise DomainTools::NoCredentialsException unless @username || @key
|
59
|
+
# must be a valid format (will be default FORMAT constant if empty or wrong)
|
60
|
+
@format = DomainTools::FORMAT if @format!="json" && @format!="xml" && @format != "html"
|
61
|
+
# if not already defined, use default
|
62
|
+
@host = DomainTools::HOST if @host.nil?
|
63
|
+
@port = DomainTools::PORT if @port.nil?
|
64
|
+
@signed = DomainTools::SIGNED if @signed.nil?
|
65
|
+
@version = DomainTools::VERSION if @version.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def do
|
69
|
+
execute
|
70
|
+
end
|
71
|
+
|
72
|
+
def do!
|
73
|
+
execute(true)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Connect to the server and execute the request
|
77
|
+
def execute(refresh=false)
|
78
|
+
return @response if @response && !refresh
|
79
|
+
validate
|
80
|
+
build_url
|
81
|
+
@done = true
|
82
|
+
DomainTools.counter!
|
83
|
+
require 'net/http'
|
84
|
+
begin
|
85
|
+
Net::HTTP.start(@host) do |http|
|
86
|
+
req = Net::HTTP::Get.new(@url)
|
87
|
+
@http = http.request(req)
|
88
|
+
@success = validate_http_status
|
89
|
+
return finalize
|
90
|
+
end
|
91
|
+
rescue DomainTools::ServiceException => e
|
92
|
+
@error = DomainTools::Error.new(self,e)
|
93
|
+
raise e.class.new(e)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def response
|
98
|
+
self.do
|
99
|
+
end
|
100
|
+
|
101
|
+
def error
|
102
|
+
@error ? @error : nil
|
103
|
+
end
|
104
|
+
|
105
|
+
# Check HTTP request status and raise an exception if needed
|
106
|
+
def validate_http_status
|
107
|
+
return true if @http.code.to_i == 200
|
108
|
+
DomainTools::Exceptions::raise_by_code(@http.code)
|
109
|
+
end
|
110
|
+
|
111
|
+
def finalize
|
112
|
+
@response = DomainTools::Response.new(self.clone)
|
113
|
+
end
|
114
|
+
|
115
|
+
def content
|
116
|
+
@http ? @http.body : nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# Response aliases
|
120
|
+
|
121
|
+
def to_s
|
122
|
+
return @response.to_s if @response
|
123
|
+
self.do.to_s
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_hash
|
127
|
+
return @response.to_hash if @response
|
128
|
+
self.do.to_hash
|
129
|
+
end
|
130
|
+
|
131
|
+
def to_json
|
132
|
+
return @response.to_json if @response
|
133
|
+
@format = "json"
|
134
|
+
self.do
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_json!
|
138
|
+
return @response.to_json! if @response
|
139
|
+
self.do.to_json!
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_xml
|
143
|
+
return @response.to_xml if @response
|
144
|
+
@format = "xml"
|
145
|
+
self.do
|
146
|
+
end
|
147
|
+
|
148
|
+
def to_xml!
|
149
|
+
return @response.to_xml! if @response
|
150
|
+
self.do.to_xml!
|
151
|
+
end
|
152
|
+
|
153
|
+
def to_yaml
|
154
|
+
return @response.to_yaml if @response
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def set_data(key,val)
|
161
|
+
eval("@#{key.to_s} = val")
|
162
|
+
end
|
163
|
+
|
164
|
+
def format_parameters
|
165
|
+
string = ""
|
166
|
+
string = @parameters if @parameters.kind_of? String
|
167
|
+
string = DomainTools::Util.vars_hash_to_string(@parameters) if @parameters.kind_of? Hash
|
168
|
+
string = "&#{string}" unless string.start_with?('&')
|
169
|
+
string
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module DomainTools
|
2
|
+
class Response
|
3
|
+
|
4
|
+
def initialize(request)
|
5
|
+
@request = request.clone
|
6
|
+
end
|
7
|
+
|
8
|
+
def request
|
9
|
+
@request
|
10
|
+
end
|
11
|
+
|
12
|
+
def content
|
13
|
+
request.content
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
self.do
|
18
|
+
end
|
19
|
+
|
20
|
+
def do
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
request.content
|
26
|
+
end
|
27
|
+
|
28
|
+
def render
|
29
|
+
to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_hash
|
33
|
+
@parsed_object = parse unless @parsed_object
|
34
|
+
@parsed_object
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return XML with parsed object (no new request made)
|
38
|
+
def to_xml!
|
39
|
+
self.to_hash.to_xml({:root => 'whoisapi'})
|
40
|
+
end
|
41
|
+
|
42
|
+
# Execute the same request and return an XML response with a NEW request
|
43
|
+
def to_xml
|
44
|
+
request.clone.to_xml
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return JSON with parsed object (no new request made)
|
48
|
+
def to_json!
|
49
|
+
self.to_hash.to_json
|
50
|
+
end
|
51
|
+
|
52
|
+
# Execute the same request and return a JSON response with a NEW request
|
53
|
+
def to_json
|
54
|
+
request.clone.to_json
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_yaml
|
58
|
+
@parsed_object = parse unless @parsed_object
|
59
|
+
@parsed_object.to_yaml
|
60
|
+
end
|
61
|
+
|
62
|
+
def [](key)
|
63
|
+
@parsed_object = parse unless @parsed_object
|
64
|
+
return @parsed_object[key.to_s] if @parsed_object[key.to_s]
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def parse
|
71
|
+
return XMLParser::parse(request.content) if request.format == "xml"
|
72
|
+
return JSONParser::parse(request.content) if request.format == "json"
|
73
|
+
# If HTML, we will fallback and make a new json request, then parse it
|
74
|
+
return JSONParser::parse(self.to_json.content) if request.format == "html"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DomainTools
|
2
|
+
class XMLParser
|
3
|
+
|
4
|
+
def self.parse(source)
|
5
|
+
require 'rexml/document'
|
6
|
+
doc = REXML::Document.new(source)
|
7
|
+
root_node = doc.elements.first
|
8
|
+
data_node = root_node.elements.first
|
9
|
+
hash = self.parse_node({},data_node)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.parse_node(hash,node)
|
13
|
+
val = {}
|
14
|
+
if node.has_elements?
|
15
|
+
node.elements.each{|subnode| val = self.parse_node(val,subnode)}
|
16
|
+
else
|
17
|
+
val = node.text
|
18
|
+
end
|
19
|
+
if hash[node.name].kind_of?(Array)
|
20
|
+
hash[node.name] << val
|
21
|
+
elsif !hash[node.name].nil?
|
22
|
+
tmp = hash[node.name]
|
23
|
+
hash[node.name] = [tmp,val]
|
24
|
+
else
|
25
|
+
hash[node.name] = val
|
26
|
+
end
|
27
|
+
hash
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/domain_tools.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
DOMAIN_TOOLS_BASE_PATH = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
module DomainTools
|
4
|
+
|
5
|
+
# Defaut HOST for the request
|
6
|
+
HOST = "api.domaintools.com"
|
7
|
+
# Use Signed Authentication
|
8
|
+
SIGNED = true
|
9
|
+
# Digest method used for HMAC signature
|
10
|
+
DIGEST = "sha256"
|
11
|
+
# Default PORT for the request
|
12
|
+
PORT = "80"
|
13
|
+
# Default VERSION for the request
|
14
|
+
VERSION = "v1"
|
15
|
+
# Default FORMAT for the request
|
16
|
+
FORMAT = "json"
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/exceptions" # Exceptions classes declaration
|
21
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/json_parser" # JSON parser methods
|
22
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/xml_parser" # XML parser methods
|
23
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/error" # Error class
|
24
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/error_parser" # Response error parser (JSON/XML)
|
25
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/request" # Request class
|
26
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/response" # Response class
|
27
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/util" # Tools lib
|
28
|
+
require "#{DOMAIN_TOOLS_BASE_PATH}/domain_tools/core" # Core methods
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: domain_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- DomainTools, LLC
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-26 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Ruby wrapper of the domaintools.com API, allowing you to easily request any service available on domaintools.com
|
22
|
+
email: MemberServices@DomainTools.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- lib/domain_tools/core.rb
|
31
|
+
- lib/domain_tools/error.rb
|
32
|
+
- lib/domain_tools/error_parser.rb
|
33
|
+
- lib/domain_tools/exceptions.rb
|
34
|
+
- lib/domain_tools/json_parser.rb
|
35
|
+
- lib/domain_tools/request.rb
|
36
|
+
- lib/domain_tools/response.rb
|
37
|
+
- lib/domain_tools/util.rb
|
38
|
+
- lib/domain_tools/xml_parser.rb
|
39
|
+
- lib/domain_tools.rb
|
40
|
+
- examples/1_prepare.rb
|
41
|
+
- examples/2_response.rb
|
42
|
+
- examples/3_browsing.rb
|
43
|
+
- examples/4_error.rb
|
44
|
+
- examples/5_complete.rb
|
45
|
+
homepage: http://www.domaintools.com/api/
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 19
|
68
|
+
segments:
|
69
|
+
- 1
|
70
|
+
- 3
|
71
|
+
- 4
|
72
|
+
version: 1.3.4
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: domain_tools
|
76
|
+
rubygems_version: 1.8.11
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Ruby gem for requesting domaintools.com webservices
|
80
|
+
test_files: []
|
81
|
+
|