google_api 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -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