domain_tools 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|