alexa 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +70 -33
- data/lib/alexa/api/base.rb +20 -0
- data/lib/alexa/api/category_browse.rb +48 -45
- data/lib/alexa/api/category_listings.rb +60 -50
- data/lib/alexa/api/sites_linking_in.rb +41 -38
- data/lib/alexa/api/traffic_history.rb +60 -42
- data/lib/alexa/api/url_info.rb +81 -78
- data/lib/alexa/version.rb +1 -1
- data/test/api/category_browse_test.rb +14 -0
- data/test/api/category_listings_test.rb +18 -0
- data/test/api/sites_linking_in_test.rb +14 -0
- data/test/api/traffic_history_test.rb +38 -4
- data/test/api/url_info_test.rb +15 -1
- data/test/fixtures/traffic_history/{github_range_2.txt → alexa_error.txt} +1 -1
- data/test/fixtures/traffic_history/github.txt +325 -0
- metadata +7 -6
- data/test/fixtures/traffic_history/alexa_example.txt +0 -37
data/README.md
CHANGED
@@ -10,91 +10,128 @@ gem install alexa
|
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
+
All success response objects contain `response_id` method.
|
14
|
+
|
13
15
|
### Url Info
|
14
16
|
|
15
17
|
``` ruby
|
16
18
|
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
17
19
|
url_info = client.url_info(url: "site.com")
|
18
|
-
|
19
|
-
returns object with methods:
|
20
|
-
:rank, :data_url, :site_title, :site_description, :language_locale, :language_encoding,
|
21
|
-
:links_in_count, :keywords, :related_links, :speed_median_load_time, :speed_percentile,
|
22
|
-
:rank_by_country, :rank_by_city, :usage_statistics
|
23
20
|
```
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
Returns object that contains methods:
|
23
|
+
|
24
|
+
* rank
|
25
|
+
* data_url
|
26
|
+
* site_title
|
27
|
+
* site_description
|
28
|
+
* language_locale
|
29
|
+
* language_encoding
|
30
|
+
* links_in_count
|
31
|
+
* keywords
|
32
|
+
* related_links
|
33
|
+
* speed_median_load_time
|
34
|
+
* speed_percentile
|
35
|
+
* rank_by_country
|
36
|
+
* rank_by_city
|
37
|
+
* usage_statistics
|
38
|
+
|
39
|
+
You can specify options:
|
40
|
+
|
41
|
+
* url - address to be measured
|
42
|
+
* response_group - which data to include in response (i.e. ["rank", "contact_info"]) - defaults to all available
|
43
|
+
|
44
|
+
See: [Docs](http://docs.amazonwebservices.com/AlexaWebInfoService/latest/) for valid groups.
|
28
45
|
|
29
46
|
### Sites Linking In
|
30
47
|
|
31
48
|
``` ruby
|
32
49
|
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
33
50
|
sites_linking_in = client.sites_linking_in(url: "site.com")
|
34
|
-
|
35
|
-
# returns object with `sites` method
|
36
51
|
```
|
37
52
|
|
38
|
-
|
53
|
+
Returns object that contains method:
|
54
|
+
|
55
|
+
* sites
|
56
|
+
|
57
|
+
You can specify options:
|
39
58
|
|
40
|
-
*
|
41
|
-
*
|
59
|
+
* url - address to be measured
|
60
|
+
* count - how many results to retrieve - defaults to max value that is 20
|
61
|
+
* start - offset of results - defaults to 0
|
42
62
|
|
43
63
|
### Traffic History
|
44
64
|
|
45
65
|
``` ruby
|
46
66
|
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
47
67
|
traffic_history = client.traffic_history(url: "site.com")
|
48
|
-
|
49
|
-
# returns object with `data` method
|
50
68
|
```
|
51
69
|
|
52
|
-
|
70
|
+
Returns object that contains method:
|
71
|
+
|
72
|
+
* site
|
73
|
+
* range
|
74
|
+
* start
|
75
|
+
* data
|
53
76
|
|
54
|
-
|
55
|
-
|
77
|
+
You can specify options:
|
78
|
+
|
79
|
+
* url - address to be measured
|
80
|
+
* range - how many days to retrieve - defaults to max value 31
|
81
|
+
* start - start date (i.e. "20120120", 4.days.ago) - defaults to range number days ago
|
56
82
|
|
57
83
|
### Category Browse
|
58
84
|
|
59
85
|
``` ruby
|
60
86
|
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
61
87
|
category_browse = client.category_browse(path: "Top/Games/Card_Games")
|
62
|
-
|
63
|
-
# returns object with `categories`, `language_categories`, `related_categories`, `letter_bars` methods.
|
64
88
|
```
|
65
89
|
|
66
|
-
|
90
|
+
Returns object that contains methods:
|
67
91
|
|
68
|
-
|
92
|
+
* categories
|
93
|
+
* language_categories
|
94
|
+
* related_categories
|
95
|
+
* letter_bars
|
69
96
|
|
70
97
|
You can specify options:
|
71
98
|
|
72
|
-
*
|
73
|
-
*
|
99
|
+
* path - category to be measured (i.e. "Top/Games/Card_Games") - valid paths can be found on [dmoz](http://www.dmoz.org/)
|
100
|
+
* response_group - any of: categories, related_categories, language_categories, letter_bars - defaults to all
|
101
|
+
* descriptions - should response include descriptions (i.e. false) - defaults to true
|
74
102
|
|
75
103
|
### Category Listings
|
76
104
|
|
77
105
|
``` ruby
|
78
106
|
client = Alexa::Client.new(access_key_id: "key", secret_access_key: "secret")
|
79
107
|
category_listings = client.category_listings(path: "Top/Games/Card_Games")
|
80
|
-
|
81
|
-
# returns object with `recursive_count`, `listings` methods.
|
82
108
|
```
|
83
109
|
|
84
|
-
|
110
|
+
Returns object that contains methods:
|
85
111
|
|
86
|
-
|
112
|
+
* count
|
113
|
+
* recursive_count
|
114
|
+
* listings
|
87
115
|
|
88
116
|
You can specify options:
|
89
117
|
|
90
|
-
*
|
91
|
-
*
|
92
|
-
*
|
93
|
-
*
|
94
|
-
*
|
118
|
+
* path - category to be measured (i.e. "Top/Games/Card_Games") - valid paths can be found on [dmoz](http://www.dmoz.org/)
|
119
|
+
* sort_by - sort results by one of: popularity, title, average_review - defaults to popularity
|
120
|
+
* recursive - should result include subcategories (i.e. false)- defaults to true
|
121
|
+
* count - how many results to retrieve - defaults to max value, that is 20
|
122
|
+
* start - offset of results - defaults to 0
|
123
|
+
* descriptions - should response include descriptions (i.e. false) - defaults to true
|
95
124
|
|
96
125
|
## Caveats
|
97
126
|
|
127
|
+
### Status Code
|
128
|
+
|
129
|
+
You can retrieve Alexa status code calling `status_code` method.
|
130
|
+
|
131
|
+
It happens (so far in TrafficHistory) that Alexa returns response `200` with `AlexaError` status.
|
132
|
+
|
133
|
+
### Parsers
|
134
|
+
|
98
135
|
Alexa is using `multi_xml` to parse XML documents. Tested with:
|
99
136
|
|
100
137
|
* rexml
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Alexa
|
2
|
+
module API
|
3
|
+
class Base
|
4
|
+
include Utils
|
5
|
+
|
6
|
+
attr_reader :arguments, :response_body
|
7
|
+
|
8
|
+
def initialize(credentials)
|
9
|
+
if MultiXml.parser.to_s == "MultiXml::Parsers::Ox"
|
10
|
+
raise StandardError, "MultiXml parser is set to :ox - alexa gem will not work with it currently, use one of: :libxml, :nokogiri, :rexml"
|
11
|
+
end
|
12
|
+
@credentials = credentials
|
13
|
+
end
|
14
|
+
|
15
|
+
def parsed_body
|
16
|
+
@parsed_body ||= MultiXml.parse(response_body)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,62 +1,65 @@
|
|
1
|
-
|
2
|
-
class CategoryBrowse
|
3
|
-
include Alexa::Utils
|
1
|
+
require "alexa/api/base"
|
4
2
|
|
5
|
-
|
3
|
+
module Alexa
|
4
|
+
module API
|
5
|
+
class CategoryBrowse < Base
|
6
|
+
DEFAULT_RESPONSE_GROUP = ["categories", "related_categories", "language_categories", "letter_bars"]
|
6
7
|
|
7
|
-
|
8
|
+
def fetch(arguments = {})
|
9
|
+
raise ArgumentError.new("You must specify path") unless arguments.has_key?(:path)
|
10
|
+
@arguments = arguments
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
+
@arguments[:response_group] = Array(arguments.fetch(:response_group, DEFAULT_RESPONSE_GROUP))
|
13
|
+
@arguments[:descriptions] = arguments.fetch(:descriptions, true)
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@descriptions = arguments.fetch(:descriptions, true)
|
17
|
-
@response_body = Alexa::Connection.new(@credentials).get(params)
|
18
|
-
self
|
19
|
-
end
|
15
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
16
|
+
self
|
17
|
+
end
|
20
18
|
|
21
|
-
|
19
|
+
# Response attributes
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
def categories
|
22
|
+
@categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "Categories", "Category")
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def language_categories
|
26
|
+
@language_categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "LanguageCategories", "Category")
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def related_categories
|
30
|
+
@related_categories ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "RelatedCategories", "Category")
|
31
|
+
end
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
def letter_bars
|
34
|
+
@letter_bars ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "CategoryBrowseResult", "Alexa", "CategoryBrowse", "LetterBars", "Category")
|
35
|
+
end
|
38
36
|
|
39
|
-
|
37
|
+
def status_code
|
38
|
+
@status_code ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "ResponseStatus", "StatusCode")
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
"ResponseGroup" => response_group_param,
|
45
|
-
"Path" => path,
|
46
|
-
"Descriptions" => descriptions_param
|
47
|
-
}
|
48
|
-
end
|
41
|
+
def request_id
|
42
|
+
@request_id ||= safe_retrieve(parsed_body, "CategoryBrowseResponse", "Response", "OperationRequest", "RequestId")
|
43
|
+
end
|
49
44
|
|
50
|
-
|
51
|
-
response_group.sort.map { |group| camelize(group) }.join(",")
|
52
|
-
end
|
45
|
+
private
|
53
46
|
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
def params
|
48
|
+
{
|
49
|
+
"Action" => "CategoryBrowse",
|
50
|
+
"ResponseGroup" => response_group_param,
|
51
|
+
"Path" => arguments[:path],
|
52
|
+
"Descriptions" => descriptions_param
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def response_group_param
|
57
|
+
arguments[:response_group].sort.map { |group| camelize(group) }.join(",")
|
58
|
+
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
+
def descriptions_param
|
61
|
+
arguments[:descriptions].to_s.capitalize
|
62
|
+
end
|
60
63
|
end
|
61
64
|
end
|
62
65
|
end
|
@@ -1,66 +1,76 @@
|
|
1
|
-
|
2
|
-
class CategoryListings
|
3
|
-
include Alexa::Utils
|
1
|
+
require "alexa/api/base"
|
4
2
|
|
5
|
-
|
3
|
+
module Alexa
|
4
|
+
module API
|
5
|
+
class CategoryListings < Base
|
6
|
+
def fetch(arguments = {})
|
7
|
+
raise ArgumentError, "You must specify path" unless arguments.has_key?(:path)
|
8
|
+
@arguments = arguments
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
@arguments[:sort_by] = arguments.fetch(:sort_by, "popularity")
|
11
|
+
@arguments[:recursive] = arguments.fetch(:recursive, true)
|
12
|
+
@arguments[:descriptions] = arguments.fetch(:descriptions, true)
|
13
|
+
@arguments[:start] = arguments.fetch(:start, 0)
|
14
|
+
@arguments[:count] = arguments.fetch(:count, 20)
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
16
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
17
|
+
self
|
18
|
+
end
|
21
19
|
|
22
|
-
|
20
|
+
# Response attributes
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def count
|
23
|
+
return @count if defined?(@count)
|
24
|
+
if count = safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "CategoryListingsResult", "Alexa", "CategoryListings", "Count")
|
25
|
+
@count = count.to_i
|
26
|
+
end
|
28
27
|
end
|
29
|
-
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def recursive_count
|
30
|
+
return @recursive_count if defined?(@recursive_count)
|
31
|
+
if recursive_count = safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "CategoryListingsResult", "Alexa", "CategoryListings", "RecursiveCount")
|
32
|
+
@recursive_count = recursive_count.to_i
|
33
|
+
end
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
+
def listings
|
37
|
+
@listings ||= safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "CategoryListingsResult", "Alexa", "CategoryListings", "Listings", "Listing")
|
38
|
+
end
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
40
|
+
def status_code
|
41
|
+
@status_code ||= safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "ResponseStatus", "StatusCode")
|
42
|
+
end
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
44
|
+
def request_id
|
45
|
+
@request_id ||= safe_retrieve(parsed_body, "CategoryListingsResponse", "Response", "OperationRequest", "RequestId")
|
46
|
+
end
|
53
47
|
|
54
|
-
|
55
|
-
descriptions.to_s.capitalize
|
56
|
-
end
|
48
|
+
private
|
57
49
|
|
58
|
-
|
59
|
-
|
60
|
-
|
50
|
+
def params
|
51
|
+
{
|
52
|
+
"Action" => "CategoryListings",
|
53
|
+
"ResponseGroup" => "Listings",
|
54
|
+
"Path" => arguments[:path],
|
55
|
+
"Recursive" => recursive_param,
|
56
|
+
"Descriptions" => descriptions_param,
|
57
|
+
"SortBy" => sort_by_param,
|
58
|
+
"Count" => arguments[:count],
|
59
|
+
"Start" => arguments[:start],
|
60
|
+
}
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
def recursive_param
|
64
|
+
arguments[:recursive].to_s.capitalize
|
65
|
+
end
|
66
|
+
|
67
|
+
def descriptions_param
|
68
|
+
arguments[:descriptions].to_s.capitalize
|
69
|
+
end
|
70
|
+
|
71
|
+
def sort_by_param
|
72
|
+
camelize(arguments[:sort_by])
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|
@@ -1,41 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
1
|
+
require "alexa/api/base"
|
2
|
+
|
3
|
+
module Alexa
|
4
|
+
module API
|
5
|
+
class SitesLinkingIn < Base
|
6
|
+
def fetch(arguments = {})
|
7
|
+
raise ArgumentError, "You must specify url" unless arguments.has_key?(:url)
|
8
|
+
@arguments = arguments
|
9
|
+
|
10
|
+
@arguments[:count] = arguments.fetch(:count, 20)
|
11
|
+
@arguments[:start] = arguments.fetch(:start, 0)
|
12
|
+
|
13
|
+
@response_body = Alexa::Connection.new(@credentials).get(params)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Response attributes
|
18
|
+
|
19
|
+
def sites
|
20
|
+
@sites ||= safe_retrieve(parsed_body, "SitesLinkingInResponse", "Response", "SitesLinkingInResult", "Alexa", "SitesLinkingIn", "Site")
|
21
|
+
end
|
22
|
+
|
23
|
+
def status_code
|
24
|
+
@status_code ||= safe_retrieve(parsed_body, "SitesLinkingInResponse", "Response", "ResponseStatus", "StatusCode")
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_id
|
28
|
+
@request_id ||= safe_retrieve(parsed_body, "SitesLinkingInResponse", "Response", "OperationRequest", "RequestId")
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def params
|
34
|
+
{
|
35
|
+
"Action" => "SitesLinkingIn",
|
36
|
+
"ResponseGroup" => "SitesLinkingIn",
|
37
|
+
"Count" => arguments[:count],
|
38
|
+
"Start" => arguments[:start],
|
39
|
+
"Url" => arguments[:url]
|
40
|
+
}
|
41
|
+
end
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|