readmedia-garb 0.9.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/README.md +198 -0
  2. data/Rakefile +57 -0
  3. data/lib/garb/account.rb +22 -0
  4. data/lib/garb/account_feed_request.rb +25 -0
  5. data/lib/garb/authentication_request.rb +53 -0
  6. data/lib/garb/data_request.rb +42 -0
  7. data/lib/garb/destination.rb +18 -0
  8. data/lib/garb/filter_parameters.rb +42 -0
  9. data/lib/garb/goal.rb +20 -0
  10. data/lib/garb/management/account.rb +39 -0
  11. data/lib/garb/management/feed.rb +26 -0
  12. data/lib/garb/management/goal.rb +44 -0
  13. data/lib/garb/management/profile.rb +44 -0
  14. data/lib/garb/management/segment.rb +27 -0
  15. data/lib/garb/management/web_property.rb +38 -0
  16. data/lib/garb/model.rb +91 -0
  17. data/lib/garb/profile.rb +33 -0
  18. data/lib/garb/profile_reports.rb +16 -0
  19. data/lib/garb/report.rb +28 -0
  20. data/lib/garb/report_parameter.rb +25 -0
  21. data/lib/garb/report_response.rb +56 -0
  22. data/lib/garb/reports/bounces.rb +5 -0
  23. data/lib/garb/reports/exits.rb +5 -0
  24. data/lib/garb/reports/pageviews.rb +5 -0
  25. data/lib/garb/reports/unique_pageviews.rb +5 -0
  26. data/lib/garb/reports/visits.rb +5 -0
  27. data/lib/garb/reports.rb +5 -0
  28. data/lib/garb/resource.rb +115 -0
  29. data/lib/garb/result_set.rb +21 -0
  30. data/lib/garb/session.rb +25 -0
  31. data/lib/garb/step.rb +13 -0
  32. data/lib/garb/version.rb +14 -0
  33. data/lib/garb.rb +69 -0
  34. data/lib/support.rb +40 -0
  35. data/test/fixtures/cacert.pem +67 -0
  36. data/test/fixtures/profile_feed.xml +72 -0
  37. data/test/fixtures/report_feed.xml +48 -0
  38. data/test/test_helper.rb +45 -0
  39. data/test/unit/garb/account_feed_request_test.rb +42 -0
  40. data/test/unit/garb/account_test.rb +53 -0
  41. data/test/unit/garb/authentication_request_test.rb +121 -0
  42. data/test/unit/garb/data_request_test.rb +107 -0
  43. data/test/unit/garb/destination_test.rb +28 -0
  44. data/test/unit/garb/filter_parameters_test.rb +68 -0
  45. data/test/unit/garb/goal_test.rb +24 -0
  46. data/test/unit/garb/management/account_test.rb +70 -0
  47. data/test/unit/garb/management/feed_test.rb +44 -0
  48. data/test/unit/garb/management/goal_test.rb +81 -0
  49. data/test/unit/garb/management/profile_test.rb +81 -0
  50. data/test/unit/garb/management/segment_test.rb +47 -0
  51. data/test/unit/garb/management/web_property_test.rb +64 -0
  52. data/test/unit/garb/model_test.rb +141 -0
  53. data/test/unit/garb/oauth_session_test.rb +11 -0
  54. data/test/unit/garb/profile_reports_test.rb +29 -0
  55. data/test/unit/garb/profile_test.rb +77 -0
  56. data/test/unit/garb/report_parameter_test.rb +43 -0
  57. data/test/unit/garb/report_response_test.rb +47 -0
  58. data/test/unit/garb/report_test.rb +99 -0
  59. data/test/unit/garb/resource_test.rb +50 -0
  60. data/test/unit/garb/session_test.rb +84 -0
  61. data/test/unit/garb/step_test.rb +15 -0
  62. data/test/unit/garb_test.rb +26 -0
  63. data/test/unit/symbol_operator_test.rb +37 -0
  64. metadata +189 -0
