alexa 0.3.1 → 0.4.0
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/.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
|
+
[](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
|