garb 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +32 -18
- data/lib/garb.rb +1 -44
- data/lib/garb/profile.rb +1 -1
- data/lib/garb/report.rb +2 -6
- data/lib/garb/resource.rb +76 -73
- data/lib/garb/session.rb +7 -13
- data/lib/garb/version.rb +2 -2
- data/test/unit/report_test.rb +6 -2
- data/test/unit/resource_test.rb +3 -3
- metadata +1 -1
data/README.md
CHANGED
@@ -8,11 +8,25 @@ garb
|
|
8
8
|
Important Changes
|
9
9
|
=================
|
10
10
|
|
11
|
-
|
11
|
+
Version 0.4.0
|
12
|
+
|
13
|
+
* Changes the api for filters and sort making it consistent with metrics/dimensions
|
14
|
+
* If you wish to clear the defaults defined on a class, you may use clear_(filters/sort/metrics/dimensions)
|
15
|
+
* To make a custom class using Garb::Resource, you must now extend instead of include the module
|
16
|
+
|
17
|
+
Version 0.3.2
|
18
|
+
|
19
|
+
* adds Profile.first which can be used to get the first profile with a table id, or web property id (UA number)
|
20
|
+
|
21
|
+
Version 0.2.4
|
22
|
+
|
23
|
+
* requires happymapper from rubygems, version 0.2.5. Be sure to update.
|
12
24
|
|
13
|
-
|
14
|
-
|
15
|
-
|
25
|
+
Version 0.2.0
|
26
|
+
|
27
|
+
* makes major changes (compared to 0.1.0) to the way garb is used to build reports.
|
28
|
+
* There is now both a module that gets included for generating defined classes,
|
29
|
+
* slight changes to the way that the Report class can be used.
|
16
30
|
|
17
31
|
Description
|
18
32
|
-----------
|
@@ -38,6 +52,8 @@ Profiles
|
|
38
52
|
|
39
53
|
> Garb::Account.first.profiles
|
40
54
|
|
55
|
+
> Garb::Profile.first('UA-XXXX-XX')
|
56
|
+
|
41
57
|
> Garb::Profile.all
|
42
58
|
> profile = Garb::Profile.all.first
|
43
59
|
|
@@ -45,14 +61,16 @@ Define a Report Class and Get Results
|
|
45
61
|
-------------------------------------
|
46
62
|
|
47
63
|
class Exits
|
48
|
-
|
64
|
+
extend Garb::Resource
|
49
65
|
|
50
66
|
metrics :exits, :pageviews, :exit_rate
|
51
|
-
dimensions :
|
67
|
+
dimensions :page_path
|
68
|
+
filters :page_path => 'season'
|
69
|
+
sort :exits
|
52
70
|
end
|
53
71
|
|
54
|
-
Parameters
|
55
|
-
|
72
|
+
Other Parameters
|
73
|
+
----------------
|
56
74
|
|
57
75
|
* start_date: The date of the period you would like this report to start
|
58
76
|
* end_date: The date to end, inclusive
|
@@ -86,7 +104,7 @@ Building a Report
|
|
86
104
|
Or, with sorting and filters:
|
87
105
|
|
88
106
|
Exits.results(profile, :limit => 10, :offset => 19) do
|
89
|
-
|
107
|
+
filters :request_uri.contains => 'season', :exits.gt => 100
|
90
108
|
sort :exits
|
91
109
|
end
|
92
110
|
|
@@ -96,10 +114,11 @@ Build a One-Off Report
|
|
96
114
|
----------------------
|
97
115
|
|
98
116
|
report = Garb::Report.new(profile)
|
99
|
-
report.metrics :pageviews
|
100
|
-
report.dimensions :
|
117
|
+
report.metrics :pageviews, :exits
|
118
|
+
report.dimensions :page_path
|
101
119
|
|
102
|
-
report.
|
120
|
+
report.filters :page_path.contains => 'season', :exits.gte => 10 # AND'd together
|
121
|
+
report.filters :page_path.contains => 'greeting' # OR'd with previous filters
|
103
122
|
report.sort :exits
|
104
123
|
|
105
124
|
report.results
|
@@ -159,22 +178,17 @@ TODOS
|
|
159
178
|
* Single user login is the only supported method currently.
|
160
179
|
Intend to add hooks for using OAuth
|
161
180
|
* Read opensearch header in results
|
162
|
-
* OR joining filter parameters
|
163
181
|
|
164
182
|
Requirements
|
165
183
|
------------
|
166
184
|
|
167
|
-
happymapper >= 0.
|
185
|
+
happymapper >= 0.3.0 (should also install libxml)
|
168
186
|
|
169
187
|
Install
|
170
188
|
-------
|
171
189
|
|
172
190
|
sudo gem install garb
|
173
191
|
|
174
|
-
OR
|
175
|
-
|
176
|
-
sudo gem install vigetlabs-garb -s http://gems.github.com
|
177
|
-
|
178
192
|
License
|
179
193
|
-------
|
180
194
|
|
data/lib/garb.rb
CHANGED
@@ -24,48 +24,5 @@ require 'extensions/symbol'
|
|
24
24
|
require 'extensions/array'
|
25
25
|
|
26
26
|
module Garb
|
27
|
-
# :stopdoc:
|
28
27
|
GA = "http://schemas.google.com/analytics/2008"
|
29
|
-
|
30
|
-
VERSION = '0.1.2'
|
31
|
-
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
32
|
-
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
33
|
-
# :startdoc:
|
34
|
-
|
35
|
-
# Returns the version string for the library.
|
36
|
-
#
|
37
|
-
def self.version
|
38
|
-
VERSION
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns the library path for the module. If any arguments are given,
|
42
|
-
# they will be joined to the end of the libray path using
|
43
|
-
# <tt>File.join</tt>.
|
44
|
-
#
|
45
|
-
def self.libpath( *args )
|
46
|
-
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Returns the lpath for the module. If any arguments are given,
|
50
|
-
# they will be joined to the end of the path using
|
51
|
-
# <tt>File.join</tt>.
|
52
|
-
#
|
53
|
-
def self.path( *args )
|
54
|
-
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Utility method used to rquire all files ending in .rb that lie in the
|
58
|
-
# directory below this file that has the same name as the filename passed
|
59
|
-
# in. Optionally, a specific _directory_ name can be passed in such that
|
60
|
-
# the _filename_ does not have to be equivalent to the directory.
|
61
|
-
#
|
62
|
-
def self.require_all_libs_relative_to( fname, dir = nil )
|
63
|
-
dir ||= ::File.basename(fname, '.*')
|
64
|
-
search_me = ::File.expand_path(
|
65
|
-
::File.join(::File.dirname(fname), dir, '*', '*.rb'))
|
66
|
-
|
67
|
-
Dir.glob(search_me).sort.each {|rb| require rb}
|
68
|
-
end
|
69
|
-
end # module Garb
|
70
|
-
|
71
|
-
# EOF
|
28
|
+
end
|
data/lib/garb/profile.rb
CHANGED
data/lib/garb/report.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Garb
|
2
2
|
class Report
|
3
|
-
include Resource
|
3
|
+
include Resource
|
4
4
|
|
5
5
|
MONTH = 2592000
|
6
6
|
URL = "https://www.google.com/analytics/feeds/data"
|
@@ -13,13 +13,9 @@ module Garb
|
|
13
13
|
@limit = opts.fetch(:limit, nil)
|
14
14
|
@offset = opts.fetch(:offset, nil)
|
15
15
|
|
16
|
-
# clear filters and sort
|
17
|
-
@filters = ReportParameter.new(:filters)
|
18
|
-
@sorts = ReportParameter.new(:sort)
|
19
|
-
|
20
16
|
metrics opts.fetch(:metrics, [])
|
21
17
|
dimensions opts.fetch(:dimensions, [])
|
22
|
-
|
18
|
+
filters opts.fetch(:filters, [])
|
23
19
|
sort opts.fetch(:sort, [])
|
24
20
|
end
|
25
21
|
|
data/lib/garb/resource.rb
CHANGED
@@ -3,87 +3,90 @@ module Garb
|
|
3
3
|
MONTH = 2592000
|
4
4
|
URL = "https://www.google.com/analytics/feeds/data"
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def metrics(*fields)
|
13
|
-
@metrics ||= ReportParameter.new(:metrics)
|
14
|
-
@metrics << fields
|
15
|
-
end
|
16
|
-
|
17
|
-
def dimensions(*fields)
|
18
|
-
@dimensions ||= ReportParameter.new(:dimensions)
|
19
|
-
@dimensions << fields
|
20
|
-
end
|
21
|
-
|
22
|
-
def filter(*hash)
|
23
|
-
@filters << hash
|
24
|
-
end
|
25
|
-
|
26
|
-
def filters
|
27
|
-
@filters ||= ReportParameter.new(:filters)
|
28
|
-
end
|
29
|
-
|
30
|
-
def sort(*fields)
|
31
|
-
@sorts << fields
|
32
|
-
end
|
33
|
-
|
34
|
-
def sorts
|
35
|
-
@sorts ||= ReportParameter.new(:sort)
|
36
|
-
end
|
37
|
-
|
38
|
-
def results(profile, opts = {}, &block)
|
39
|
-
@profile = profile
|
40
|
-
|
41
|
-
# clear filters and sort
|
42
|
-
@filters = ReportParameter.new(:filters)
|
43
|
-
@sorts = ReportParameter.new(:sort)
|
44
|
-
|
45
|
-
@start_date = opts.fetch(:start_date, Time.now - MONTH)
|
46
|
-
@end_date = opts.fetch(:end_date, Time.now)
|
47
|
-
@limit = opts.fetch(:limit, nil)
|
48
|
-
@offset = opts.fetch(:offset, nil)
|
49
|
-
|
50
|
-
instance_eval(&block) if block_given?
|
6
|
+
%w(metrics dimensions filters sort).each do |parameter|
|
7
|
+
class_eval <<-CODE
|
8
|
+
def #{parameter}(*fields)
|
9
|
+
@#{parameter} ||= ReportParameter.new(:#{parameter})
|
10
|
+
@#{parameter} << fields
|
11
|
+
end
|
51
12
|
|
52
|
-
|
53
|
-
|
13
|
+
def clear_#{parameter}
|
14
|
+
@#{parameter} = ReportParameter.new(:#{parameter})
|
15
|
+
end
|
16
|
+
CODE
|
17
|
+
end
|
54
18
|
|
55
|
-
|
56
|
-
|
57
|
-
|
19
|
+
# def metrics(*fields)
|
20
|
+
# @metrics ||= ReportParameter.new(:metrics)
|
21
|
+
# @metrics << fields
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def dimensions(*fields)
|
25
|
+
# @dimensions ||= ReportParameter.new(:dimensions)
|
26
|
+
# @dimensions << fields
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# def filters(*hashes)
|
30
|
+
# @filters ||= ReportParameter.new(:filters)
|
31
|
+
# @filters << hashes
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# def sort(*fields)
|
35
|
+
# @sort ||= ReportParameter.new(:sort)
|
36
|
+
# @sort << fields
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def clear_filters
|
40
|
+
# @filters = ReportParameter.new(:filters)
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# def clear_sort
|
44
|
+
# @sort = ReportParameter.new(:sort)
|
45
|
+
# end
|
46
|
+
|
47
|
+
def results(profile, opts = {}, &block)
|
48
|
+
@profile = profile.is_a?(Profile) ? profile : Profile.first(profile)
|
49
|
+
|
50
|
+
@start_date = opts.fetch(:start_date, Time.now - MONTH)
|
51
|
+
@end_date = opts.fetch(:end_date, Time.now)
|
52
|
+
@limit = opts.fetch(:limit, nil)
|
53
|
+
@offset = opts.fetch(:offset, nil)
|
54
|
+
|
55
|
+
instance_eval(&block) if block_given?
|
56
|
+
|
57
|
+
ReportResponse.new(send_request_for_body).results
|
58
|
+
end
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
'end-date' => format_time(@end_date)}
|
63
|
-
end
|
60
|
+
def page_params
|
61
|
+
{'max-results' => @limit, 'start-index' => @offset}.reject{|k,v| v.nil?}
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
filters.to_params,
|
71
|
-
page_params
|
72
|
-
].inject(default_params) do |p, i|
|
73
|
-
p.merge(i)
|
74
|
-
end
|
75
|
-
end
|
64
|
+
def default_params
|
65
|
+
{'ids' => @profile.table_id,
|
66
|
+
'start-date' => format_time(@start_date),
|
67
|
+
'end-date' => format_time(@end_date)}
|
68
|
+
end
|
76
69
|
|
77
|
-
|
78
|
-
|
70
|
+
def params
|
71
|
+
[
|
72
|
+
metrics.to_params,
|
73
|
+
dimensions.to_params,
|
74
|
+
sort.to_params,
|
75
|
+
filters.to_params,
|
76
|
+
page_params
|
77
|
+
].inject(default_params) do |p, i|
|
78
|
+
p.merge(i)
|
79
79
|
end
|
80
|
+
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
response.body
|
85
|
-
end
|
82
|
+
def format_time(t)
|
83
|
+
t.strftime('%Y-%m-%d')
|
84
|
+
end
|
86
85
|
|
86
|
+
def send_request_for_body
|
87
|
+
request = DataRequest.new(URL, params)
|
88
|
+
response = request.send_request
|
89
|
+
response.body
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
data/lib/garb/session.rb
CHANGED
@@ -1,19 +1,13 @@
|
|
1
1
|
module Garb
|
2
|
-
|
2
|
+
module Session
|
3
|
+
extend self
|
4
|
+
|
5
|
+
attr_accessor :auth_token, :email
|
3
6
|
|
4
|
-
def
|
5
|
-
|
7
|
+
def login(email, password, opts={})
|
8
|
+
self.email = email
|
6
9
|
auth_request = AuthenticationRequest.new(email, password, opts)
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.auth_token
|
11
|
-
@auth_token
|
10
|
+
self.auth_token = auth_request.auth_token(opts)
|
12
11
|
end
|
13
|
-
|
14
|
-
def self.email
|
15
|
-
@email
|
16
|
-
end
|
17
|
-
|
18
12
|
end
|
19
13
|
end
|
data/lib/garb/version.rb
CHANGED
data/test/unit/report_test.rb
CHANGED
@@ -11,10 +11,14 @@ module Garb
|
|
11
11
|
@report = Report.new(@profile)
|
12
12
|
end
|
13
13
|
|
14
|
-
%w(metrics dimensions filters
|
14
|
+
%w(metrics dimensions filters sort).each do |param|
|
15
15
|
should "have parameters for #{param}" do
|
16
16
|
assert @report.send(:"#{param}").is_a?(ReportParameter)
|
17
17
|
end
|
18
|
+
|
19
|
+
should "clear parameters for #{param}" do
|
20
|
+
assert_equal({}, @report.send(:"clear_#{param}").to_params)
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
should "have default parameters" do
|
@@ -27,7 +31,7 @@ module Garb
|
|
27
31
|
@report.stubs(:metrics).returns(stub(:to_params => {'metrics' => 6}))
|
28
32
|
@report.stubs(:dimensions).returns(stub(:to_params => {'dimensions' => 5}))
|
29
33
|
@report.stubs(:filters).returns(stub(:to_params => {'filters' => 4}))
|
30
|
-
@report.stubs(:
|
34
|
+
@report.stubs(:sort).returns(stub(:to_params => {'sort' => 3}))
|
31
35
|
@report.stubs(:page_params).returns({'page_params' => 2})
|
32
36
|
@report.stubs(:default_params).returns({'default_params' => 1})
|
33
37
|
|
data/test/unit/resource_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
2
|
|
3
3
|
class TestReport
|
4
|
-
|
4
|
+
extend Garb::Resource
|
5
5
|
end
|
6
6
|
|
7
7
|
# Most of the resource testing is done as a part of ReportTest
|
@@ -9,11 +9,11 @@ class ResourceTest < MiniTest::Unit::TestCase
|
|
9
9
|
|
10
10
|
context "A class with Garb::Resource mixed in" do
|
11
11
|
should "get results from GA" do
|
12
|
-
profile = stub
|
12
|
+
profile = stub(:is_a? => true)
|
13
13
|
TestReport.expects(:send_request_for_body).returns('xml')
|
14
14
|
Garb::ReportResponse.expects(:new).with('xml').returns(mock(:results => 'analytics'))
|
15
15
|
|
16
16
|
assert_equal 'analytics', TestReport.results(profile)
|
17
17
|
end
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|