chrisle-gattica 0.6.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.
@@ -0,0 +1,21 @@
1
+ module GatticaError
2
+ # user errors
3
+ class InvalidEmail < StandardError; end;
4
+ class InvalidPassword < StandardError; end;
5
+ # authentication errors
6
+ class CouldNotAuthenticate < StandardError; end;
7
+ class NoLoginOrToken < StandardError; end;
8
+ class InvalidToken < StandardError; end;
9
+ # profile errors
10
+ class InvalidProfileId < StandardError; end;
11
+ # search errors
12
+ class TooManyDimensions < StandardError; end;
13
+ class TooManyMetrics < StandardError; end;
14
+ class InvalidSort < StandardError; end;
15
+ class InvalidFilter < StandardError; end;
16
+ class MissingStartDate < StandardError; end;
17
+ class MissingEndDate < StandardError; end;
18
+ # errors from Analytics
19
+ class AnalyticsError < StandardError; end;
20
+ class UnknownAnalyticsError < StandardError; end;
21
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+
4
+ module Gattica
5
+ class Goals
6
+ include Convertible
7
+
8
+ attr_reader :id, :updated, :title, :table_id, :account_id, :account_name,
9
+ :profile_id, :web_property_id, :goals
10
+
11
+
12
+ def initialize(xml)
13
+ @id = xml.at(:id).inner_html
14
+ @updated = DateTime.parse(xml.at(:updated).inner_html)
15
+ @account_id = xml.at("dxp:property[@name='ga:accountId']").attributes['value'].to_i
16
+ @account_name = xml.at("dxp:property[@name='ga:accountName']").attributes['value']
17
+
18
+ @title = xml.at("dxp:property[@name='ga:profileName']").attributes['value']
19
+ @table_id = xml.at("dxp:property[@name='dxp:tableId']").attributes['value']
20
+ @profile_id = xml.at("dxp:property[@name='ga:profileId']").attributes['value'].to_i
21
+ @web_property_id = xml.at("dxp:property[@name='ga:webPropertyId']").attributes['value']
22
+
23
+ # @goals = xml.search('ga:goal').collect do |goal| {
24
+ # :active => goal.attributes['active'],
25
+ # :name => goal.attributes['name'],
26
+ # :number => goal.attributes['number'].to_i,
27
+ # :value => goal.attributes['value'].to_f,
28
+ # }
29
+ # end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module Gattica
2
+ module HashExtensions
3
+
4
+ def to_query
5
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
6
+ self.collect do |key, value|
7
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
8
+ end.sort * '&'
9
+ end
10
+
11
+ def key
12
+ self.keys.first if self.length == 1
13
+ end
14
+
15
+ def value
16
+ self.values.first if self.length == 1
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+
4
+ module Gattica
5
+ class Profiles
6
+ include Convertible
7
+
8
+ attr_reader :id, :updated, :title, :table_id, :account_id, :account_name,
9
+ :profile_id, :web_property_id, :goals
10
+
11
+
12
+ def initialize(xml)
13
+ @id = xml.at(:id).inner_html
14
+ @updated = DateTime.parse(xml.at(:updated).inner_html)
15
+ @account_id = xml.at("dxp:property[@name='ga:accountId']").attributes['value'].to_i
16
+ @account_name = xml.at("dxp:property[@name='ga:accountName']").attributes['value']
17
+
18
+ @title = xml.at("dxp:property[@name='ga:profileName']").attributes['value']
19
+ @table_id = xml.at("dxp:property[@name='dxp:tableId']").attributes['value']
20
+ @profile_id = xml.at("dxp:property[@name='ga:profileId']").attributes['value'].to_i
21
+ @web_property_id = xml.at("dxp:property[@name='ga:webPropertyId']").attributes['value']
22
+
23
+ # @goals = xml.search('ga:goal').collect do |goal| {
24
+ # :active => goal.attributes['active'],
25
+ # :name => goal.attributes['name'],
26
+ # :number => goal.attributes['number'].to_i,
27
+ # :value => goal.attributes['value'].to_f,
28
+ # }
29
+ # end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+
4
+ module Gattica
5
+ class Segment
6
+ include Convertible
7
+
8
+ attr_reader :id, :name, :definition
9
+
10
+ def initialize(xml)
11
+ @id = xml.attributes['id']
12
+ @name = xml.attributes['name']
13
+ @definition = xml.at("dxp:definition").inner_html
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ module Gattica
2
+ module Settings
3
+
4
+ USE_SSL = true
5
+ SSL_PORT = 443
6
+ NON_SSL_PORT = 80
7
+
8
+ TIMEOUT = 100
9
+
10
+ DEFAULT_ARGS = {
11
+ :start_date => nil,
12
+ :end_date => nil,
13
+ :dimensions => [],
14
+ :metrics => [],
15
+ :filters => [],
16
+ :sort => []
17
+ }
18
+
19
+ DEFAULT_OPTIONS = {
20
+ :email => nil, # eg: 'email@gmail.com'
21
+ :password => nil, # eg: '$up3r_$ekret'
22
+ :token => nil,
23
+ :profile_id => nil,
24
+ :debug => false,
25
+ :headers => {},
26
+ :logger => Logger.new(STDOUT)
27
+ }
28
+
29
+ FILTER_METRIC_OPERATORS = %w{ == != > < >= <= }
30
+ FILTER_DIMENSION_OPERATORS = %w{ == != =~ !~ =@ ~@ }
31
+
32
+
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ module Gattica
2
+
3
+ # Represents a user to be authenticated by GA
4
+
5
+ class User
6
+
7
+ include Convertible
8
+
9
+ attr_accessor :email, :password
10
+
11
+ def initialize(email,password)
12
+ @email = email
13
+ @password = password
14
+ validate
15
+ end
16
+
17
+ # User gets a special +to_h+ because Google expects +Email+ and +Passwd+ instead of our nicer internal names
18
+ def to_h
19
+ { :Email => @email,
20
+ :Passwd => @password }
21
+ end
22
+
23
+ private
24
+ # Determine whether or not this is a valid user
25
+ def validate
26
+ raise GatticaError::InvalidEmail, "The email address '#{@email}' is not valid" if not @email.match(/^(?:[_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-zA-Z0-9\-\.]+)*(\.[a-z]{2,4})$/i)
27
+ raise GatticaError::InvalidPassword, "The password cannot be blank" if @password.empty? || @password.nil?
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. lib gattica])
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+
6
+ # include Gattica
7
+
8
+ def fixture(name)
9
+ File.read(File.join(File.dirname(__FILE__), 'fixtures', name))
10
+ end
11
+
12
+ def absolute_project_path
13
+ File.expand_path(File.join(File.dirname(__FILE__), '..'))
14
+ end
@@ -0,0 +1,28 @@
1
+ module GatticaTest
2
+
3
+ DEFAULT_AUTH = {
4
+ :email => 'name@email.com',
5
+ :password => 'password',
6
+ :debug => true
7
+ }
8
+ DEFAULT_QUERY = {
9
+ :start_date => '2010-01-01',
10
+ :end_date => '2011-01-01',
11
+ :dimensions => ['date'],
12
+ :metrics => ['visits']
13
+ }
14
+ PROFILE_ID = 23987717
15
+
16
+ def self.ga(options={}, profile_id=PROFILE_ID)
17
+ unless defined? @ga
18
+ @ga = Gattica.new(DEFAULT_AUTH)
19
+ @ga.profile_id = profile_id
20
+ end
21
+ @ga
22
+ end
23
+
24
+ def self.get(options={}, profile_id=PROFILE_ID)
25
+ ga.get(DEFAULT_QUERY.merge(options))
26
+ end
27
+
28
+ end
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+
3
+ tests = Dir["#{File.dirname(__FILE__)}/test_*.rb"]
4
+ tests.each do |file|
5
+ require file
6
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+ require File.expand_path('../settings', __FILE__)
3
+
4
+ class TestEngine < Test::Unit::TestCase
5
+
6
+ def test_login_with_good_password
7
+ assert Gattica.new(GatticaTest::DEFAULT_AUTH),
8
+ "should have been able to login"
9
+ end
10
+
11
+ def test_login_with_bad_user_password
12
+ assert_raise GatticaError::CouldNotAuthenticate do
13
+ Gattica.new({ :email => 'bad-email@gmail.com',
14
+ :password => 'bad-password' })
15
+ end
16
+ end
17
+
18
+ def test_accounts
19
+ ga = Gattica.new(GatticaTest::DEFAULT_AUTH)
20
+ accounts = ga.accounts
21
+ assert accounts.count > 900, "should have gotten at least 900 accounts"
22
+ end
23
+
24
+ # def test_timeout_too_short
25
+ # ga = Gattica.new(GatticaTest::DEFAULT_AUTH.merge!(:timeout => 0))
26
+ # assert_raise Timeout::Error do
27
+ # ga.accounts
28
+ # end
29
+ # end
30
+
31
+ def test_setting_timeout
32
+ ga = Gattica.new((GatticaTest::DEFAULT_AUTH).merge!(:timeout => 300))
33
+ http = ga.instance_variable_get('@http')
34
+ assert http.read_timeout == 300, "http timeout should be 300"
35
+ end
36
+
37
+ # def test_raise_error_when_no_user_pass_or_token_specified
38
+ # assert_raise GatticaError::NoLoginOrToken do
39
+ # Gattica.new
40
+ # end
41
+ # end
42
+ #
43
+ # def test_use_an_existing_token
44
+ # token = Gattica.new(@auth).token
45
+ # assert Gattica.new({ :token => token })
46
+ # end
47
+
48
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+ require File.expand_path('../settings', __FILE__)
3
+
4
+ class TestResults < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @response = GatticaTest::get({ :start_index => 5, :max_results => 5 })
8
+ end
9
+
10
+ def test_max_results
11
+ assert @response.points.count == 5, "should only return 5 results"
12
+ end
13
+
14
+ def test_start_index
15
+ assert @response.points.first.title == "ga:date=20100105", "should start on the 5th"
16
+ end
17
+
18
+ def test_conversions
19
+ assert @response.class.inspect == 'Gattica::DataSet', "should be a Gattica:DataSet"
20
+ assert @response.to_h.class.inspect == 'Hash', "Should be a hash"
21
+ end
22
+
23
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestUser < Test::Unit::TestCase
4
+ def setup
5
+
6
+ end
7
+
8
+ def test_can_create_user
9
+ assert Gattica::User.new('anonymous@anon.com','none')
10
+ end
11
+
12
+ def test_invalid_email
13
+ assert_raise GatticaError::InvalidEmail do Gattica::User.new('','') end
14
+ assert_raise ArgumentError do Gattica::User.new('') end
15
+ assert_raise GatticaError::InvalidEmail do Gattica::User.new('anonymous','none') end
16
+ assert_raise GatticaError::InvalidEmail do Gattica::User.new('anonymous@asdfcom','none') end
17
+ end
18
+
19
+ def test_invalid_password
20
+ assert_raise GatticaError::InvalidPassword do Gattica::User.new('anonymous@anon.com','') end
21
+ assert_raise ArgumentError do Gattica::User.new('anonymous@anon.com') end
22
+ end
23
+
24
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chrisle-gattica
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christopher Le, et all
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: hpricot
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Gattica is a easy to use Ruby Gem for getting data from the Google Analytics
47
+ API. It supports metrics, dimensions, sort, filters, goals, and segments. It can
48
+ handle accounts with 1000+ profiles, and can return data in CSV, Hash, or JSON
49
+ email: chrisl@seerinteractive.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files:
53
+ - LICENSE
54
+ - README.md
55
+ files:
56
+ - Gemfile
57
+ - Gemfile.lock
58
+ - LICENSE
59
+ - README.md
60
+ - Rakefile
61
+ - VERSION.yml
62
+ - chrisle-gattica.gemspec
63
+ - lib/gattica.rb
64
+ - lib/gattica/account.rb
65
+ - lib/gattica/auth.rb
66
+ - lib/gattica/convertible.rb
67
+ - lib/gattica/data_point.rb
68
+ - lib/gattica/data_set.rb
69
+ - lib/gattica/engine.rb
70
+ - lib/gattica/exceptions.rb
71
+ - lib/gattica/goals.rb
72
+ - lib/gattica/hash_extensions.rb
73
+ - lib/gattica/profiles.rb
74
+ - lib/gattica/segment.rb
75
+ - lib/gattica/settings.rb
76
+ - lib/gattica/user.rb
77
+ - test/helper.rb
78
+ - test/settings.rb
79
+ - test/suite.rb
80
+ - test/test_engine.rb
81
+ - test/test_results.rb
82
+ - test/test_user.rb
83
+ homepage: http://github.com/chrisle/gattica
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Gattica is a easy to use Ruby Gem for getting data from the Google Analytics
107
+ API.
108
+ test_files: []
109
+ has_rdoc: