ralexa 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +6 -5
- data/lib/ralexa/abstract_service.rb +41 -0
- data/lib/ralexa/client.rb +0 -2
- data/lib/ralexa/lazy_collection.rb +35 -0
- data/lib/ralexa/paginating_collection.rb +36 -0
- data/lib/ralexa/paginator.rb +57 -0
- data/lib/ralexa/session.rb +0 -3
- data/lib/ralexa/top_sites.rb +40 -32
- data/lib/ralexa/uri_signer.rb +0 -2
- data/lib/ralexa/version.rb +1 -1
- data/lib/ralexa.rb +4 -1
- data/spec/canonicalized_query_string_spec.rb +0 -2
- data/spec/client_spec.rb +0 -2
- data/spec/fixtures/global-page1.xml +1613 -0
- data/spec/fixtures/global-page2.xml +813 -0
- data/spec/fixtures/global-top10.xml +173 -0
- data/spec/paginator_spec.rb +55 -0
- data/spec/ralexa_spec.rb +0 -2
- data/spec/session_spec.rb +0 -2
- data/spec/spec_helper.rb +2 -0
- data/spec/top_sites_spec.rb +57 -32
- data/spec/uri_signer_spec.rb +0 -1
- metadata +21 -12
- data/lib/ralexa/abstract_xml_service.rb +0 -27
- data/spec/fixtures/global.xml +0 -45
data/README.md
CHANGED
@@ -41,19 +41,20 @@ session = Ralexa.session("aws_access_key_id", "aws_secret_access_key")
|
|
41
41
|
|
42
42
|
# all countries
|
43
43
|
countries = session.top_sites.list_countries
|
44
|
+
p countries.map(&:name)
|
44
45
|
|
45
|
-
# global top sites
|
46
|
-
global = session.top_sites.global
|
46
|
+
# global top 250 sites
|
47
|
+
global = session.top_sites.global(250)
|
47
48
|
|
48
49
|
# per-country top sites
|
49
50
|
first_by_country = {}
|
50
51
|
countries.each do |c|
|
51
|
-
first_by_country[c.name] = session.top_sites.country(c.code).first.url
|
52
|
+
first_by_country[c.name] = session.top_sites.country(c.code, 1).first.url
|
52
53
|
end
|
53
54
|
|
54
55
|
# individual country lookup
|
55
|
-
puts "Top Australian Sites"
|
56
|
-
session.top_sites.country("AU").each do |s|
|
56
|
+
puts "Top Ten Australian Sites"
|
57
|
+
session.top_sites.country("AU", 10).each do |s|
|
57
58
|
puts "#{s.url} (#{s.page_views} pageviews)"
|
58
59
|
end
|
59
60
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ralexa
|
2
|
+
class AbstractService
|
3
|
+
|
4
|
+
def initialize(client)
|
5
|
+
@client = client
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# A lazy collection which fetches records on demand.
|
11
|
+
def collection(*params, &parser)
|
12
|
+
LazyCollection.new(
|
13
|
+
@client,
|
14
|
+
host,
|
15
|
+
path,
|
16
|
+
merged_params(*params),
|
17
|
+
&parser
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def paginating_collection(limit, per_page, *params, &parser)
|
22
|
+
PaginatingCollection.new(
|
23
|
+
@client,
|
24
|
+
host,
|
25
|
+
path,
|
26
|
+
merged_params(*params),
|
27
|
+
limit,
|
28
|
+
per_page,
|
29
|
+
&parser
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
# A hash of the provided params hashes merged into the default_params.
|
34
|
+
def merged_params(*params)
|
35
|
+
params.reduce(default_params) do |merged, params|
|
36
|
+
merged.merge(params)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/ralexa/client.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module Ralexa
|
4
|
+
class LazyCollection
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(client, host, path, parameters, &parser)
|
9
|
+
@client = client
|
10
|
+
@host = host
|
11
|
+
@path = path
|
12
|
+
@parameters = parameters
|
13
|
+
@parser = parser
|
14
|
+
end
|
15
|
+
|
16
|
+
def each
|
17
|
+
parse(fetch(@parameters)).each do |item|
|
18
|
+
yield item
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def fetch(parameters)
|
25
|
+
@client.get(@host, @path, parameters)
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse(response_body)
|
29
|
+
@parser.call(
|
30
|
+
Nokogiri::XML.parse(response_body).remove_namespaces!
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Ralexa
|
2
|
+
class PaginatingCollection < LazyCollection
|
3
|
+
|
4
|
+
def initialize(client, host, path, parameters, limit, per_page, &parser)
|
5
|
+
validate_parameters(parameters)
|
6
|
+
super(client, host, path, parameters, &parser)
|
7
|
+
@limit = limit
|
8
|
+
@per_page = per_page
|
9
|
+
end
|
10
|
+
|
11
|
+
def each
|
12
|
+
Paginator.new(@per_page, @limit).pages.each do |page|
|
13
|
+
parse(fetch(parameters(page))).each do |item|
|
14
|
+
yield item
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def parameters(page)
|
22
|
+
@parameters.merge("Start" => page.start, "Count" => page.count)
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate_parameters(parameters)
|
26
|
+
parameters.keys.each do |k|
|
27
|
+
if %w{start count}.include?(k.to_s.downcase)
|
28
|
+
raise Error,
|
29
|
+
"Limit & Count must not be specified for PaginatingCollection"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Error = Class.new(StandardError)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ralexa
|
2
|
+
class Paginator
|
3
|
+
|
4
|
+
def initialize(per_page, items)
|
5
|
+
@per_page = per_page
|
6
|
+
@items = items
|
7
|
+
end
|
8
|
+
|
9
|
+
def pages
|
10
|
+
page_count.times.map do |i|
|
11
|
+
Page.new(page_count, @per_page, @items, i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def page_count
|
18
|
+
Rational(@items, @per_page).ceil
|
19
|
+
end
|
20
|
+
|
21
|
+
class Page
|
22
|
+
|
23
|
+
def initialize(page_count, per_page, items, index)
|
24
|
+
@page_count = page_count
|
25
|
+
@per_page = per_page
|
26
|
+
@items = items
|
27
|
+
@index = index
|
28
|
+
end
|
29
|
+
|
30
|
+
def number
|
31
|
+
@index + 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def start
|
35
|
+
(@index * @per_page) + 1
|
36
|
+
end
|
37
|
+
|
38
|
+
def finish
|
39
|
+
start + count - 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def count
|
43
|
+
if full? then @per_page else @items % @per_page end
|
44
|
+
end
|
45
|
+
|
46
|
+
def full?
|
47
|
+
number < @page_count || @items % @per_page == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def partial?
|
51
|
+
!full?
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/ralexa/session.rb
CHANGED
data/lib/ralexa/top_sites.rb
CHANGED
@@ -1,37 +1,43 @@
|
|
1
|
-
require "ralexa/abstract_xml_service"
|
2
|
-
|
3
1
|
module Ralexa
|
4
|
-
class TopSites <
|
2
|
+
class TopSites < AbstractService
|
3
|
+
|
4
|
+
PER_PAGE = 100
|
5
5
|
|
6
6
|
# A global list of top sites.
|
7
|
-
def global(params = {})
|
8
|
-
|
7
|
+
def global(limit, params = {})
|
8
|
+
paginating_collection(
|
9
|
+
limit,
|
10
|
+
PER_PAGE,
|
9
11
|
{"ResponseGroup" => "Country"},
|
10
|
-
params
|
11
|
-
|
12
|
+
params,
|
13
|
+
&top_sites_parser
|
14
|
+
)
|
12
15
|
end
|
13
16
|
|
14
17
|
# Top sites for the specified two letter country code.
|
15
|
-
def country(code, params = {})
|
16
|
-
|
18
|
+
def country(code, limit, params = {})
|
19
|
+
paginating_collection(
|
20
|
+
limit,
|
21
|
+
PER_PAGE,
|
17
22
|
{"ResponseGroup" => "Country", "CountryCode" => code.to_s.upcase},
|
18
|
-
params
|
19
|
-
|
23
|
+
params,
|
24
|
+
&top_sites_parser
|
25
|
+
)
|
20
26
|
end
|
21
27
|
|
22
28
|
# All countries that have Alexa top sites.
|
23
29
|
def list_countries(params = {})
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
collection({"ResponseGroup" => "ListCountries"}, params) do |document|
|
31
|
+
path = "//TopSitesResult/Alexa/TopSites/Countries"
|
32
|
+
document.at(path).elements.map do |node|
|
33
|
+
Country.new(
|
34
|
+
node.at("Name").text,
|
35
|
+
node.at("Code").text,
|
36
|
+
node.at("TotalSites").text.to_i,
|
37
|
+
node.at("PageViews").text.to_f * 1_000_000,
|
38
|
+
node.at("Users").text.to_f * 1_000_000,
|
39
|
+
)
|
40
|
+
end
|
35
41
|
end
|
36
42
|
end
|
37
43
|
|
@@ -41,16 +47,18 @@ module Ralexa
|
|
41
47
|
def path; "/" end
|
42
48
|
def default_params; {"Action" => "TopSites"} end
|
43
49
|
|
44
|
-
def
|
45
|
-
document
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
def top_sites_parser
|
51
|
+
->(document){
|
52
|
+
document.at("//TopSites/Country/Sites").elements.map do |node|
|
53
|
+
Site.new(
|
54
|
+
node.at("DataUrl").text,
|
55
|
+
node.at("Country/Rank").text.to_i,
|
56
|
+
node.at("Country/Reach/PerMillion").text.to_i * 1_000_000,
|
57
|
+
(node.at("Country/PageViews/PerMillion").text.to_f * 1_000_000).to_i,
|
58
|
+
node.at("Country/PageViews/PerUser").text.to_f
|
59
|
+
)
|
60
|
+
end
|
61
|
+
}
|
54
62
|
end
|
55
63
|
|
56
64
|
Country = Struct.new(:name, :code, :total_sites, :page_views, :users)
|
data/lib/ralexa/uri_signer.rb
CHANGED
data/lib/ralexa/version.rb
CHANGED
data/lib/ralexa.rb
CHANGED