alexa 0.4.0 → 0.4.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/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
|