google_api 1.0.0.beta

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.
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task :default => :spec
9
+ task :test => :spec
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/google_api/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ondřej Moravčík"]
6
+ gem.email = ["moravcik.ondrej@gmail.com"]
7
+ gem.description = %q{Simple Google Api. Include google analytics.}
8
+ gem.summary = %q{Simple Google Api. Include google analytics.}
9
+ gem.homepage = "https://github.com/ondra-m/google_api"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "google_api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = GoogleApi::VERSION
17
+
18
+ gem.add_dependency 'google-api-client'
19
+
20
+ gem.add_development_dependency 'rake'
21
+ gem.add_development_dependency 'rspec'
22
+ end
@@ -0,0 +1,37 @@
1
+ require "google/api_client"
2
+
3
+ require "google_api/core_ext/hash"
4
+ require "google_api/configuration"
5
+ require "google_api/version"
6
+
7
+ module GoogleApi
8
+
9
+ autoload :Cache, 'google_api/cache'
10
+
11
+ autoload :Ga, 'google_api/ga'
12
+
13
+ class SessionError < StandardError; end
14
+ class GaError < StandardError; end
15
+ class DateError < StandardError; end
16
+ class TypeError < StandardError; end
17
+
18
+ CONFIGURATION = {
19
+ client_id: nil,
20
+ client_secret: nil,
21
+ client_developer_email: nil,
22
+ client_cert_file: nil,
23
+ key_secret: 'notasecret',
24
+ redirect_uri: nil,
25
+
26
+ ga: Configuration.new(Ga::CONFIGURATION)
27
+ }
28
+
29
+ def self.config
30
+ @config ||= Configuration.new(CONFIGURATION)
31
+ end
32
+
33
+ def self.configure(&block)
34
+ config.instance_eval(&block)
35
+ end
36
+
37
+ end
@@ -0,0 +1,49 @@
1
+ module GoogleApi
2
+ class Cache
3
+
4
+ def initialize
5
+ @cache = {}
6
+ end
7
+
8
+ def write(key, value, expire = 0)
9
+ expire = expire == 0 ? 0 : Time.now + (expire * 60)
10
+
11
+ @cache[key] = [value, expire]
12
+ end
13
+
14
+ def read(key)
15
+ if exists?(key)
16
+ return @cache[key][0]
17
+ end
18
+
19
+ nil
20
+ end
21
+
22
+ def exists?(key)
23
+ @cache.has_key?(key) && !expire?(key)
24
+ end
25
+
26
+ def delete(key)
27
+ @cache.delete(key)
28
+ end
29
+
30
+ private
31
+
32
+ def expire?(key)
33
+ expire = @cache[key][1]
34
+
35
+ if expire == 0
36
+ return false
37
+ end
38
+
39
+ if expire < Time.now
40
+ delete(key)
41
+
42
+ return true
43
+ end
44
+
45
+ false
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ module GoogleApi
2
+ class Configuration
3
+
4
+ def initialize(config = {})
5
+ config.each do |key, value|
6
+ eval <<-METHOD
7
+ def #{key}=(value)
8
+ @#{key} = value
9
+ end
10
+
11
+ def #{key}(value = nil, &block)
12
+ if block_given?
13
+ @#{key}.instance_eval(&block)
14
+ end
15
+
16
+ if value.nil?
17
+ return @#{key}
18
+ end
19
+
20
+ self.#{key} = value
21
+ end
22
+ METHOD
23
+
24
+ self.send("#{key}=", value)
25
+ end
26
+ end
27
+
28
+ def configure(&block)
29
+ if block_given?
30
+ yield self
31
+ end
32
+
33
+ self
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ unless Hash.new.respond_to?(:symbolize_keys!)
2
+ class Hash
3
+ def symbolize_keys!
4
+ keys.each do |key|
5
+ self[(key.to_sym rescue key) || key] = delete(key)
6
+ end
7
+
8
+ self
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+ def red
3
+ "\033[31m#{self}\033[0m"
4
+ end
5
+
6
+ def green
7
+ "\033[32m#{self}\033[0m"
8
+ end
9
+
10
+ def bold
11
+ "\033[1m#{self}\033[0m"
12
+ end
13
+ end
@@ -0,0 +1,59 @@
1
+ require "date"
2
+
3
+ module GoogleApi
4
+ module Date
5
+
6
+ DATE_FORMAT = /\A[0-9]{4}-[0-9]{2}-[0-9]{2}\Z/
7
+
8
+ def to_date(date)
9
+ if date.is_a?(String)
10
+ unless date =~ DATE_FORMAT
11
+ raise GoogleApi::DateError, "Date: #{date} must match with #{DATE_FORMAT}."
12
+ end
13
+
14
+ date = Date.parse(date)
15
+ end
16
+
17
+
18
+ date.to_date
19
+ end
20
+
21
+ def now
22
+ Date.today
23
+ end
24
+
25
+ def prev_month
26
+ Date.today.prev_month
27
+ end
28
+
29
+ def more_months?(d1, d2)
30
+
31
+ d1 = Date.parse(d1) if d1.is_a?(String)
32
+ d2 = Date.parse(d2) if d2.is_a?(String)
33
+
34
+ d1.month != d2.month
35
+ end
36
+
37
+ def more_years?(d1, d2)
38
+
39
+ d1 = Date.parse(d1) if d1.is_a?(String)
40
+ d2 = Date.parse(d2) if d2.is_a?(String)
41
+
42
+ d1.year != d2.year
43
+ end
44
+
45
+ def day_older?(date)
46
+
47
+ if date.is_a?(String)
48
+ date = Date.parse(date)
49
+ end
50
+
51
+ if (Date.today <=> date.to_date) > 0
52
+ return true
53
+ end
54
+
55
+ return false
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,52 @@
1
+ module GoogleApi
2
+ module Ga
3
+
4
+ CONFIGURATION = {
5
+ client_id: nil,
6
+ client_secret: nil,
7
+ client_developer_email: nil,
8
+ client_cert_file: nil,
9
+ key_secret: 'notasecret',
10
+ redirect_uri: nil,
11
+
12
+ cache: GoogleApi::Cache.new
13
+ }
14
+
15
+ # Session
16
+ autoload :Session, 'google_api/ga/session'
17
+
18
+ # Management
19
+ autoload :Management, 'google_api/ga/management/management'
20
+ autoload :Account, 'google_api/ga/management/account'
21
+ autoload :Webproperty, 'google_api/ga/management/webproperty'
22
+ autoload :Profile, 'google_api/ga/management/profile'
23
+ autoload :Goal, 'google_api/ga/management/goal'
24
+ autoload :Segment, 'google_api/ga/management/segment'
25
+
26
+ # Helper
27
+ autoload :Helper, 'google_api/ga/helper'
28
+
29
+ # Data
30
+ autoload :Data, 'google_api/ga/data'
31
+ autoload :DataDsl, 'google_api/ga/data/data_dsl'
32
+ autoload :FiltersDsl, 'google_api/ga/data/filters_dsl'
33
+ autoload :SegmentDsl, 'google_api/ga/data/segment_dsl'
34
+
35
+ extend GoogleApi::Ga::Helper
36
+
37
+ @@id = 0
38
+
39
+ def self.id(id=nil)
40
+ if id.nil?
41
+ return @@id
42
+ end
43
+
44
+ @@id = id.to_i
45
+ end
46
+
47
+ def self.cache
48
+ GoogleApi.config.ga.cache
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,335 @@
1
+ module GoogleApi
2
+ module Ga
3
+ class Data
4
+
5
+ def initialize
6
+ @ids, @cache = nil, nil
7
+ @start_date, @end_date = Date.today, Date.today
8
+ @metrics, @dimensions, @sort = [], [], []
9
+ @filters, @segment = nil, nil
10
+ @start_index, @max_results = nil, nil
11
+ end
12
+
13
+ # Auto initialize data
14
+ def self.method_missing(method, *args, &block)
15
+ if block_given?
16
+ new.send(method, &block)
17
+ else
18
+ new.send(method, *args)
19
+ end
20
+ end
21
+
22
+ # Convert string, DateTime and Time to date
23
+ DATE_FORMAT = /\A[0-9]{4}-[0-9]{2}-[0-9]{2}\Z/
24
+
25
+ def to_date(date)
26
+ if date.is_a?(String)
27
+ unless date =~ DATE_FORMAT
28
+ raise GoogleApi::DateError, "Date: #{date} must match with #{DATE_FORMAT}."
29
+ end
30
+
31
+ date = Date.parse(date)
32
+ end
33
+
34
+ date.to_date
35
+ end
36
+
37
+ # Add prefix ga: to symbol in Array
38
+ def build_param(value)
39
+ type?(value, Array)
40
+
41
+ value.flatten.collect { |v| v.is_a?(Symbol) ? "ga:#{v}" : v }
42
+ end
43
+
44
+ # Check type
45
+ def type?(value, type)
46
+ unless value.is_a?(type)
47
+ raise GoogleApi::TypeError, "Value: #{value} must be #{type}."
48
+ end
49
+ end
50
+
51
+ # Clear value
52
+ def clear
53
+ @header = nil
54
+ @parameters = nil
55
+ @data = nil
56
+ @all = nil
57
+ end
58
+
59
+ # -----------------------------------------------------------------------------------
60
+ # Type 1, all are integer
61
+ #
62
+ # Ids, Cache, Start index, Max results
63
+ #
64
+ # name, alias
65
+ #
66
+ TYPE_1 = { ids: :id,
67
+ cache: nil,
68
+ start_index: :offset,
69
+ max_results: :limit }
70
+
71
+ TYPE_1.each do |key, value|
72
+ eval <<-METHOD
73
+ def #{key}(value = nil)
74
+ if value.nil?
75
+ return @#{key}
76
+ end
77
+
78
+ self.#{key} = value
79
+ self
80
+ end
81
+
82
+ def #{key}=(value)
83
+ type?(value, Integer)
84
+
85
+ @#{key} = value
86
+ end
87
+ METHOD
88
+
89
+ unless value.nil?
90
+ eval <<-METHOD
91
+ alias :#{value} :#{key}
92
+ alias :#{value}= :#{key}=
93
+ METHOD
94
+ end
95
+ end
96
+
97
+ # -----------------------------------------------------------------------------------
98
+ # Type 2, date
99
+ #
100
+ # Start date, End date
101
+ #
102
+ # name, alias
103
+ #
104
+ TYPE_2 = { start_date: :from,
105
+ end_date: :to }
106
+
107
+ TYPE_2.each do |key, value|
108
+ eval <<-METHOD
109
+ def #{key}(date = nil)
110
+ if date.nil?
111
+ return @#{key}
112
+ end
113
+
114
+ self.#{key} = date
115
+ self
116
+ end
117
+
118
+ def #{key}=(date)
119
+ if date.is_a?(Integer)
120
+ @#{key} += date
121
+ else
122
+ @#{key} = to_date(date)
123
+ end
124
+ end
125
+ METHOD
126
+
127
+ unless value.nil?
128
+ eval <<-METHOD
129
+ alias :#{value} :#{key}
130
+ alias :#{value}= :#{key}=
131
+ METHOD
132
+ end
133
+ end
134
+
135
+ # -----------------------------------------------------------------------------------
136
+ # Type 3
137
+ #
138
+ # Metrics, Dimensions, Sort
139
+ #
140
+ # name, alias
141
+ #
142
+ TYPE_3 = { metrics: :select,
143
+ dimensions: :with,
144
+ sort: nil }
145
+
146
+ TYPE_3.each do |key, value|
147
+ eval <<-METHOD
148
+ def #{key}(*args)
149
+ if args.size == 0
150
+ return @#{key}
151
+ end
152
+
153
+ self.#{key} = args
154
+ self
155
+ end
156
+
157
+ def #{key}=(value)
158
+ clear
159
+ @#{key} = build_param(value)
160
+ end
161
+
162
+ def #{key}_add(*args)
163
+ if args.size == 0
164
+ return @#{key}
165
+ end
166
+
167
+ self.#{key}_add = args
168
+ self
169
+ end
170
+
171
+ def #{key}_add=(value)
172
+ clear
173
+ @#{key} += build_param(value)
174
+ end
175
+
176
+ def #{key}_sub(*args)
177
+ if args.size == 0
178
+ return @#{key}
179
+ end
180
+
181
+ self.#{key}_sub = args
182
+ self
183
+ end
184
+
185
+ def #{key}_sub=(value)
186
+ clear
187
+ @#{key} -= build_param(value)
188
+ end
189
+ METHOD
190
+
191
+ unless value.nil?
192
+ eval <<-METHOD
193
+ alias :#{value} :#{key}
194
+ alias :#{value}= :#{key}=
195
+
196
+ alias :#{value}_add :#{key}_add
197
+ alias :#{value}_add= :#{key}_add=
198
+
199
+ alias :#{value}_sub :#{key}_sub
200
+ alias :#{value}_sub= :#{key}_sub=
201
+ METHOD
202
+ end
203
+ end
204
+
205
+ # -----------------------------------------------------------------------------------
206
+ # Type 4
207
+ #
208
+ # Filters, Segment
209
+ #
210
+ # name, alias
211
+ #
212
+ TYPE_4 = { filters: :where,
213
+ segment: nil }
214
+
215
+ TYPE_4.each do |key, value|
216
+ eval <<-METHOD
217
+ def #{key}(value = nil, &block)
218
+ if !block_given? && value.nil?
219
+ return @#{key}
220
+ end
221
+
222
+ if block_given?
223
+ @#{key} = #{key.to_s.capitalize}Dsl.new.instance_eval(&block).join
224
+ else
225
+ @#{key} = value
226
+ end
227
+ self
228
+ end
229
+ METHOD
230
+
231
+ unless value.nil?
232
+ eval <<-METHOD
233
+ alias :#{value} :#{key}
234
+ METHOD
235
+ end
236
+ end
237
+
238
+ # Add row!, header!, all!, count!. First clear and run method .
239
+ [:rows, :header, :all, :count].each do |value|
240
+ eval <<-METHOD
241
+ def #{value}!
242
+ clear
243
+ #{value}
244
+ end
245
+ METHOD
246
+ end
247
+
248
+ def rows
249
+ data.rows
250
+ end
251
+
252
+ def header
253
+ @header ||= data.column_headers.map { |c| c.name }
254
+ end
255
+
256
+ def count
257
+ data.total_results
258
+ end
259
+
260
+ def all
261
+ @all ||= [header, rows]
262
+ end
263
+
264
+ def each(&block)
265
+ if block.arity == 1 # each
266
+ rows.each do |row|
267
+ yield(row)
268
+ end
269
+ else # each with index
270
+ i = -1
271
+ rows.each do |row|
272
+ i += 1
273
+ yield(i, row)
274
+ end
275
+ end
276
+ end
277
+
278
+ def each!(&block)
279
+ clear
280
+ each(block)
281
+ end
282
+
283
+ private
284
+
285
+ def data
286
+ @data ||= get.data
287
+ end
288
+
289
+ def parameters
290
+ return @parameters if @parameters
291
+
292
+ if @ids.nil?
293
+ self.ids = Ga.id
294
+ end
295
+
296
+ @parameters = {}
297
+
298
+ @parameters['ids'] = "ga:#{@ids}"
299
+ @parameters['start-date'] = @start_date.to_s
300
+ @parameters['end-date'] = @end_date.to_s
301
+ @parameters['metrics'] = @metrics.join(',')
302
+
303
+ @parameters['dimensions'] = @dimensions.join(',') unless @dimensions.empty?
304
+ @parameters['sort'] = @sort.join(',') unless @sort.empty?
305
+ @parameters['filters'] = @filters unless @filters.nil?
306
+ @parameters['start-index'] = @start_index unless @start_index.nil?
307
+ @parameters['max-results'] = @max_results unless @max_results.nil?
308
+
309
+ @parameters
310
+ end
311
+
312
+ def _cache
313
+ GoogleApi::Ga.cache
314
+ end
315
+
316
+ def _session
317
+ Session
318
+ end
319
+
320
+ def get
321
+ if @cache && _cache.exists?(parameters)
322
+ return _cache.read(parameters)
323
+ end
324
+
325
+ result = _session.client.execute( api_method: _session.api.data.ga.get,
326
+ parameters: parameters )
327
+
328
+ _cache.write(parameters, result, @cache) if @cache.is_a?(Integer)
329
+
330
+ result
331
+ end
332
+
333
+ end
334
+ end
335
+ end