data/README.md ADDED
@@ -0,0 +1,198 @@
1
+ Garb
2
+ ====
3
+
4
+ Originally forked from: http://github.com/vigetlabs/garb
5
+
6
+ Important Changes
7
+ =================
8
+
9
+ Philip Brocoum (readMedia): Google deprecated their API version 2.3 on
10
+ Thursday, August 23, 2012. Version 2.4 of the API is mostly
11
+ backward-compatible except there are new URL endpoints, which have been
12
+ updated in this release of 0.9.1.1.
13
+
14
+ With The release of version 0.9.0 I have officially deprecated Garb::Report, Garb::Resource,
15
+ Garb::Profile, and Garb::Account. Garb::Report and Garb::Resource should be replaced by Garb::Model.
16
+ Garb::Profile and Garb::Account are supplanted by their Garb::Management::* counterparts.
17
+
18
+ I'll be working hard to update the documentation over the next day or so to highlight all of the
19
+ old features in the new classes, as well as any new features brought by the new classes. If you
20
+ are looking for something in particular, please open an issue and I will try to prioritize these
21
+ requests.
22
+
23
+ Please read CHANGELOG
24
+
25
+ Description
26
+ -----------
27
+
28
+ Provides a Ruby API to the Google Analytics API.
29
+
30
+ http://code.google.com/apis/analytics/docs/gdata/gdataDeveloperGuide.html
31
+
32
+ Basic Usage
33
+ ===========
34
+
35
+ Single User Login
36
+ -----------------
37
+
38
+ > Garb::Session.login(username, password)
39
+
40
+ OAuth Access Token
41
+ ------------------
42
+
43
+ > Garb::Session.access_token = access_token # assign from oauth gem
44
+
45
+ Accounts, WebProperties, Profiles, and Goals
46
+ --------
47
+
48
+ > Garb::Management::Account.all
49
+ > Garb::Management::WebProperty.all
50
+ > Garb::Management::Profile.all
51
+ > Garb::Management::Goal.all
52
+
53
+ Profiles for a UA- Number (a WebProperty)
54
+ --------
55
+
56
+ > profile = Garb::Management::Profile.all.detect {|p| p.web_property_id == 'UA-XXXXXXX-X'}
57
+
58
+ Define a Report Class
59
+ ---------------------
60
+
61
+ class Exits
62
+ extend Garb::Model
63
+
64
+ metrics :exits, :pageviews
65
+ dimensions :page_path
66
+ end
67
+
68
+ Get the Results
69
+ ---------------
70
+
71
+ > Exits.results(profile, :filters => {:page_path.eql => '/'})
72
+
73
+ OR shorthand
74
+
75
+ > profile.exits(:filters => {:page_path.eql => '/'})
76
+
77
+ Be forewarned, these numbers are for the last **30** days and may be slightly different from the numbers displayed in Google Analytics' dashboard for **1 month**.
78
+
79
+ Other Parameters
80
+ ----------------
81
+
82
+ * start_date: The date of the period you would like this report to start
83
+ * end_date: The date to end, inclusive
84
+ * limit: The maximum number of results to be returned
85
+ * offset: The starting index
86
+
87
+ Metrics & Dimensions
88
+ --------------------
89
+
90
+ **Metrics and Dimensions are very complex because of the ways in which they can and cannot be combined.**
91
+
92
+ I suggest reading the google documentation to familiarize yourself with this.
93
+
94
+ http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDimensionsMetrics.html#bounceRate
95
+
96
+ When you've returned, you can pass the appropriate combinations to Garb, as symbols.
97
+
98
+ Filtering
99
+ ---------
100
+
101
+ Google Analytics supports a significant number of filtering options.
102
+
103
+ http://code.google.com/apis/analytics/docs/gdata/gdataReference.html#filtering
104
+
105
+ Here is what we can do currently:
106
+ (the operator is a method on a symbol for the appropriate metric or dimension)
107
+
108
+ Operators on metrics:
109
+
110
+ eql => '==',
111
+ not_eql => '!=',
112
+ gt => '>',
113
+ gte => '>=',
114
+ lt => '<',
115
+ lte => '<='
116
+
117
+ Operators on dimensions:
118
+
119
+ matches => '==',
120
+ does_not_match => '!=',
121
+ contains => '=~',
122
+ does_not_contain => '!~',
123
+ substring => '=@',
124
+ not_substring => '!@'
125
+
126
+ Given the previous Exits example report in shorthand, we can add an option for filter:
127
+
128
+ profile.exits(:filters => {:page_path.eql => '/extend/effectively-using-git-with-subversion/')
129
+
130
+ SSL
131
+ ---
132
+
133
+ Version 0.2.3 includes support for real ssl encryption for SINGLE USER authentication. First do:
134
+
135
+ Garb::Session.login(username, password, :secure => true)
136
+
137
+ Next, be sure to download http://curl.haxx.se/ca/cacert.pem into your application somewhere.
138
+ Then, define a constant CA_CERT_FILE and point to that file.
139
+
140
+ For whatever reason, simply creating a new certificate store and setting the defaults would
141
+ not validate the google ssl certificate as authentic.
142
+
143
+ TODOS
144
+ -----
145
+
146
+ * rebuild AND/OR filtering in Garb::Model
147
+
148
+ Requirements
149
+ ------------
150
+
151
+ * crack >= 0.1.6
152
+ * active_support >= 2.2.0
153
+
154
+ Requirements for Testing
155
+ ------------------------
156
+
157
+ * shoulda
158
+ * jferris-mocha
159
+
160
+ Install
161
+ -------
162
+
163
+ gem install garb
164
+
165
+ Contributors
166
+ ------------
167
+
168
+ Many Thanks, for all their help, goes to:
169
+
170
+ * Patrick Reagan
171
+ * Justin Marney
172
+ * Nick Plante
173
+
174
+ License
175
+ -------
176
+
177
+ (The MIT License)
178
+
179
+ Copyright (c) 2010 Viget Labs
180
+
181
+ Permission is hereby granted, free of charge, to any person obtaining
182
+ a copy of this software and associated documentation files (the
183
+ 'Software'), to deal in the Software without restriction, including
184
+ without limitation the rights to use, copy, modify, merge, publish,
185
+ distribute, sublicense, and/or sell copies of the Software, and to
186
+ permit persons to whom the Software is furnished to do so, subject to
187
+ the following conditions:
188
+
189
+ The above copyright notice and this permission notice shall be
190
+ included in all copies or substantial portions of the Software.
191
+
192
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
193
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
194
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
195
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
196
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
197
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
198
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rake/gempackagetask'
2
+ require 'rake/testtask'
3
+
4
+ $:.unshift File.expand_path('../lib', __FILE__)
5
+ require 'garb'
6
+
7
+ task :default => :test
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'readmedia-garb'
11
+ s.version = Garb::Version.to_s
12
+ s.has_rdoc = false
13
+ s.rubyforge_project = 'readmedia'
14
+ s.summary = "Google Analytics API (v2.4) Ruby Wrapper"
15
+ s.authors = ['Tony Pitale, Philip Brocoum (readMedia)']
16
+ s.email = 'Developer@readMedia.com'
17
+ s.homepage = 'http://github.com/readmedia/garb'
18
+ s.files = %w(README.md Rakefile) + Dir.glob("lib/**/*")
19
+ s.test_files = Dir.glob("test/**/*")
20
+
21
+ s.add_dependency("crack", [">= 0.1.6"])
22
+ s.add_dependency("activesupport", [">= 2.2.0"])
23
+ end
24
+
25
+ Rake::GemPackageTask.new(spec) do |pkg|
26
+ pkg.gem_spec = spec
27
+ end
28
+
29
+ Rake::TestTask.new do |t|
30
+ t.libs << 'test'
31
+ t.test_files = FileList["test/**/*_test.rb"]
32
+ t.verbose = true
33
+ end
34
+
35
+ desc 'Generate the gemspec to serve this Gem from Github'
36
+ task :github do
37
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
38
+ File.open(file, 'w') {|f| f << spec.to_ruby }
39
+ puts "Created gemspec: #{file}"
40
+ end
41
+
42
+ begin
43
+ require 'rcov/rcovtask'
44
+
45
+ desc "Generate RCov coverage report"
46
+ Rcov::RcovTask.new(:rcov) do |t|
47
+ t.libs << "test"
48
+ t.test_files = FileList['test/**/*_test.rb']
49
+ t.rcov_opts << "-x \"test/*,gems/*,/Library/Ruby/*,config/*\" -x lib/garb.rb -x lib/garb/version.rb --rails"
50
+ end
51
+ rescue LoadError
52
+ nil
53
+ end
54
+
55
+ task :default => 'test'
56
+
57
+ # EOF
@@ -0,0 +1,22 @@
1
+ module Garb
2
+ class Account
3
+ attr_reader :id, :name, :profiles
4
+
5
+ def initialize(profiles)
6
+ @id = profiles.first.account_id
7
+ @name = profiles.first.account_name
8
+ @profiles = profiles
9
+ end
10
+
11
+ def self.all(session = Session)
12
+ ActiveSupport::Deprecation.warn("The use of Garb::Account has been deprecated in favor of 'Garb::Management::Account'")
13
+ profiles = {}
14
+
15
+ Profile.all(session).each do |profile|
16
+ (profiles[profile.account_id] ||= []) << profile
17
+ end
18
+
19
+ profiles.map {|k,v| v}.map {|profiles| new(profiles)}
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Garb
2
+ class AccountFeedRequest
3
+ URL = "https://www.google.com/analytics/feeds/accounts/default"
4
+
5
+ def initialize(session = Session)
6
+ @request = DataRequest.new(session, URL)
7
+ end
8
+
9
+ def response
10
+ @response ||= @request.send_request
11
+ end
12
+
13
+ def parsed_response
14
+ @parsed_response ||= Crack::XML.parse(response.body)
15
+ end
16
+
17
+ def entries
18
+ parsed_response ? Array(parsed_response['feed']['entry']).flatten.compact : []
19
+ end
20
+
21
+ def segments
22
+ parsed_response ? Array(parsed_response['feed']['dxp:segment']).flatten.compact : []
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ module Garb
2
+ class AuthenticationRequest
3
+ class AuthError < StandardError;end
4
+
5
+ URL = 'https://www.google.com/accounts/ClientLogin'
6
+
7
+ def initialize(email, password, opts={})
8
+ @email = email
9
+ @password = password
10
+ @account_type = opts.fetch(:account_type, 'HOSTED_OR_GOOGLE')
11
+ end
12
+
13
+ def parameters
14
+ {
15
+ 'Email' => @email,
16
+ 'Passwd' => @password,
17
+ 'accountType' => @account_type,
18
+ 'service' => 'analytics',
19
+ 'source' => 'vigetLabs-garb-001'
20
+ }
21
+ end
22
+
23
+ def uri
24
+ URI.parse(URL)
25
+ end
26
+
27
+ def send_request(ssl_mode)
28
+ http = Net::HTTP.new(uri.host, uri.port)
29
+ http.use_ssl = true
30
+ http.verify_mode = ssl_mode
31
+
32
+ if ssl_mode == OpenSSL::SSL::VERIFY_PEER
33
+ http.ca_file = CA_CERT_FILE
34
+ end
35
+
36
+ http.request(build_request) do |response|
37
+ raise AuthError unless response.is_a?(Net::HTTPOK)
38
+ end
39
+ end
40
+
41
+ def build_request
42
+ post = Net::HTTP::Post.new(uri.path)
43
+ post.set_form_data(parameters)
44
+ post
45
+ end
46
+
47
+ def auth_token(opts={})
48
+ ssl_mode = opts[:secure] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
49
+ send_request(ssl_mode).body.match(/^Auth=(.*)$/)[1]
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,42 @@
1
+ module Garb
2
+ class DataRequest
3
+ class ClientError < StandardError; end
4
+
5
+ def initialize(session, base_url, parameters={})
6
+ @session = session
7
+ @base_url = base_url
8
+ @parameters = parameters
9
+ end
10
+
11
+ def query_string
12
+ parameter_list = @parameters.map {|k,v| "#{k}=#{v}" }
13
+ parameter_list.empty? ? '' : "?#{parameter_list.join('&')}"
14
+ end
15
+
16
+ def uri
17
+ URI.parse(@base_url)
18
+ end
19
+
20
+ def send_request
21
+ response = if @session.single_user?
22
+ single_user_request
23
+ elsif @session.oauth_user?
24
+ oauth_user_request
25
+ end
26
+
27
+ raise ClientError, response.body.inspect unless response.kind_of?(Net::HTTPSuccess)
28
+ response
29
+ end
30
+
31
+ def single_user_request
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+ http.use_ssl = true
34
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
35
+ http.get("#{uri.path}#{query_string}", {'Authorization' => "GoogleLogin auth=#{@session.auth_token}", 'GData-Version' => '2'})
36
+ end
37
+
38
+ def oauth_user_request
39
+ @session.access_token.get("#{uri}#{query_string}", {'GData-Version' => '2'})
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module Garb
2
+ class Destination
3
+ attr_reader :match_type, :expression, :steps, :case_sensitive
4
+
5
+ alias :case_sensitive? :case_sensitive
6
+
7
+ def initialize(attributes)
8
+ return unless attributes.is_a?(Hash)
9
+
10
+ @match_type = attributes['matchType']
11
+ @expression = attributes['expression']
12
+ @case_sensitive = (attributes['caseSensitive'] == 'true')
13
+
14
+ step_attributes = attributes[Garb.to_ga('step')]
15
+ @steps = Array(step_attributes.is_a?(Hash) ? [step_attributes] : step_attributes).map {|s| Step.new(s)}
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Garb
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
+ attr_accessor :parameters
17
+
18
+ def initialize
19
+ self.parameters = []
20
+ end
21
+
22
+ def filters(&block)
23
+ @filter_hash = {}
24
+
25
+ instance_eval &block
26
+
27
+ self.parameters << @filter_hash
28
+ end
29
+
30
+ def to_params
31
+ value = self.parameters.map do |param|
32
+ param.map do |k,v|
33
+ next unless k.is_a?(SymbolOperator)
34
+ escaped_v = v.to_s.gsub(/([,;\\])/) {|c| '\\'+c}
35
+ "#{URI.encode(k.to_google_analytics, /[=<>]/)}#{CGI::escape(escaped_v)}"
36
+ end.join('%3B') # Hash AND (no duplicate keys), escape char for ';' fixes oauth
37
+ end.join(',') # Array OR
38
+
39
+ value.empty? ? {} : {'filters' => value}
40
+ end
41
+ end
42
+ end
data/lib/garb/goal.rb ADDED
@@ -0,0 +1,20 @@
1
+ module Garb
2
+ class Goal
3
+ attr_reader :name, :number, :value, :destination
4
+
5
+ def initialize(attributes={})
6
+ return unless attributes.is_a?(Hash)
7
+
8
+ @name = attributes['name']
9
+ @number = attributes['number'].to_i
10
+ @value = attributes['value'].to_f
11
+ @active = (attributes['active'] == 'true')
12
+
13
+ @destination = Destination.new(attributes[Garb.to_ga('destination')])
14
+ end
15
+
16
+ def active?
17
+ @active
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ module Garb
2
+ module Management
3
+ class Account
4
+ attr_accessor :session, :path
5
+ attr_accessor :id, :title, :name
6
+
7
+ def self.all(session = Session)
8
+ feed = Feed.new(session, '/accounts')
9
+ feed.entries.map {|entry| new_from_entry(entry, session)}
10
+ end
11
+
12
+ def self.new_from_entry(entry, session)
13
+ account = new
14
+ account.session = session
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
19
+ end
20
+
21
+ def properties=(properties)
22
+ self.id = properties["account_id"]
23
+ self.name = properties["account_name"]
24
+ end
25
+
26
+ def web_properties
27
+ @web_properties ||= WebProperty.for_account(self)
28
+ end
29
+
30
+ def profiles
31
+ @profiles ||= Profile.for_account(self)
32
+ end
33
+
34
+ def goals
35
+ @goals ||= Goal.for_account(self)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ module Garb
2
+ module Management
3
+ class Feed
4
+ BASE_URL = "https://www.google.com/analytics/feeds/datasources/ga"
5
+
6
+ attr_reader :request
7
+
8
+ def initialize(session, path)
9
+ @request = DataRequest.new(session, BASE_URL+path)
10
+ end
11
+
12
+ def parsed_response
13
+ @parsed_response ||= Crack::XML.parse(response.body)
14
+ end
15
+
16
+ def entries
17
+ # possible to have nil entries, yuck
18
+ parsed_response ? [parsed_response['feed']['entry']].flatten.compact : []
19
+ end
20
+
21
+ def response
22
+ @response ||= request.send_request
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ module Garb
2
+ module Management
3
+ class Goal
4
+
5
+ attr_accessor :session, :path
6
+ attr_accessor :name, :number, :value, :destination, :active
7
+
8
+ alias :active? :active
9
+
10
+ def self.all(session = Session, path = '/accounts/~all/webproperties/~all/profiles/~all/goals')
11
+ feed = Feed.new(session, path)
12
+ feed.entries.map {|entry| new_from_entry(entry, session)}
13
+ end
14
+
15
+ def self.for_account(account)
16
+ all(account.session, account.path + '/webproperties/~all/profiles/~all/goals')
17
+ end
18
+
19
+ def self.for_web_property(web_property)
20
+ all(web_property.session, web_property.path + '/profiles/~all/goals')
21
+ end
22
+
23
+ def self.for_profile(profile)
24
+ all(profile.session, profile.path + '/goals')
25
+ end
26
+
27
+ def self.new_from_entry(entry, session)
28
+ goal = new
29
+ goal.session = session
30
+ goal.path = Garb.parse_link(entry, "self").gsub(Feed::BASE_URL, '')
31
+ goal.properties = entry[Garb.to_ga('goal')]
32
+ goal
33
+ end
34
+
35
+ def properties=(properties)
36
+ self.name = properties["name"]
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')])
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ module Garb
2
+ module Management
3
+ class Profile
4
+
5
+ include ProfileReports
6
+
7
+ attr_accessor :session, :path
8
+ attr_accessor :id, :table_id, :title, :account_id, :web_property_id
9
+
10
+ def self.all(session = Session, path = '/accounts/~all/webproperties/~all/profiles')
11
+ feed = Feed.new(session, path)
12
+ feed.entries.map {|entry| new_from_entry(entry, session)}
13
+ end
14
+
15
+ def self.for_account(account)
16
+ all(account.session, account.path+'/webproperties/~all/profiles')
17
+ end
18
+
19
+ def self.for_web_property(web_property)
20
+ all(web_property.session, web_property.path+'/profiles')
21
+ end
22
+
23
+ def self.new_from_entry(entry, session)
24
+ profile = new
25
+ profile.session = session
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']
37
+ end
38
+
39
+ def goals
40
+ Goal.for_profile(self)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ module Garb
2
+ module Management
3
+ class Segment
4
+ attr_accessor :session, :path
5
+ attr_accessor :id, :name, :definition
6
+
7
+ def self.all(session = Session)
8
+ feed = Feed.new(session, '/segments')
9
+ feed.entries.map {|entry| new_from_entry(entry, session)}
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
18
+ end
19
+
20
+ def properties=(properties)
21
+ self.id = properties['id']
22
+ self.name = properties['name']
23
+ self.definition = properties['dxp:definition']
24
+ end
25
+ end
26
+ end
27
+ end