morgoth-alexa 0.0.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Wojciech Wnętrzak
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,16 @@
1
+ = Alexa Web Information Service
2
+
3
+ == Usage
4
+ Alexa.url_info(:access_key_id => 'key', :secret_access_key => 'secret', :host => 'site.com')
5
+ # also you can specify option :response_group => 'Rank,ContactInfo' or any other valid group,
6
+ # see: http://docs.amazonwebservices.com/AlexaWebInfoService/2005-07-11/
7
+ # default response group takes all the available options
8
+
9
+ returns object with methods:
10
+ :xml_response, :rank, :data_url, :site_title, :site_description, :language_locale, :language_encoding,
11
+ :links_in_count, :keywords, :related_links, :speed_median_load_time, :speed_percentile,
12
+ :rank_by_country, :rank_by_city, :usage_statistics
13
+
14
+ == Copyright
15
+
16
+ Copyright (c) 2009 Wojciech Wnętrzak. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "alexa"
9
+ gem.summary = %Q{Alexa Web Information Service library}
10
+ gem.email = "w.wnetrzak@gmail.com"
11
+ gem.homepage = "http://github.com/morgoth/alexa"
12
+ gem.authors = ["Wojciech Wnętrzak"]
13
+ gem.add_dependency('xml-simple')
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION.yml')
47
+ config = YAML.load(File.read('VERSION.yml'))
48
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "alexa #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/alexa.gemspec ADDED
@@ -0,0 +1,51 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{alexa}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Wojciech Wnętrzak"]
9
+ s.date = %q{2009-07-03}
10
+ s.email = %q{w.wnetrzak@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "alexa.gemspec",
23
+ "lib/alexa.rb",
24
+ "lib/alexa/url_info.rb",
25
+ "test/alexa_test.rb",
26
+ "test/fixtures/polsl.xml",
27
+ "test/test_helper.rb"
28
+ ]
29
+ s.homepage = %q{http://github.com/morgoth/alexa}
30
+ s.rdoc_options = ["--charset=UTF-8"]
31
+ s.require_paths = ["lib"]
32
+ s.rubygems_version = %q{1.3.4}
33
+ s.summary = %q{Alexa Web Information Service library}
34
+ s.test_files = [
35
+ "test/alexa_test.rb",
36
+ "test/test_helper.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<xml-simple>, [">= 0"])
45
+ else
46
+ s.add_dependency(%q<xml-simple>, [">= 0"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<xml-simple>, [">= 0"])
50
+ end
51
+ end
@@ -0,0 +1,62 @@
1
+ module Alexa
2
+ class UrlInfo
3
+ RESPONSE_GROUP = "Rank,ContactInfo,AdultContent,Speed,Language,Keywords,OwnedDomains,LinksInCount,SiteData,RelatedLinks,RankByCountry,RankByCity,UsageStats"
4
+ attr_accessor :access_key_id, :secret_access_key, :host, :response_group, :xml_response,
5
+ :rank, :data_url, :site_title, :site_description, :language_locale, :language_encoding,
6
+ :links_in_count, :keywords, :related_links, :speed_median_load_time, :speed_percentile,
7
+ :rank_by_country, :rank_by_city, :usage_statistics
8
+
9
+ def initialize(options = {} )
10
+ @access_key_id = options[:access_key_id]
11
+ @secret_access_key = options[:secret_access_key]
12
+ @host = options[:host]
13
+ @response_group = options[:response_group] || RESPONSE_GROUP
14
+ end
15
+
16
+ def connect
17
+ action = "UrlInfo"
18
+ timestamp = ( Time::now ).utc.strftime("%Y-%m-%dT%H:%M:%S.000Z")
19
+ signature = generate_signature(secret_access_key, action, timestamp)
20
+ url = generate_url(action, access_key_id, signature, timestamp, response_group, host)
21
+ @xml_response = Net::HTTP.get(url)
22
+ end
23
+
24
+ def parse_xml(xml)
25
+ xml = XmlSimple.xml_in(xml.force_encoding(Encoding::UTF_8), 'ForceArray' => false)
26
+ @rank = xml['Response']['UrlInfoResult']['Alexa']['TrafficData']['Rank'].to_i
27
+ @data_url = xml['Response']['UrlInfoResult']['Alexa']['TrafficData']['DataUrl']['content']
28
+ @site_title = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['SiteData']['Title']
29
+ @site_description = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['SiteData']['Description']
30
+ @language_locale = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['Language']['Locale']
31
+ @language_encoding = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['Language']['Encoding']
32
+ @links_in_count = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['LinksInCount'].to_i
33
+ @keywords = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['Keywords']['Keyword']
34
+ @related_links = xml['Response']['UrlInfoResult']['Alexa']['Related']['RelatedLinks']['RelatedLink']
35
+ @speed_median_load_time = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['Speed']['MedianLoadTime'].to_i
36
+ @speed_percentile = xml['Response']['UrlInfoResult']['Alexa']['ContentData']['Speed']['Percentile'].to_i
37
+ @rank_by_country = xml['Response']['UrlInfoResult']['Alexa']['TrafficData']['RankByCountry']['Country']
38
+ @rank_by_city = xml['Response']['UrlInfoResult']['Alexa']['TrafficData']['RankByCity']['City']
39
+ @usage_statistics = xml['Response']['UrlInfoResult']['Alexa']['TrafficData']['UsageStatistics']["UsageStatistic"]
40
+ end
41
+
42
+ private
43
+
44
+ def generate_signature(secret_acces_key, action, timestamp)
45
+ Base64.encode64( OpenSSL::HMAC.digest( OpenSSL::Digest::Digest.new( "sha1" ), secret_access_key, action + timestamp)).strip
46
+ end
47
+
48
+ def generate_url(action, access_key_id, signature, timestamp, response_group, host)
49
+ url = URI.parse(
50
+ "http://awis.amazonaws.com/?" +
51
+ {
52
+ "Action" => action,
53
+ "AWSAccessKeyId" => access_key_id,
54
+ "Signature" => signature,
55
+ "Timestamp" => timestamp,
56
+ "ResponseGroup" => response_group,
57
+ "Url" => host
58
+ }.to_a.collect{|item| item.first + "=" + CGI::escape(item.last) }.join("&") # Put key value pairs into http GET format
59
+ )
60
+ end
61
+ end
62
+ end
data/lib/alexa.rb ADDED
@@ -0,0 +1,21 @@
1
+ #/usr/bin/ruby
2
+ require "cgi"
3
+ require "base64"
4
+ require "openssl"
5
+ require "digest/sha1"
6
+ require "uri"
7
+ require "net/https"
8
+ require "xmlsimple"
9
+ require "time"
10
+
11
+ require 'alexa/url_info'
12
+
13
+ module Alexa
14
+ def self.url_info(options = {})
15
+ url_info = Alexa::UrlInfo.new(options)
16
+ xml = url_info.connect
17
+ url_info.parse_xml(xml)
18
+ url_info
19
+ end
20
+ end
21
+
@@ -0,0 +1,96 @@
1
+ require 'test_helper'
2
+
3
+ class AlexaTest < Test::Unit::TestCase
4
+ context "Alexa::UrlInfo" do
5
+ setup do
6
+ @alexa = Alexa::UrlInfo.new(
7
+ :access_key_id => "12345678901234567890",
8
+ :secret_access_key => "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDF",
9
+ :host => "some.host"
10
+ )
11
+ end
12
+
13
+ should "Generate signature" do
14
+ signature = @alexa.send :generate_signature, @alexa.secret_access_key, "UrlInfo", '2009-07-03T07:22:24.000Z'
15
+ assert_equal "I1mPdBy+flhhzqqUaamNq9gq190=", signature
16
+ end
17
+
18
+ should "Generatee url" do
19
+ url = @alexa.send( :generate_url,
20
+ "UrlInfo",
21
+ @alexa.access_key_id,
22
+ "I1mPdBy+flhhzqqUaamNq9gq190=",
23
+ '2009-07-03T07:22:24.000Z',
24
+ "Rank,ContactInfo,AdultContent,Speed,Language,Keywords,OwnedDomains,LinksInCount,SiteData,RelatedLinks",
25
+ "heroku.com"
26
+ )
27
+ expected_uri = "/?Action=UrlInfo&AWSAccessKeyId=12345678901234567890&Signature=I1mPdBy%2BflhhzqqUaamNq9gq190%3D&Timestamp=2009-07-03T07%3A22%3A24.000Z&ResponseGroup=Rank%2CContactInfo%2CAdultContent%2CSpeed%2CLanguage%2CKeywords%2COwnedDomains%2CLinksInCount%2CSiteData%2CRelatedLinks&Url=heroku.com"
28
+ assert_equal expected_uri, url.request_uri
29
+ assert_equal "awis.amazonaws.com", url.host
30
+ end
31
+
32
+ context "should parse xml and" do
33
+ setup do
34
+ @xml = fixture_file('polsl.xml')
35
+ @alexa.parse_xml(@xml)
36
+ end
37
+
38
+ should "return rank" do
39
+ assert_equal 86020, @alexa.rank
40
+ end
41
+
42
+ should "return data url" do
43
+ assert_equal "polsl.pl", @alexa.data_url
44
+ end
45
+
46
+ should "return site title" do
47
+ assert_equal "Silesian University of Technology", @alexa.site_title
48
+ end
49
+
50
+ should "return site description" do
51
+ assert_equal "About the university, studies, faculties and departments, photo gallery.", @alexa.site_description
52
+ end
53
+
54
+ should "return language locale" do
55
+ assert_equal "pl-PL", @alexa.language_locale
56
+ end
57
+
58
+ should "return language encoding" do
59
+ assert_equal "iso-8859-2", @alexa.language_encoding
60
+ end
61
+
62
+ should "return links in count" do
63
+ assert_equal 281, @alexa.links_in_count
64
+ end
65
+
66
+ should "return keywords" do
67
+ assert_equal ["Polska", "Regionalne", "Gliwice"], @alexa.keywords
68
+ end
69
+
70
+ should "return related links" do
71
+ assert_equal 10, @alexa.related_links.count
72
+ end
73
+
74
+ should "return speed_median load time" do
75
+ assert_equal 266, @alexa.speed_median_load_time
76
+ end
77
+
78
+ should "return speed percentile" do
79
+ assert_equal 98, @alexa.speed_percentile
80
+ end
81
+
82
+ should "return rank by country" do
83
+ assert_equal 3, @alexa.rank_by_country.count
84
+ end
85
+
86
+ should "return rank by city" do
87
+ assert_equal 68, @alexa.rank_by_city.count
88
+ end
89
+
90
+ should "return usage statistics" do
91
+ assert_equal 4, @alexa.usage_statistics.count
92
+ end
93
+
94
+ end
95
+ end
96
+ end