ralexa 0.0.2 → 0.0.3
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 +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