garb 0.9.1 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +95 -0
- data/Gemfile +15 -0
- data/README.md +47 -25
- data/Rakefile +8 -34
- data/garb.gemspec +22 -0
- data/lib/garb.rb +71 -48
- data/lib/garb/attributes.rb +35 -0
- data/lib/garb/core_ext/array.rb +13 -0
- data/lib/garb/core_ext/string.rb +48 -0
- data/lib/garb/core_ext/symbol.rb +59 -0
- data/lib/garb/destination.rb +5 -6
- data/lib/garb/errors.rb +20 -0
- data/lib/garb/filter_parameters.rb +20 -29
- data/lib/garb/management/account.rb +10 -16
- data/lib/garb/management/feed.rb +4 -5
- data/lib/garb/management/goal.rb +10 -15
- data/lib/garb/management/profile.rb +11 -20
- data/lib/garb/management/segment.rb +9 -15
- data/lib/garb/management/web_property.rb +11 -16
- data/lib/garb/model.rb +37 -13
- data/lib/garb/path_attribute.rb +7 -0
- data/lib/garb/report_parameter.rb +5 -5
- data/lib/garb/report_response.rb +29 -28
- data/lib/garb/reports/bounces.rb +1 -1
- data/lib/garb/reports/exits.rb +1 -1
- data/lib/garb/reports/pageviews.rb +1 -1
- data/lib/garb/reports/unique_pageviews.rb +1 -1
- data/lib/garb/reports/visits.rb +1 -1
- data/lib/garb/request/authentication.rb +54 -0
- data/lib/garb/request/data.rb +98 -0
- data/lib/garb/result_set.rb +23 -9
- data/lib/garb/session.rb +3 -3
- data/lib/garb/step.rb +4 -4
- data/lib/garb/support.rb +6 -0
- data/lib/garb/version.rb +3 -3
- data/test/fixtures/account_management.json +1 -0
- data/test/fixtures/ga_profile_management.json +1 -0
- data/test/fixtures/ga_segment_management.json +1 -0
- data/test/fixtures/ga_webproperty_management.json +1 -0
- data/test/fixtures/goal_management.json +1 -0
- data/test/fixtures/profile_feed.json +1 -0
- data/test/fixtures/report_feed.json +75 -0
- data/test/test_helper.rb +6 -10
- data/test/unit/garb/filter_parameters_test.rb +15 -46
- data/test/unit/garb/management/account_test.rb +8 -16
- data/test/unit/garb/management/feed_test.rb +5 -10
- data/test/unit/garb/management/goal_test.rb +7 -21
- data/test/unit/garb/management/profile_test.rb +11 -26
- data/test/unit/garb/management/segment_test.rb +7 -6
- data/test/unit/garb/management/web_property_test.rb +10 -12
- data/test/unit/garb/model_test.rb +70 -32
- data/test/unit/garb/report_parameter_test.rb +6 -6
- data/test/unit/garb/report_response_test.rb +23 -13
- data/test/unit/garb/request/authentication_test.rb +152 -0
- data/test/unit/garb/request/data_test.rb +157 -0
- data/test/unit/garb/session_test.rb +13 -13
- data/test/unit/garb_test.rb +4 -11
- data/test/unit/symbol_operator_test.rb +3 -3
- metadata +90 -292
- data/lib/garb/account.rb +0 -22
- data/lib/garb/account_feed_request.rb +0 -25
- data/lib/garb/authentication_request.rb +0 -53
- data/lib/garb/data_request.rb +0 -42
- data/lib/garb/goal.rb +0 -20
- data/lib/garb/profile.rb +0 -33
- data/lib/garb/report.rb +0 -28
- data/lib/garb/resource.rb +0 -115
- data/lib/support.rb +0 -40
- data/test/unit/garb/account_feed_request_test.rb +0 -42
- data/test/unit/garb/account_test.rb +0 -53
- data/test/unit/garb/authentication_request_test.rb +0 -121
- data/test/unit/garb/coverage/assets/0.3.9/app.js +0 -66
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/test/unit/garb/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/test/unit/garb/coverage/assets/0.3.9/favicon.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
- data/test/unit/garb/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
- data/test/unit/garb/coverage/assets/0.3.9/jquery.timeago.js +0 -141
- data/test/unit/garb/coverage/assets/0.3.9/jquery.url.js +0 -174
- data/test/unit/garb/coverage/assets/0.3.9/loading.gif +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/magnify.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/test/unit/garb/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/test/unit/garb/coverage/assets/0.3.9/stylesheet.css +0 -341
- data/test/unit/garb/coverage/index.html +0 -100
- data/test/unit/garb/coverage/resultset.yml +0 -5
- data/test/unit/garb/data_request_test.rb +0 -107
- data/test/unit/garb/destination_test.rb +0 -28
- data/test/unit/garb/goal_test.rb +0 -24
- data/test/unit/garb/management/coverage/assets/0.3.9/app.js +0 -66
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/blank.gif +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_close.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_loading.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_left.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_nav_right.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_e.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_n.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_ne.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_nw.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_s.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_se.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_sw.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_shadow_w.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_left.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_main.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_over.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancy_title_right.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-x.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox-y.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/fancybox.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/test/unit/garb/management/coverage/assets/0.3.9/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/test/unit/garb/management/coverage/assets/0.3.9/favicon.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/jquery-1.4.2.min.js +0 -155
- data/test/unit/garb/management/coverage/assets/0.3.9/jquery.dataTables.min.js +0 -152
- data/test/unit/garb/management/coverage/assets/0.3.9/jquery.timeago.js +0 -141
- data/test/unit/garb/management/coverage/assets/0.3.9/jquery.url.js +0 -174
- data/test/unit/garb/management/coverage/assets/0.3.9/loading.gif +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/magnify.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/test/unit/garb/management/coverage/assets/0.3.9/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/test/unit/garb/management/coverage/assets/0.3.9/stylesheet.css +0 -341
- data/test/unit/garb/management/coverage/index.html +0 -100
- data/test/unit/garb/management/coverage/resultset.yml +0 -5
- data/test/unit/garb/profile_test.rb +0 -77
- data/test/unit/garb/report_test.rb +0 -99
- data/test/unit/garb/resource_test.rb +0 -50
- data/test/unit/garb/step_test.rb +0 -15
@@ -0,0 +1,35 @@
|
|
1
|
+
module Garb
|
2
|
+
module Attributes
|
3
|
+
def self.extended(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def ga_attribute(*keys)
|
9
|
+
hashes, symbols = keys.partition { |k| k.is_a? Hash }
|
10
|
+
symbols.each { |key| define_a_method_for key }
|
11
|
+
hashes.each { |hash| map_values_for hash }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def define_a_method_for(key, custom_key = nil)
|
16
|
+
custom_key ||= key.to_s.camelize(:lower)
|
17
|
+
define_method(key) do
|
18
|
+
var = "@#{key}"
|
19
|
+
if instance_variable_defined? var
|
20
|
+
instance_variable_get var
|
21
|
+
else
|
22
|
+
hash_key = (custom_key || key).to_s
|
23
|
+
instance_variable_set var, @entry[hash_key]
|
24
|
+
end
|
25
|
+
end #unless method_defined?(key)
|
26
|
+
end
|
27
|
+
|
28
|
+
def map_values_for(hash)
|
29
|
+
hash.each_pair do |key, value|
|
30
|
+
define_a_method_for key, value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Pull in some AS String utilities (not loaded if AS is available)
|
2
|
+
unless Object.const_defined?('ActiveSupport')
|
3
|
+
class String
|
4
|
+
def camelize(first_letter = :upper)
|
5
|
+
case first_letter
|
6
|
+
when :upper then Garb::Inflector.camelize(self, true)
|
7
|
+
when :lower then Garb::Inflector.camelize(self, false)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
alias_method :camelcase, :camelize
|
11
|
+
|
12
|
+
def underscore
|
13
|
+
Garb::Inflector.underscore(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def demodulize
|
17
|
+
Garb::Inflector.demodulize(self)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Garb
|
22
|
+
module Inflector
|
23
|
+
extend self
|
24
|
+
|
25
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
26
|
+
if first_letter_in_uppercase
|
27
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
28
|
+
else
|
29
|
+
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def underscore(camel_cased_word)
|
34
|
+
word = camel_cased_word.to_s.dup
|
35
|
+
word.gsub!(/::/, '/')
|
36
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
37
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
38
|
+
word.tr!("-", "_")
|
39
|
+
word.downcase!
|
40
|
+
word
|
41
|
+
end
|
42
|
+
|
43
|
+
def demodulize(class_name_in_module)
|
44
|
+
class_name_in_module.to_s.gsub(/^.*::/, '')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SymbolOperatorMethods
|
2
|
+
OPERATORS = {
|
3
|
+
:eql => '==',
|
4
|
+
:not_eql => '!=',
|
5
|
+
:gt => '>',
|
6
|
+
:gte => '>=',
|
7
|
+
:lt => '<',
|
8
|
+
:lte => '<=',
|
9
|
+
:matches => '==',
|
10
|
+
|
11
|
+
:does_not_match => '!=',
|
12
|
+
:contains => '=~',
|
13
|
+
:does_not_contain => '!~',
|
14
|
+
:substring => '=@',
|
15
|
+
:not_substring => '!@',
|
16
|
+
|
17
|
+
:desc => '-',
|
18
|
+
:descending => '-'
|
19
|
+
}
|
20
|
+
SLUGS = OPERATORS.keys.freeze
|
21
|
+
|
22
|
+
def to_google_analytics
|
23
|
+
t = Garb.to_google_analytics @field || @target
|
24
|
+
o = OPERATORS[@operator]
|
25
|
+
|
26
|
+
[:desc, :descending].include?(@operator) ? "#{o}#{t}" : "#{t}#{o}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class SymbolOperator
|
31
|
+
include SymbolOperatorMethods
|
32
|
+
|
33
|
+
def initialize(field, operator)
|
34
|
+
@field, @operator = field, operator
|
35
|
+
end unless method_defined? :initialize
|
36
|
+
end
|
37
|
+
|
38
|
+
symbol_slugs = if Object.const_defined?('DataMapper')
|
39
|
+
# make sure the class is defined
|
40
|
+
require 'dm-core/core_ext/symbol'
|
41
|
+
|
42
|
+
# add to_google_analytics to DM's Opeartor
|
43
|
+
class DataMapper::Query::Operator
|
44
|
+
include SymbolOperatorMethods
|
45
|
+
end
|
46
|
+
|
47
|
+
SymbolOperatorMethods::SLUGS - DataMapper::Query::Conditions::Comparison.slugs
|
48
|
+
else
|
49
|
+
SymbolOperatorMethods::SLUGS
|
50
|
+
end
|
51
|
+
|
52
|
+
# define the remaining symbol operators
|
53
|
+
symbol_slugs.each do |operator|
|
54
|
+
Symbol.class_eval <<-RUBY
|
55
|
+
def #{operator}
|
56
|
+
SymbolOperator.new self, :#{operator}
|
57
|
+
end unless method_defined? :#{operator}
|
58
|
+
RUBY
|
59
|
+
end
|
data/lib/garb/destination.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
module Garb
|
2
2
|
class Destination
|
3
|
-
attr_reader :match_type, :
|
3
|
+
attr_reader :match_type, :url, :steps, :case_sensitive
|
4
4
|
|
5
5
|
alias :case_sensitive? :case_sensitive
|
6
6
|
|
7
7
|
def initialize(attributes)
|
8
|
-
return unless attributes.is_a?
|
8
|
+
return unless attributes.is_a? Hash
|
9
9
|
|
10
10
|
@match_type = attributes['matchType']
|
11
|
-
@
|
12
|
-
@case_sensitive =
|
11
|
+
@url = attributes['url'] # TODO was @expression
|
12
|
+
@case_sensitive = attributes['caseSensitive']
|
13
13
|
|
14
|
-
|
15
|
-
@steps = Array(step_attributes.is_a?(Hash) ? [step_attributes] : step_attributes).map {|s| Step.new(s)}
|
14
|
+
@steps = attributes['steps'] && attributes['steps'].map { |s| Step.new(s) }
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
data/lib/garb/errors.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Garb
|
2
|
+
class Error < StandardError; end
|
3
|
+
class MissingCertFileError < Error; end
|
4
|
+
class AuthError < Error; end
|
5
|
+
class ClientError < Error
|
6
|
+
attr_reader :code, :message, :errors, :uri
|
7
|
+
|
8
|
+
def initialize(uri, message, code = nil, errors = [])
|
9
|
+
@code, @message, @errors, @uri = code, message, errors, uri
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"#{code ? "[#{code}] #{message}" : message} : #{uri}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class BadRequestError < ClientError; end
|
17
|
+
class InvalidCredentialsError < ClientError; end
|
18
|
+
class InsufficientPermissionsError < ClientError; end
|
19
|
+
class BackendError < ClientError; end
|
20
|
+
end
|
@@ -1,42 +1,33 @@
|
|
1
1
|
module Garb
|
2
2
|
class FilterParameters
|
3
|
-
def self.define_operators(*methods)
|
4
|
-
methods.each do |method|
|
5
|
-
class_eval <<-CODE
|
6
|
-
def #{method}(field, value)
|
7
|
-
@filter_hash.merge!({SymbolOperator.new(field, :#{method}) => value})
|
8
|
-
end
|
9
|
-
CODE
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
define_operators :eql, :not_eql, :gt, :gte, :lt, :lte, :matches,
|
14
|
-
:does_not_match, :contains, :does_not_contain, :substring, :not_substring
|
15
|
-
|
16
3
|
attr_accessor :parameters
|
17
4
|
|
18
|
-
def initialize
|
19
|
-
self.parameters = []
|
5
|
+
def initialize(parameters)
|
6
|
+
self.parameters = (Array.wrap(parameters) || []).compact
|
20
7
|
end
|
21
8
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
instance_eval &block
|
26
|
-
|
27
|
-
self.parameters << @filter_hash
|
9
|
+
def to_params
|
10
|
+
value = array_to_params(self.parameters)
|
11
|
+
value.empty? ? {} : {'filters' => value}
|
28
12
|
end
|
29
13
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
14
|
+
private
|
15
|
+
def array_to_params(arr)
|
16
|
+
arr.map do |param|
|
17
|
+
case param
|
18
|
+
when Hash then hash_to_params(param)
|
19
|
+
when Array then array_to_params(param)
|
20
|
+
end
|
37
21
|
end.join(',') # Array OR
|
22
|
+
end
|
38
23
|
|
39
|
-
|
24
|
+
def hash_to_params(hsh)
|
25
|
+
hsh.map do |k, v|
|
26
|
+
next unless k.is_a?(SymbolOperatorMethods)
|
27
|
+
|
28
|
+
escaped_v = v.to_s.gsub(/([,;])/) { |c| '\\' + c }
|
29
|
+
"#{URI.encode(k.to_google_analytics, /[=<>]/)}#{CGI::escape(escaped_v)}"
|
30
|
+
end.join('%3B') # Hash AND (no duplicate keys), escape char for ';' fixes oauth
|
40
31
|
end
|
41
32
|
end
|
42
33
|
end
|
@@ -1,26 +1,20 @@
|
|
1
1
|
module Garb
|
2
2
|
module Management
|
3
3
|
class Account
|
4
|
-
|
5
|
-
|
4
|
+
extend Garb::Attributes
|
5
|
+
include PathAttribute
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
feed.entries.map {|entry| new_from_entry(entry, session)}
|
10
|
-
end
|
7
|
+
attr_reader :session
|
8
|
+
ga_attribute :id, :name
|
11
9
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
account.path = Garb.parse_link(entry, "self").gsub(Feed::BASE_URL, '')
|
16
|
-
account.title = entry['title'].gsub('Google Analytics Account ', '') # can we get this in properties=?
|
17
|
-
account.properties = Garb.parse_properties(entry)
|
18
|
-
account
|
10
|
+
def initialize(entry, session)
|
11
|
+
@entry = entry
|
12
|
+
@session = session
|
19
13
|
end
|
20
14
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
15
|
+
def self.all(session = Session)
|
16
|
+
feed = Feed.new(session, '/accounts')
|
17
|
+
feed.entries.map { |entry| new(entry, session) }
|
24
18
|
end
|
25
19
|
|
26
20
|
def web_properties
|
data/lib/garb/management/feed.rb
CHANGED
@@ -1,21 +1,20 @@
|
|
1
1
|
module Garb
|
2
2
|
module Management
|
3
3
|
class Feed
|
4
|
-
BASE_URL =
|
4
|
+
BASE_URL = 'https://www.googleapis.com/analytics/v3/management'
|
5
5
|
|
6
6
|
attr_reader :request
|
7
7
|
|
8
8
|
def initialize(session, path)
|
9
|
-
@request =
|
9
|
+
@request = Request::Data.new(session, BASE_URL + path)
|
10
10
|
end
|
11
11
|
|
12
12
|
def parsed_response
|
13
|
-
@parsed_response ||=
|
13
|
+
@parsed_response ||= MultiJson.load(response.body)
|
14
14
|
end
|
15
15
|
|
16
16
|
def entries
|
17
|
-
|
18
|
-
parsed_response ? [parsed_response['feed']['entry']].flatten.compact : []
|
17
|
+
parsed_response && parsed_response['items'] || []
|
19
18
|
end
|
20
19
|
|
21
20
|
def response
|
data/lib/garb/management/goal.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
module Garb
|
2
2
|
module Management
|
3
3
|
class Goal
|
4
|
+
extend Attributes
|
5
|
+
include PathAttribute
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
attr_reader :session
|
8
|
+
ga_attribute :name, :number, :value, :active
|
7
9
|
|
8
10
|
alias :active? :active
|
9
11
|
|
10
12
|
def self.all(session = Session, path = '/accounts/~all/webproperties/~all/profiles/~all/goals')
|
11
13
|
feed = Feed.new(session, path)
|
12
|
-
feed.entries.map {|entry|
|
14
|
+
feed.entries.map { |entry| new(entry, session) }
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.for_account(account)
|
@@ -24,20 +26,13 @@ module Garb
|
|
24
26
|
all(profile.session, profile.path + '/goals')
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
goal.path = Garb.parse_link(entry, "self").gsub(Feed::BASE_URL, '')
|
31
|
-
goal.properties = entry[Garb.to_ga('goal')]
|
32
|
-
goal
|
29
|
+
def initialize(entry, session)
|
30
|
+
@entry = entry
|
31
|
+
@session = session
|
33
32
|
end
|
34
33
|
|
35
|
-
def
|
36
|
-
|
37
|
-
self.number = properties["number"].to_i
|
38
|
-
self.value = properties["value"].to_f
|
39
|
-
self.active = (properties["active"] == "true")
|
40
|
-
self.destination = Destination.new(properties[Garb.to_ga('destination')])
|
34
|
+
def destination
|
35
|
+
@destination ||= Destination.new(@entry['urlDestinationDetails'])
|
41
36
|
end
|
42
37
|
end
|
43
38
|
end
|
@@ -3,41 +3,32 @@ module Garb
|
|
3
3
|
class Profile
|
4
4
|
|
5
5
|
include ProfileReports
|
6
|
+
include PathAttribute
|
7
|
+
extend Attributes
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
attr_reader :session
|
10
|
+
ga_attribute :id, :name, :account_id, :web_property_id, :website_url
|
9
11
|
|
10
12
|
def self.all(session = Session, path = '/accounts/~all/webproperties/~all/profiles')
|
11
13
|
feed = Feed.new(session, path)
|
12
|
-
feed.entries.map {|entry|
|
14
|
+
feed.entries.map { |entry| new(entry, session) }
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.for_account(account)
|
16
|
-
all(account.session, account.path+'/webproperties/~all/profiles')
|
18
|
+
all(account.session, account.path + '/webproperties/~all/profiles')
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.for_web_property(web_property)
|
20
|
-
all(web_property.session, web_property.path+'/profiles')
|
22
|
+
all(web_property.session, web_property.path + '/profiles')
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
profile.path = Garb.parse_link(entry, "self").gsub(Feed::BASE_URL, '')
|
27
|
-
profile.properties = Garb.parse_properties(entry)
|
28
|
-
profile
|
29
|
-
end
|
30
|
-
|
31
|
-
def properties=(properties)
|
32
|
-
self.id = properties['profile_id']
|
33
|
-
self.table_id = properties['dxp:table_id']
|
34
|
-
self.title = properties['profile_name']
|
35
|
-
self.account_id = properties['account_id']
|
36
|
-
self.web_property_id = properties['web_property_id']
|
25
|
+
def initialize(entry, session)
|
26
|
+
@entry = entry
|
27
|
+
@session = session
|
37
28
|
end
|
38
29
|
|
39
30
|
def goals
|
40
|
-
Goal.for_profile
|
31
|
+
Goal.for_profile self
|
41
32
|
end
|
42
33
|
end
|
43
34
|
end
|
@@ -1,26 +1,20 @@
|
|
1
1
|
module Garb
|
2
2
|
module Management
|
3
3
|
class Segment
|
4
|
-
|
5
|
-
|
4
|
+
extend Attributes
|
5
|
+
include PathAttribute
|
6
|
+
|
7
|
+
attr_reader :session
|
8
|
+
ga_attribute :name, :definition, :id => 'segmentId'
|
6
9
|
|
7
10
|
def self.all(session = Session)
|
8
11
|
feed = Feed.new(session, '/segments')
|
9
|
-
feed.entries.map {|entry|
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.new_from_entry(entry, session)
|
13
|
-
segment = new
|
14
|
-
segment.session = session
|
15
|
-
segment.path = Garb.parse_link(entry, "self").gsub(Feed::BASE_URL, '')
|
16
|
-
segment.properties = entry['dxp:segment']
|
17
|
-
segment
|
12
|
+
feed.entries.map { |entry| new(entry, session) }
|
18
13
|
end
|
19
14
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
self.definition = properties['dxp:definition']
|
15
|
+
def initialize(entry, session)
|
16
|
+
@entry = entry
|
17
|
+
@session = session
|
24
18
|
end
|
25
19
|
end
|
26
20
|
end
|