garb 0.3.2 → 0.4.0
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 +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
|