alexa 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -5
- data/Gemfile +1 -0
- data/README.md +76 -21
- data/alexa.gemspec +1 -9
- data/lib/alexa.rb +11 -22
- data/lib/alexa/api/category_browse.rb +62 -0
- data/lib/alexa/api/category_listings.rb +66 -0
- data/lib/alexa/api/sites_linking_in.rb +41 -0
- data/lib/alexa/api/traffic_history.rb +45 -0
- data/lib/alexa/api/url_info.rb +108 -0
- data/lib/alexa/client.rb +30 -0
- data/lib/alexa/connection.rb +86 -0
- data/lib/alexa/exceptions.rb +17 -0
- data/lib/alexa/utils.rb +19 -0
- data/lib/alexa/version.rb +1 -1
- data/test/api/category_browse_test.rb +27 -0
- data/test/api/category_listings_test.rb +19 -0
- data/test/api/sites_linking_in_test.rb +23 -0
- data/test/api/traffic_history_test.rb +24 -0
- data/test/api/url_info_test.rb +112 -0
- data/test/client_test.rb +65 -0
- data/test/connection_test.rb +37 -0
- data/test/fixtures/bad_request.txt +8 -0
- data/test/fixtures/category_browse/card_games.txt +480 -0
- data/test/fixtures/category_listings/card_games.txt +138 -0
- data/test/fixtures/sites_linking_in/github_count_3.txt +24 -0
- data/test/fixtures/traffic_history/alexa_example.txt +37 -0
- data/test/fixtures/traffic_history/github_range_2.txt +8 -0
- data/test/fixtures/{custom-response-group.txt → url_info/custom-response-group.txt} +0 -0
- data/test/fixtures/{empty_group.txt → url_info/empty_group.txt} +0 -0
- data/test/fixtures/{github_full.txt → url_info/github_full.txt} +0 -0
- data/test/fixtures/{github_rank.txt → url_info/github_rank.txt} +0 -0
- data/test/helper.rb +6 -8
- data/test/utils_test.rb +54 -0
- metadata +33 -23
- data/lib/alexa/url_info.rb +0 -109
- data/test/config_test.rb +0 -35
- data/test/url_info_test.rb +0 -152
data/.travis.yml
CHANGED
@@ -2,11 +2,10 @@ notifications:
|
|
2
2
|
disabled: true
|
3
3
|
rvm:
|
4
4
|
- ree
|
5
|
-
- 1.9.2
|
6
5
|
- 1.9.3
|
7
6
|
env:
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
7
|
+
- XML_PARSER=rexml
|
8
|
+
- XML_PARSER=nokogiri
|
9
|
+
- XML_PARSER=libxml
|
11
10
|
# does not work yet
|
12
|
-
# -
|
11
|
+
# - XML_PARSER=ox
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,52 +10,107 @@ gem install alexa
|
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
+
### Url Info
|
14
|
+
|
13
15
|
``` ruby
|
14
|
-
Alexa.
|
16
|
+
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
17
|
+
url_info = client.url_info(url: "site.com")
|
15
18
|
|
16
19
|
returns object with methods:
|
17
|
-
:
|
20
|
+
:rank, :data_url, :site_title, :site_description, :language_locale, :language_encoding,
|
18
21
|
:links_in_count, :keywords, :related_links, :speed_median_load_time, :speed_percentile,
|
19
22
|
:rank_by_country, :rank_by_city, :usage_statistics
|
20
23
|
```
|
21
24
|
|
22
|
-
NOTE: You can specify option
|
25
|
+
NOTE: You can specify option `response_group: ["rank", "contact_info"]` or any other valid group.
|
23
26
|
See: [Docs](http://docs.amazonwebservices.com/AlexaWebInfoService/latest/)
|
24
27
|
Default response group takes all the available options.
|
25
28
|
|
26
|
-
|
29
|
+
### Sites Linking In
|
27
30
|
|
28
31
|
``` ruby
|
29
|
-
Alexa.
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
33
|
+
sites_linking_in = client.sites_linking_in(url: "site.com")
|
34
|
+
|
35
|
+
# returns object with `sites` method
|
33
36
|
```
|
34
37
|
|
35
|
-
|
38
|
+
NOTE: You can specify options:
|
36
39
|
|
37
|
-
*
|
38
|
-
*
|
39
|
-
|
40
|
+
* count (how many results to retrieve - default to max value 20)
|
41
|
+
* start (offset of results - default to 0)
|
42
|
+
|
43
|
+
### Traffic History
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
47
|
+
traffic_history = client.traffic_history(url: "site.com")
|
48
|
+
|
49
|
+
# returns object with `data` method
|
50
|
+
```
|
51
|
+
|
52
|
+
NOTE: You can specify options:
|
53
|
+
|
54
|
+
* range (how many days to retrieve - default to max value 31)
|
55
|
+
* start (start date - default to range days ago)
|
56
|
+
|
57
|
+
### Category Browse
|
58
|
+
|
59
|
+
``` ruby
|
60
|
+
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
61
|
+
category_browse = client.category_browse(path: "Top/Games/Card_Games")
|
62
|
+
|
63
|
+
# returns object with `categories`, `language_categories`, `related_categories`, `letter_bars` methods.
|
64
|
+
```
|
40
65
|
|
41
|
-
|
66
|
+
NOTE:
|
42
67
|
|
43
|
-
|
68
|
+
You can find valid paths on [dmoz](http://www.dmoz.org/) site
|
44
69
|
|
45
|
-
|
70
|
+
You can specify options:
|
46
71
|
|
47
|
-
*
|
48
|
-
*
|
49
|
-
|
50
|
-
|
72
|
+
* response_group (any of: categories, related_categories, language_categories, letter_bars)
|
73
|
+
* descriptions (include descriptions - boolean, true by default)
|
74
|
+
|
75
|
+
### Category Listings
|
76
|
+
|
77
|
+
``` ruby
|
78
|
+
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
79
|
+
category_listings = client.category_listings(path: "Top/Games/Card_Games")
|
80
|
+
|
81
|
+
# returns object with `recursive_count`, `listings` methods.
|
82
|
+
```
|
83
|
+
|
84
|
+
NOTE:
|
85
|
+
|
86
|
+
You can find valid paths on [dmoz](http://www.dmoz.org/) site
|
87
|
+
|
88
|
+
You can specify options:
|
89
|
+
|
90
|
+
* sort_by (sort results by one of: popularity, title, average_review)
|
91
|
+
* recursive (results for the given category only, or including subcategories - boolean, true by default)
|
92
|
+
* count (how many results to retrieve - default to max value 20)
|
93
|
+
* start (offset of results - default to 0)
|
94
|
+
* descriptions (include descriptions - boolean, true by default)
|
95
|
+
|
96
|
+
## Caveats
|
97
|
+
|
98
|
+
Alexa is using `multi_xml` to parse XML documents. Tested with:
|
99
|
+
|
100
|
+
* rexml
|
101
|
+
* nokogiri
|
102
|
+
* libxml
|
103
|
+
|
104
|
+
Currently alexa will not work with `ox` gem
|
51
105
|
|
52
106
|
## Contributors
|
53
107
|
|
54
108
|
* [rmoriz](https://github.com/rmoriz)
|
55
109
|
|
56
110
|
## Continuous Integration
|
57
|
-
|
111
|
+
|
112
|
+
[![Build Status](https://secure.travis-ci.org/morgoth/alexa.png?branch=master)](http://travis-ci.org/morgoth/alexa)
|
58
113
|
|
59
114
|
## Copyright
|
60
115
|
|
61
|
-
Copyright (c)
|
116
|
+
Copyright (c) Wojciech Wnętrzak. See LICENSE for details.
|
data/alexa.gemspec
CHANGED
@@ -18,13 +18,5 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.add_dependency "multi_xml", ">= 0.5.0"
|
19
19
|
|
20
20
|
gem.add_development_dependency "mocha"
|
21
|
-
gem.add_development_dependency "
|
22
|
-
|
23
|
-
gem.post_install_message = %{
|
24
|
-
|
25
|
-
Gem syntax of 0.4 version of this gem will change with backward incompatibilities.
|
26
|
-
If you don't want to update your code, please specify in your Gemfile:
|
27
|
-
gem "alexa", "~> 0.3.0"
|
28
|
-
|
29
|
-
}
|
21
|
+
gem.add_development_dependency "webmock"
|
30
22
|
end
|
data/lib/alexa.rb
CHANGED
@@ -1,28 +1,17 @@
|
|
1
|
-
require "cgi"
|
2
|
-
require "base64"
|
3
|
-
require "openssl"
|
4
|
-
require "digest/sha1"
|
5
|
-
require "net/https"
|
6
|
-
require "time"
|
7
|
-
|
8
1
|
require "multi_xml"
|
9
2
|
|
10
3
|
require "alexa/version"
|
11
|
-
require "alexa/
|
4
|
+
require "alexa/utils"
|
5
|
+
require "alexa/exceptions"
|
6
|
+
require "alexa/connection"
|
7
|
+
require "alexa/client"
|
8
|
+
require "alexa/api/category_browse"
|
9
|
+
require "alexa/api/category_listings"
|
10
|
+
require "alexa/api/sites_linking_in"
|
11
|
+
require "alexa/api/traffic_history"
|
12
|
+
require "alexa/api/url_info"
|
12
13
|
|
13
14
|
module Alexa
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def configure
|
18
|
-
yield self
|
19
|
-
end
|
20
|
-
|
21
|
-
def url_info(options = {})
|
22
|
-
url_info = Alexa::UrlInfo.new(options)
|
23
|
-
xml = url_info.connect
|
24
|
-
url_info.parse_xml(xml)
|
25
|
-
url_info
|
26
|
-
end
|
27
|
-
end
|
15
|
+
API_VERSION = "2005-07-11"
|
16
|
+
API_HOST = "awis.amazonaws.com"
|
28
17
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Alexa::API
|
2
|
+
class CategoryBrowse
|
3
|
+
include Alexa::Utils
|
4
|
+
|
5
|
+
DEFAULT_RESPONSE_GROUP = ["categories", "related_categories", "language_categories", "letter_bars"]
|
6
|
+
|
7
|
+
attr_reader :response_group, :path, :descriptions, :response_body
|
8
|
+
|
9
|
+
def initialize(credentials)
|
10
|
+
@credentials = credentials
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch(arguments = {})
|
14
|
+
@path = arguments[:path] || raise(ArgumentError.new("You must specify path"))
|
15
|
+
@response_group = Array(arguments.fetch(:response_group, DEFAULT_RESPONSE_GROUP))
|
16
|
+
@descriptions = arguments.fetch(:descriptions, true)
|
17
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Attributes
|
22
|
+
|
23
|
+
def categories
|
24
|
+
@categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "Categories", "Category")
|
25
|
+
end
|
26
|
+
|
27
|
+
def language_categories
|
28
|
+
@language_categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "LanguageCategories", "Category")
|
29
|
+
end
|
30
|
+
|
31
|
+
def related_categories
|
32
|
+
@related_categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "RelatedCategories", "Category")
|
33
|
+
end
|
34
|
+
|
35
|
+
def letter_bars
|
36
|
+
@letter_bars ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "LetterBars", "Category")
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def params
|
42
|
+
{
|
43
|
+
"Action" => "CategoryBrowse",
|
44
|
+
"ResponseGroup" => response_group_param,
|
45
|
+
"Path" => path,
|
46
|
+
"Descriptions" => descriptions_param
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def response_group_param
|
51
|
+
response_group.sort.map { |group| camelize(group) }.join(",")
|
52
|
+
end
|
53
|
+
|
54
|
+
def descriptions_param
|
55
|
+
descriptions.to_s.capitalize
|
56
|
+
end
|
57
|
+
|
58
|
+
def parsed_body
|
59
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Alexa::API
|
2
|
+
class CategoryListings
|
3
|
+
include Alexa::Utils
|
4
|
+
|
5
|
+
attr_reader :path, :sort_by, :recursive, :start, :count, :descriptions, :response_body
|
6
|
+
|
7
|
+
def initialize(credentials)
|
8
|
+
@credentials = credentials
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(arguments = {})
|
12
|
+
@path = arguments[:path] || raise(ArgumentError.new("You must specify path"))
|
13
|
+
@sort_by = arguments.fetch(:sort_by, "popularity")
|
14
|
+
@recursive = arguments.fetch(:recursive, true)
|
15
|
+
@start = arguments.fetch(:start, 0)
|
16
|
+
@count = arguments.fetch(:count, 20)
|
17
|
+
@descriptions = arguments.fetch(:descriptions, true)
|
18
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
# Attributes
|
23
|
+
|
24
|
+
def recursive_count
|
25
|
+
return @recursive_count if defined?(@recursive_count)
|
26
|
+
if recursive_count = safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "CategoryListingsResult", "Alexa", "CategoryListings", "RecursiveCount")
|
27
|
+
@recursive_count = recursive_count.to_i
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def listings
|
32
|
+
@listings ||= safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "CategoryListingsResult", "Alexa", "CategoryListings", "Listings", "Listing")
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def params
|
38
|
+
{
|
39
|
+
"Action" => "CategoryListings",
|
40
|
+
"ResponseGroup" => "Listings",
|
41
|
+
"Path" => path,
|
42
|
+
"Recursive" => recursive_param,
|
43
|
+
"Descriptions" => descriptions_param,
|
44
|
+
"SortBy" => sort_by_param,
|
45
|
+
"Count" => count,
|
46
|
+
"Start" => start,
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def recursive_param
|
51
|
+
recursive.to_s.capitalize
|
52
|
+
end
|
53
|
+
|
54
|
+
def descriptions_param
|
55
|
+
descriptions.to_s.capitalize
|
56
|
+
end
|
57
|
+
|
58
|
+
def sort_by_param
|
59
|
+
camelize(sort_by)
|
60
|
+
end
|
61
|
+
|
62
|
+
def parsed_body
|
63
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Alexa::API
|
2
|
+
class SitesLinkingIn
|
3
|
+
include Alexa::Utils
|
4
|
+
|
5
|
+
attr_reader :url, :count, :start, :response_body
|
6
|
+
|
7
|
+
def initialize(credentials)
|
8
|
+
@credentials = credentials
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(arguments = {})
|
12
|
+
@url = arguments[:url] || raise(ArgumentError.new("You must specify url"))
|
13
|
+
@count = arguments.fetch(:count, 20)
|
14
|
+
@start = arguments.fetch(:start, 0)
|
15
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Attributes
|
20
|
+
|
21
|
+
def sites
|
22
|
+
@sites ||= safe_retrieve(parsed_body, "SitesLinkingInResponse", "Response", "SitesLinkingInResult", "Alexa", "SitesLinkingIn", "Site")
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def params
|
28
|
+
{
|
29
|
+
"Action" => "SitesLinkingIn",
|
30
|
+
"ResponseGroup" => "SitesLinkingIn",
|
31
|
+
"Count" => count,
|
32
|
+
"Start" => start,
|
33
|
+
"Url" => url
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def parsed_body
|
38
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Alexa::API
|
2
|
+
class TrafficHistory
|
3
|
+
include Alexa::Utils
|
4
|
+
|
5
|
+
attr_reader :url, :range, :start, :response_body
|
6
|
+
|
7
|
+
def initialize(credentials)
|
8
|
+
@credentials = credentials
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(arguments = {})
|
12
|
+
@url = arguments[:url] || raise(ArgumentError.new("You must specify url"))
|
13
|
+
@range = arguments.fetch(:range, 31)
|
14
|
+
@start = arguments.fetch(:start) { Time.now - (3600 * 24 * range.to_i) }
|
15
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Attributes
|
20
|
+
|
21
|
+
def data
|
22
|
+
@data ||= safe_retrieve(parsed_body, "TrafficHistoryResponse", "Response", "TrafficHistoryResult", "Alexa", "TrafficHistory", "HistoricalData", "Data")
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def params
|
28
|
+
{
|
29
|
+
"Action" => "TrafficHistory",
|
30
|
+
"ResponseGroup" => "History",
|
31
|
+
"Range" => range,
|
32
|
+
"Start" => start_param,
|
33
|
+
"Url" => url
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_param
|
38
|
+
start.respond_to?(:strftime) ? start.strftime("%Y%m%d") : start
|
39
|
+
end
|
40
|
+
|
41
|
+
def parsed_body
|
42
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Alexa::API
|
2
|
+
class UrlInfo
|
3
|
+
include Alexa::Utils
|
4
|
+
|
5
|
+
DEFAULT_RESPONSE_GROUP = ["adult_content", "contact_info", "keywords", "language", "links_in_count", "owned_domains", "rank", "rank_by_city", "rank_by_country", "related_links", "site_data", "speed", "usage_stats"]
|
6
|
+
|
7
|
+
attr_reader :url, :response_group, :response_body
|
8
|
+
|
9
|
+
def initialize(credentials)
|
10
|
+
@credentials = credentials
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch(arguments = {})
|
14
|
+
@url = arguments[:url] || raise(ArgumentError.new("You must specify url"))
|
15
|
+
@response_group = Array(arguments.fetch(:response_group, DEFAULT_RESPONSE_GROUP))
|
16
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# attributes
|
21
|
+
|
22
|
+
def rank
|
23
|
+
return @rank if defined?(@rank)
|
24
|
+
if rank = safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "TrafficData", "Rank")
|
25
|
+
@rank = rank.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def rank_by_country
|
30
|
+
@rank_by_country ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "TrafficData", "RankByCountry", "Country")
|
31
|
+
end
|
32
|
+
|
33
|
+
def rank_by_city
|
34
|
+
@rank_by_city ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "TrafficData", "RankByCity", "City")
|
35
|
+
end
|
36
|
+
|
37
|
+
def data_url
|
38
|
+
@data_url ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "TrafficData", "DataUrl", "__content__")
|
39
|
+
end
|
40
|
+
|
41
|
+
def usage_statistics
|
42
|
+
@usage_statistics ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "TrafficData", "UsageStatistics", "UsageStatistic")
|
43
|
+
end
|
44
|
+
|
45
|
+
def site_title
|
46
|
+
@site_title ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "SiteData", "Title")
|
47
|
+
end
|
48
|
+
|
49
|
+
def site_description
|
50
|
+
@site_description ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "SiteData", "Description")
|
51
|
+
end
|
52
|
+
|
53
|
+
def language_locale
|
54
|
+
@language_locale ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "Language", "Locale")
|
55
|
+
end
|
56
|
+
|
57
|
+
def language_encoding
|
58
|
+
@language_encoding ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "Language", "Encoding")
|
59
|
+
end
|
60
|
+
|
61
|
+
def links_in_count
|
62
|
+
return @links_in_count if defined?(@links_in_count)
|
63
|
+
if links_in_count = safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "LinksInCount")
|
64
|
+
@links_in_count = links_in_count.to_i
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def keywords
|
69
|
+
@keywords ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "Keywords", "Keyword")
|
70
|
+
end
|
71
|
+
|
72
|
+
def speed_median_load_time
|
73
|
+
return @speed_median_load_time if defined?(@speed_median_load_time)
|
74
|
+
if speed_median_load_time = safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "Speed", "MedianLoadTime")
|
75
|
+
@speed_median_load_time = speed_median_load_time.to_i
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def speed_percentile
|
80
|
+
return @speed_percentile if defined?(@speed_percentile)
|
81
|
+
if speed_percentile = safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "ContentData", "Speed", "Percentile")
|
82
|
+
@speed_percentile = speed_percentile.to_i
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def related_links
|
87
|
+
@related_links ||= safe_retrieve(parsed_body, "UrlInfoResponse", "Response", "UrlInfoResult", "Alexa", "Related", "RelatedLinks", "RelatedLink")
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def params
|
93
|
+
{
|
94
|
+
"Action" => "UrlInfo",
|
95
|
+
"ResponseGroup" => response_group_param,
|
96
|
+
"Url" => url
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def response_group_param
|
101
|
+
response_group.sort.map { |group| camelize(group) }.join(",")
|
102
|
+
end
|
103
|
+
|
104
|
+
def parsed_body
|
105
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|