garb 0.5.0 → 0.5.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/README.md +23 -6
- data/lib/garb.rb +4 -1
- data/lib/garb/authentication_request.rb +4 -4
- data/lib/garb/filter_parameters.rb +12 -20
- data/lib/garb/report_parameter.rb +1 -1
- data/lib/garb/resource.rb +6 -1
- data/lib/garb/version.rb +1 -1
- data/lib/support.rb +39 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/garb/filter_parameters_test.rb +14 -22
- data/test/unit/garb/report_parameter_test.rb +8 -8
- data/test/unit/garb/report_test.rb +9 -1
- data/test/unit/garb_test.rb +1 -0
- data/test/unit/symbol_operator_test.rb +37 -0
- metadata +6 -6
- data/lib/garb/operator.rb +0 -22
- data/test/unit/garb/operator_test.rb +0 -39
data/README.md
CHANGED
@@ -8,6 +8,11 @@ garb
|
|
8
8
|
Important Changes
|
9
9
|
=================
|
10
10
|
|
11
|
+
Version 0.5.0
|
12
|
+
|
13
|
+
* Filters now have a new DSL so that I could toss Symbol operators (which conflict with DataMapper and MongoMapper)
|
14
|
+
* The method of passing a hash to filters no longer works, at all
|
15
|
+
|
11
16
|
Version 0.4.0
|
12
17
|
|
13
18
|
* Changes the api for filters and sort making it consistent with metrics/dimensions
|
@@ -65,8 +70,11 @@ Define a Report Class and Get Results
|
|
65
70
|
|
66
71
|
metrics :exits, :pageviews, :exit_rate
|
67
72
|
dimensions :page_path
|
68
|
-
filters :page_path => 'season'
|
69
73
|
sort :exits
|
74
|
+
|
75
|
+
filters do
|
76
|
+
eql(:page_path, 'season')
|
77
|
+
end
|
70
78
|
end
|
71
79
|
|
72
80
|
Other Parameters
|
@@ -104,8 +112,12 @@ Building a Report
|
|
104
112
|
Or, with sorting and filters:
|
105
113
|
|
106
114
|
Exits.results(profile, :limit => 10, :offset => 19) do
|
107
|
-
filters :request_uri.contains => 'season', :exits.gt => 100
|
108
115
|
sort :exits
|
116
|
+
|
117
|
+
filters do
|
118
|
+
contains(:page_path, 'season')
|
119
|
+
gt(:exits, 100)
|
120
|
+
end
|
109
121
|
end
|
110
122
|
|
111
123
|
reports will be an array of OpenStructs with methods for the metrics and dimensions returned.
|
@@ -116,11 +128,13 @@ Build a One-Off Report
|
|
116
128
|
report = Garb::Report.new(profile)
|
117
129
|
report.metrics :pageviews, :exits
|
118
130
|
report.dimensions :page_path
|
119
|
-
|
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
|
122
131
|
report.sort :exits
|
123
132
|
|
133
|
+
report.filters do
|
134
|
+
contains(:page_path, 'season')
|
135
|
+
gte(:exits, 10)
|
136
|
+
and
|
137
|
+
|
124
138
|
report.results
|
125
139
|
|
126
140
|
Filtering
|
@@ -156,7 +170,9 @@ Filtering
|
|
156
170
|
|
157
171
|
Given the previous example one-off report, we can add a line for filter:
|
158
172
|
|
159
|
-
report.filters
|
173
|
+
report.filters do
|
174
|
+
eql(:page_path, '/extend/effectively-using-git-with-subversion/')
|
175
|
+
end
|
160
176
|
|
161
177
|
SSL
|
162
178
|
---
|
@@ -183,6 +199,7 @@ Requirements
|
|
183
199
|
------------
|
184
200
|
|
185
201
|
happymapper >= 0.3.0 (should also install libxml)
|
202
|
+
active_support >= 2.3.0
|
186
203
|
|
187
204
|
Install
|
188
205
|
-------
|
data/lib/garb.rb
CHANGED
@@ -20,12 +20,15 @@ require 'garb/report_parameter'
|
|
20
20
|
require 'garb/report_response'
|
21
21
|
require 'garb/resource'
|
22
22
|
require 'garb/report'
|
23
|
-
|
23
|
+
|
24
|
+
require 'support'
|
24
25
|
|
25
26
|
module Garb
|
26
27
|
GA = "http://schemas.google.com/analytics/2008"
|
27
28
|
|
28
29
|
def self.to_google_analytics(thing)
|
30
|
+
return thing.to_google_analytics if thing.respond_to?(:to_google_analytics)
|
31
|
+
|
29
32
|
"ga:#{thing.to_s.camelize(:lower)}"
|
30
33
|
end
|
31
34
|
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Garb
|
2
2
|
class AuthenticationRequest
|
3
3
|
class AuthError < StandardError;end
|
4
|
-
|
4
|
+
|
5
5
|
URL = 'https://www.google.com/accounts/ClientLogin'
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(email, password, opts={})
|
8
8
|
@email = email
|
9
9
|
@password = password
|
10
10
|
@account_type = opts.fetch(:account_type, 'HOSTED_OR_GOOGLE')
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def parameters
|
14
14
|
{
|
15
15
|
'Email' => @email,
|
@@ -23,7 +23,7 @@ module Garb
|
|
23
23
|
def uri
|
24
24
|
URI.parse(URL)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def send_request(ssl_mode)
|
28
28
|
http = Net::HTTP.new(uri.host, uri.port)
|
29
29
|
http.use_ssl = true
|
@@ -1,25 +1,17 @@
|
|
1
1
|
module Garb
|
2
2
|
class FilterParameters
|
3
|
-
def self.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
def self.define_operators(*methods)
|
4
|
+
methods.each do |method|
|
5
|
+
class_eval <<-CODE
|
6
|
+
def #{method}(field, value)
|
7
|
+
self.parameters << {SymbolOperator.new(field, :#{method}) => value}
|
8
|
+
end
|
9
|
+
CODE
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
define_operator(:gt, '>')
|
14
|
-
define_operator(:gte, '>=')
|
15
|
-
define_operator(:lt, '<')
|
16
|
-
define_operator(:lte, '<=')
|
17
|
-
define_operator(:matches, '==')
|
18
|
-
define_operator(:does_not_match, '!=')
|
19
|
-
define_operator(:contains, '=~')
|
20
|
-
define_operator(:does_not_contain, '!~')
|
21
|
-
define_operator(:substring, '=@')
|
22
|
-
define_operator(:not_substring, '!@')
|
13
|
+
define_operators :eql, :not_eql, :gt, :gte, :lt, :lte, :matches,
|
14
|
+
:does_not_match, :contains, :does_not_contain, :substring, :not_substring
|
23
15
|
|
24
16
|
attr_accessor :parameters
|
25
17
|
|
@@ -34,8 +26,8 @@ module Garb
|
|
34
26
|
def to_params
|
35
27
|
value = self.parameters.map do |param|
|
36
28
|
param.map do |k,v|
|
37
|
-
next unless k.is_a?(
|
38
|
-
"#{
|
29
|
+
next unless k.is_a?(SymbolOperator)
|
30
|
+
"#{URI.encode(k.to_google_analytics, /[=<>]/)}#{CGI::escape(v.to_s)}"
|
39
31
|
end.join(',') # Hash AND
|
40
32
|
end.join(';') # Array OR
|
41
33
|
|
data/lib/garb/resource.rb
CHANGED
@@ -16,8 +16,13 @@ module Garb
|
|
16
16
|
CODE
|
17
17
|
end
|
18
18
|
|
19
|
-
def filters(&block)
|
19
|
+
def filters(*hashes, &block)
|
20
20
|
@filter_parameters ||= FilterParameters.new
|
21
|
+
|
22
|
+
hashes.each do |hash|
|
23
|
+
@filter_parameters.parameters << hash
|
24
|
+
end
|
25
|
+
|
21
26
|
@filter_parameters.filters(&block) if block_given?
|
22
27
|
@filter_parameters
|
23
28
|
end
|
data/lib/garb/version.rb
CHANGED
data/lib/support.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
class SymbolOperator
|
2
|
+
def initialize(field, operator)
|
3
|
+
@field, @operator = field, operator
|
4
|
+
end unless method_defined?(:initialize)
|
5
|
+
|
6
|
+
def to_google_analytics
|
7
|
+
operators = {
|
8
|
+
:eql => '==',
|
9
|
+
:not_eql => '!=',
|
10
|
+
:gt => '>',
|
11
|
+
:gte => '>=',
|
12
|
+
:lt => '<',
|
13
|
+
:lte => '<=',
|
14
|
+
:matches => '==',
|
15
|
+
:does_not_match => '!=',
|
16
|
+
:contains => '=~',
|
17
|
+
:does_not_contain => '!~',
|
18
|
+
:substring => '=@',
|
19
|
+
:not_substring => '!@',
|
20
|
+
:desc => '-'
|
21
|
+
}
|
22
|
+
|
23
|
+
target = Garb.to_google_analytics(@field)
|
24
|
+
operator = operators[@operator]
|
25
|
+
|
26
|
+
@operator == :desc ? "#{operator}#{target}" : "#{target}#{operator}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Symbol
|
31
|
+
[:eql, :not_eql, :gt, :gte, :lt, :lte, :desc,
|
32
|
+
:matches, :does_not_match, :contains, :does_not_contain,
|
33
|
+
:substring, :not_substring].each do |operator|
|
34
|
+
|
35
|
+
define_method(operator) do
|
36
|
+
SymbolOperator.new(self, operator)
|
37
|
+
end unless method_defined?(operator)
|
38
|
+
end
|
39
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,16 +2,18 @@ require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
|
|
2
2
|
|
3
3
|
module Garb
|
4
4
|
class FilterParametersTest < MiniTest::Unit::TestCase
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def self.should_define_operators(*operators)
|
6
|
+
operators.each do |operator|
|
7
|
+
should "create an operator and add to parameters for the #{operator} method" do
|
8
|
+
new_operator = stub
|
9
|
+
symbol = :foo
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
SymbolOperator.expects(:new).with(:bar, operator).returns(new_operator)
|
12
|
+
@filter_parameters.send(operator.to_sym, :bar, 100)
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
parameter = {new_operator => 100}
|
15
|
+
assert_equal parameter, @filter_parameters.parameters.last
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
@@ -20,18 +22,8 @@ module Garb
|
|
20
22
|
@filter_parameters = FilterParameters.new
|
21
23
|
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
should_define_operator(:gt, '>')
|
26
|
-
should_define_operator(:gte, '>=')
|
27
|
-
should_define_operator(:lt, '<')
|
28
|
-
should_define_operator(:lte, '<=')
|
29
|
-
should_define_operator(:matches, '==')
|
30
|
-
should_define_operator(:does_not_match, '!=')
|
31
|
-
should_define_operator(:contains, '=~')
|
32
|
-
should_define_operator(:does_not_contain, '!~')
|
33
|
-
should_define_operator(:substring, '=@')
|
34
|
-
should_define_operator(:not_substring, '!@')
|
25
|
+
should_define_operators :eql, :not_eql, :gt, :gte, :lt, :lte,
|
26
|
+
:matches, :does_not_match, :contains, :does_not_contain, :substring, :not_substring
|
35
27
|
|
36
28
|
should "instance eval for filters" do
|
37
29
|
blk = lambda {"in a block"}
|
@@ -53,10 +45,10 @@ module Garb
|
|
53
45
|
|
54
46
|
should "properly encode operators" do
|
55
47
|
@filter_parameters.filters do
|
56
|
-
contains(:
|
48
|
+
contains(:page_path, 'New York')
|
57
49
|
end
|
58
50
|
|
59
|
-
params = {'filters' => 'ga:
|
51
|
+
params = {'filters' => 'ga:pagePath%3D~New+York'}
|
60
52
|
assert_equal params, @filter_parameters.to_params
|
61
53
|
end
|
62
54
|
end
|
@@ -17,24 +17,24 @@ module Garb
|
|
17
17
|
end
|
18
18
|
|
19
19
|
should "be able to add new elements" do
|
20
|
-
assert_equal(@metrics, @metrics << :
|
21
|
-
assert_equal [:
|
20
|
+
assert_equal(@metrics, @metrics << :page_path)
|
21
|
+
assert_equal [:page_path], @metrics.elements
|
22
22
|
end
|
23
23
|
|
24
24
|
should "merge an array of elements" do
|
25
|
-
assert_equal(@metrics, @metrics << [:
|
26
|
-
assert_equal [:
|
25
|
+
assert_equal(@metrics, @metrics << [:page_path])
|
26
|
+
assert_equal [:page_path], @metrics.elements
|
27
27
|
end
|
28
28
|
|
29
29
|
context "converting to params" do
|
30
30
|
should "be able to format the parameters into strings" do
|
31
|
-
@metrics << :
|
32
|
-
assert_equal({'metrics' => 'ga:
|
31
|
+
@metrics << :page_path
|
32
|
+
assert_equal({'metrics' => 'ga:pagePath'}, @metrics.to_params)
|
33
33
|
end
|
34
34
|
|
35
35
|
should "join multiple symbol elements" do
|
36
|
-
@metrics << :
|
37
|
-
assert_equal({'metrics' => 'ga:
|
36
|
+
@metrics << :page_path << :city
|
37
|
+
assert_equal({'metrics' => 'ga:pagePath,ga:city'}, @metrics.to_params)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -25,8 +25,16 @@ module Garb
|
|
25
25
|
assert @report.filters.is_a?(FilterParameters)
|
26
26
|
end
|
27
27
|
|
28
|
+
should "add new filters to filter parameters" do
|
29
|
+
@report.clear_filters
|
30
|
+
hash = {:thing.gt => 'val'}
|
31
|
+
@report.filters hash
|
32
|
+
|
33
|
+
assert_equal hash, @report.filters.parameters.first
|
34
|
+
end
|
35
|
+
|
28
36
|
should "clear filter parameters for filters" do
|
29
|
-
assert_equal({}, @report.
|
37
|
+
assert_equal({}, @report.clear_filters.to_params)
|
30
38
|
end
|
31
39
|
|
32
40
|
should "have default parameters" do
|
data/test/unit/garb_test.rb
CHANGED
@@ -3,6 +3,7 @@ require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
|
3
3
|
class GarbTest < MiniTest::Unit::TestCase
|
4
4
|
context "The Garb module" do
|
5
5
|
should 'prefix a string with ga: for GA' do
|
6
|
+
assert_equal '-ga:bob', Garb.to_google_analytics(stub(:to_google_analytics => '-ga:bob'))
|
6
7
|
assert_equal 'ga:bob', Garb.to_google_analytics('bob')
|
7
8
|
end
|
8
9
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '/test_helper')
|
2
|
+
|
3
|
+
class SymbolOperatorTest < MiniTest::Unit::TestCase
|
4
|
+
context "An instance of a SymbolOperator" do
|
5
|
+
should "lower camelize the target" do
|
6
|
+
assert_equal "ga:uniqueVisits==", SymbolOperator.new(:unique_visits, :eql).to_google_analytics
|
7
|
+
end
|
8
|
+
|
9
|
+
should "return target and operator together" do
|
10
|
+
assert_equal "ga:metric==", SymbolOperator.new(:metric, :eql).to_google_analytics
|
11
|
+
end
|
12
|
+
|
13
|
+
should "prefix the operator to the target" do
|
14
|
+
assert_equal "-ga:metric", SymbolOperator.new(:metric, :desc).to_google_analytics
|
15
|
+
end
|
16
|
+
|
17
|
+
# should "know if it is equal to another operator" do
|
18
|
+
# op1 = SymbolOperator.new(:hello, "==")
|
19
|
+
# op2 = SymbolOperator.new(:hello, "==")
|
20
|
+
# assert_equal op1, op2
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# should "not be equal to another operator if target, operator, or prefix is different" do
|
24
|
+
# op1 = SymbolOperator.new(:hello, "==")
|
25
|
+
# op2 = SymbolOperator.new(:hello, "==", true)
|
26
|
+
# refute_equal op1, op2
|
27
|
+
#
|
28
|
+
# op1 = SymbolOperator.new(:hello1, "==")
|
29
|
+
# op2 = SymbolOperator.new(:hello2, "==")
|
30
|
+
# refute_equal op1, op2
|
31
|
+
#
|
32
|
+
# op1 = SymbolOperator.new(:hello, "!=")
|
33
|
+
# op2 = SymbolOperator.new(:hello, "==")
|
34
|
+
# refute_equal op1, op2
|
35
|
+
# end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: garb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Pitale
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2010-01-14 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -49,7 +49,6 @@ files:
|
|
49
49
|
- lib/garb/data_request.rb
|
50
50
|
- lib/garb/filter_parameters.rb
|
51
51
|
- lib/garb/oauth_session.rb
|
52
|
-
- lib/garb/operator.rb
|
53
52
|
- lib/garb/profile.rb
|
54
53
|
- lib/garb/profile_array.rb
|
55
54
|
- lib/garb/report.rb
|
@@ -59,6 +58,7 @@ files:
|
|
59
58
|
- lib/garb/session.rb
|
60
59
|
- lib/garb/version.rb
|
61
60
|
- lib/garb.rb
|
61
|
+
- lib/support.rb
|
62
62
|
- test/fixtures/cacert.pem
|
63
63
|
- test/fixtures/profile_feed.xml
|
64
64
|
- test/fixtures/report_feed.xml
|
@@ -68,7 +68,6 @@ files:
|
|
68
68
|
- test/unit/garb/data_request_test.rb
|
69
69
|
- test/unit/garb/filter_parameters_test.rb
|
70
70
|
- test/unit/garb/oauth_session_test.rb
|
71
|
-
- test/unit/garb/operator_test.rb
|
72
71
|
- test/unit/garb/profile_test.rb
|
73
72
|
- test/unit/garb/report_parameter_test.rb
|
74
73
|
- test/unit/garb/report_response_test.rb
|
@@ -76,7 +75,8 @@ files:
|
|
76
75
|
- test/unit/garb/resource_test.rb
|
77
76
|
- test/unit/garb/session_test.rb
|
78
77
|
- test/unit/garb_test.rb
|
79
|
-
|
78
|
+
- test/unit/symbol_operator_test.rb
|
79
|
+
has_rdoc: false
|
80
80
|
homepage: http://github.com/vigetlabs/garb
|
81
81
|
licenses: []
|
82
82
|
|
@@ -114,7 +114,6 @@ test_files:
|
|
114
114
|
- test/unit/garb/data_request_test.rb
|
115
115
|
- test/unit/garb/filter_parameters_test.rb
|
116
116
|
- test/unit/garb/oauth_session_test.rb
|
117
|
-
- test/unit/garb/operator_test.rb
|
118
117
|
- test/unit/garb/profile_test.rb
|
119
118
|
- test/unit/garb/report_parameter_test.rb
|
120
119
|
- test/unit/garb/report_response_test.rb
|
@@ -122,3 +121,4 @@ test_files:
|
|
122
121
|
- test/unit/garb/resource_test.rb
|
123
122
|
- test/unit/garb/session_test.rb
|
124
123
|
- test/unit/garb_test.rb
|
124
|
+
- test/unit/symbol_operator_test.rb
|
data/lib/garb/operator.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# Concept from dm-core
|
2
|
-
module Garb
|
3
|
-
class Operator
|
4
|
-
attr_reader :target, :operator, :prefix
|
5
|
-
|
6
|
-
def initialize(target, operator, prefix=false)
|
7
|
-
@target = Garb.to_google_analytics(target)
|
8
|
-
@operator = operator
|
9
|
-
@prefix = prefix
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_google_analytics
|
13
|
-
@prefix ? "#{operator}#{target}" : "#{target}#{operator}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def ==(rhs)
|
17
|
-
target == rhs.target &&
|
18
|
-
operator == rhs.operator &&
|
19
|
-
prefix == rhs.prefix
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
|
2
|
-
|
3
|
-
module Garb
|
4
|
-
class OperatorTest < MiniTest::Unit::TestCase
|
5
|
-
context "An instance of an Operator" do
|
6
|
-
should "lower camelize the target" do
|
7
|
-
assert_equal "ga:uniqueVisits=", Operator.new(:unique_visits, "=").to_google_analytics
|
8
|
-
end
|
9
|
-
|
10
|
-
should "return target and operator together" do
|
11
|
-
assert_equal "ga:metric=", Operator.new(:metric, "=").to_google_analytics
|
12
|
-
end
|
13
|
-
|
14
|
-
should "prefix the operator to the target" do
|
15
|
-
assert_equal "-ga:metric", Operator.new(:metric, "-", true).to_google_analytics
|
16
|
-
end
|
17
|
-
|
18
|
-
should "know if it is equal to another operator" do
|
19
|
-
op1 = Operator.new(:hello, "==")
|
20
|
-
op2 = Operator.new(:hello, "==")
|
21
|
-
assert_equal op1, op2
|
22
|
-
end
|
23
|
-
|
24
|
-
should "not be equal to another operator if target, operator, or prefix is different" do
|
25
|
-
op1 = Operator.new(:hello, "==")
|
26
|
-
op2 = Operator.new(:hello, "==", true)
|
27
|
-
refute_equal op1, op2
|
28
|
-
|
29
|
-
op1 = Operator.new(:hello1, "==")
|
30
|
-
op2 = Operator.new(:hello2, "==")
|
31
|
-
refute_equal op1, op2
|
32
|
-
|
33
|
-
op1 = Operator.new(:hello, "!=")
|
34
|
-
op2 = Operator.new(:hello, "==")
|
35
|
-
refute_equal op1, op2
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|