chrisle-gattica 0.6.3
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/Gemfile +6 -0
- data/Gemfile.lock +21 -0
- data/LICENSE +22 -0
- data/README.md +506 -0
- data/Rakefile +24 -0
- data/VERSION.yml +5 -0
- data/chrisle-gattica.gemspec +68 -0
- data/lib/gattica.rb +35 -0
- data/lib/gattica/account.rb +54 -0
- data/lib/gattica/auth.rb +47 -0
- data/lib/gattica/convertible.rb +39 -0
- data/lib/gattica/data_point.rb +73 -0
- data/lib/gattica/data_set.rb +57 -0
- data/lib/gattica/engine.rb +295 -0
- data/lib/gattica/exceptions.rb +21 -0
- data/lib/gattica/goals.rb +33 -0
- data/lib/gattica/hash_extensions.rb +20 -0
- data/lib/gattica/profiles.rb +33 -0
- data/lib/gattica/segment.rb +17 -0
- data/lib/gattica/settings.rb +34 -0
- data/lib/gattica/user.rb +31 -0
- data/test/helper.rb +14 -0
- data/test/settings.rb +28 -0
- data/test/suite.rb +6 -0
- data/test/test_engine.rb +48 -0
- data/test/test_results.rb +23 -0
- data/test/test_user.rb +24 -0
- metadata +109 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gattica (0.6.1)
|
5
|
+
hpricot
|
6
|
+
test-unit
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
hpricot (0.8.6)
|
12
|
+
test-unit (2.4.5)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
ruby
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
bundler
|
19
|
+
gattica!
|
20
|
+
hpricot
|
21
|
+
test-unit
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2009 Rob Cameron
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,506 @@
|
|
1
|
+
Gattica
|
2
|
+
=======
|
3
|
+
Gattica is an easy to use Gem for getting data from the Google Analytics API.
|
4
|
+
|
5
|
+
Features
|
6
|
+
--------
|
7
|
+
* Supports: metrics, dimensions, sorting, filters, goals, and segments.
|
8
|
+
* Handles accounts with over 1000 profiles
|
9
|
+
* Returns data as: hash, json, CSV
|
10
|
+
|
11
|
+
[How to export Google Analytics data using Ruby](
|
12
|
+
http://www.seerinteractive.com/blog/google-analytics-data-export-api-with-rubygattica/2011/02/22/) (Links to my blog post on [Seer Interactive](http://www.seerinteractive.com))
|
13
|
+
|
14
|
+
<hr />
|
15
|
+
|
16
|
+
Quick Start
|
17
|
+
===========
|
18
|
+
Here are bare basics to get you up and running.
|
19
|
+
|
20
|
+
Installation
|
21
|
+
------------
|
22
|
+
Add Gattica to your Gemfile
|
23
|
+
|
24
|
+
gem 'gattica', :git => 'git://github.com/chrisle/gattica.git'
|
25
|
+
|
26
|
+
Don't forget to bundle install:
|
27
|
+
|
28
|
+
$ bundle install
|
29
|
+
|
30
|
+
Login, get a list of accounts, pick an account, and get data:
|
31
|
+
|
32
|
+
# Include the gem
|
33
|
+
require 'gattica'
|
34
|
+
|
35
|
+
# Login
|
36
|
+
ga = Gattica.new({
|
37
|
+
:email => 'email@gmail.com',
|
38
|
+
:password => 'password'
|
39
|
+
})
|
40
|
+
|
41
|
+
# Get a list of accounts
|
42
|
+
accounts = ga.accounts
|
43
|
+
|
44
|
+
# Choose the first account
|
45
|
+
ga.profile_id = accounts.first.profile_id
|
46
|
+
|
47
|
+
# Get the data
|
48
|
+
data = ga.get({
|
49
|
+
:start_date => '2011-01-01',
|
50
|
+
:end_date => '2011-04-01',
|
51
|
+
:dimensions => ['month', 'year'],
|
52
|
+
:metrics => ['visits', 'bounces'],
|
53
|
+
})
|
54
|
+
|
55
|
+
# Show the data
|
56
|
+
puts data.inspect
|
57
|
+
|
58
|
+
<hr />
|
59
|
+
|
60
|
+
General Usage
|
61
|
+
=============
|
62
|
+
|
63
|
+
### Create your Gattica object
|
64
|
+
|
65
|
+
ga = Gattica.new({ :email => 'email@gmail.com', :password => 'password' })
|
66
|
+
puts ga.token # => returns a big alpha-numeric string
|
67
|
+
|
68
|
+
### Query for accounts you have access to
|
69
|
+
|
70
|
+
# Retrieve a list of accounts
|
71
|
+
accounts = ga.accounts
|
72
|
+
|
73
|
+
# Show information about accounts
|
74
|
+
puts "---------------------------------"
|
75
|
+
puts "Available profiles: " + accounts.count.to_s
|
76
|
+
accounts.each do |account|
|
77
|
+
puts " --> " + account.title
|
78
|
+
puts " last updated: " + account.updated.inspect
|
79
|
+
puts " web property: " + account.web_property_id
|
80
|
+
puts " profile id: " + account.profile_id.inspect
|
81
|
+
puts " goals: " + account.goals.count.inspect
|
82
|
+
end
|
83
|
+
|
84
|
+
### Set which profile Gattica needs to use
|
85
|
+
|
86
|
+
# Tell Gattica to query profile ID 5555555
|
87
|
+
ga.profile_id = 5555555
|
88
|
+
|
89
|
+
### Get data from Google Analytics
|
90
|
+
|
91
|
+
The Get method will get data from Google Analytics and return Gattica::DataSet type.
|
92
|
+
|
93
|
+
* Dates must be in 'YYYY-MM-DD' format.
|
94
|
+
* Dimensions and metrics can be gotten from [Google Analytics Dimensions & Metrics Reference](http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDimensionsMetrics.html)
|
95
|
+
* You do not need to use "ga:" at the beginning of the strings.
|
96
|
+
|
97
|
+
Here's an example:
|
98
|
+
|
99
|
+
# Get the number of visitors by month from Jan 1st to April 1st.
|
100
|
+
data = ga.get({
|
101
|
+
:start_date => '2011-01-01',
|
102
|
+
:end_date => '2011-04-01',
|
103
|
+
:dimensions => ['month', 'year'],
|
104
|
+
:metrics => ['visitors']
|
105
|
+
})
|
106
|
+
|
107
|
+
<hr />
|
108
|
+
|
109
|
+
Using Dimension & Metrics
|
110
|
+
=========================
|
111
|
+
|
112
|
+
Here are some additional examples that illustrate different things you can do with dimensions and metrics.
|
113
|
+
|
114
|
+
|
115
|
+
### Sorting
|
116
|
+
|
117
|
+
# Sorting by number of visits in descending order (most visits at the top)
|
118
|
+
data = ga.get({
|
119
|
+
:start_date => '2011-01-01',
|
120
|
+
:end_date => '2011-04-01',
|
121
|
+
:dimensions => ['month', 'year'],
|
122
|
+
:metrics => ['visits']
|
123
|
+
:sort => ['-visits'],
|
124
|
+
})
|
125
|
+
|
126
|
+
### Limiting results
|
127
|
+
|
128
|
+
# Limit the number of results to 25.
|
129
|
+
data = ga.get({
|
130
|
+
:start_date => '2011-01-01',
|
131
|
+
:end_date => '2011-04-01',
|
132
|
+
:dimensions => ['month', 'year'],
|
133
|
+
:metrics => ['visits']
|
134
|
+
:max_results => 25
|
135
|
+
})
|
136
|
+
|
137
|
+
### Results as a Hash
|
138
|
+
|
139
|
+
my_hash = data.to_h['points']
|
140
|
+
|
141
|
+
# =>
|
142
|
+
# [{
|
143
|
+
# "xml" => "<entry gd:etag=\"W/".... </entry>",
|
144
|
+
# "id" => "http://www.google.com/analytics/feeds/data?...",
|
145
|
+
# "updated" => Thu, 31 Mar 2011 17:00:00 -0700,
|
146
|
+
# "title" => "ga:month=01 | ga:year=2011",
|
147
|
+
# "dimensions" => [{:month=>"01"}, {:year=>"2011"}],
|
148
|
+
# "metrics" => [{:visitors=>6}]
|
149
|
+
# },
|
150
|
+
# {
|
151
|
+
# "xml" => ...
|
152
|
+
# "id" => ...
|
153
|
+
# "updated" => ...
|
154
|
+
# ...
|
155
|
+
# }]
|
156
|
+
|
157
|
+
|
158
|
+
### JSON formatted string
|
159
|
+
|
160
|
+
# Return data as a json string. (Useful for NoSQL databases)
|
161
|
+
my_json = data.to_h['points'].to_json
|
162
|
+
|
163
|
+
# =>
|
164
|
+
# "[{
|
165
|
+
# \"xml\":\"<entry> .... </entry>\",
|
166
|
+
# \"id\":\"http://www.google.com/analytics/feeds/data? ...",
|
167
|
+
# \"updated\":\"2011-03-31T17:00:00-07:00\",
|
168
|
+
# \"title\":\"ga:month=01 | ga:year=2011\",
|
169
|
+
# \"dimensions\":[{\"month\":\"01\"},{\"year\":\"2011\"}],
|
170
|
+
# \"metrics\":[{\"visitors\":6}]
|
171
|
+
# },
|
172
|
+
# {
|
173
|
+
# \"xml\":\"<entry> .... </entry>\",
|
174
|
+
# \"id\":\"http://www.google.com/analytics/feeds/data? ...",
|
175
|
+
# ...
|
176
|
+
# }]"
|
177
|
+
|
178
|
+
### CSV formatted string
|
179
|
+
|
180
|
+
# Return the data in CSV format. (Useful for using in Excel.)
|
181
|
+
|
182
|
+
# Short CSV will only return your dimensions and metrics:
|
183
|
+
short_csv = data.to_csv(:short)
|
184
|
+
|
185
|
+
# => "month,year,visitors\n\n01,2011, ...."
|
186
|
+
|
187
|
+
# Long CSV will get you a few additional columns:
|
188
|
+
long_csv = data.to_csv
|
189
|
+
|
190
|
+
# => "id,updated,title,month,year,visitors\n\nhttp:// ..."
|
191
|
+
|
192
|
+
|
193
|
+
### DIY formatting
|
194
|
+
|
195
|
+
# You can work directly with the 'point' method to return data.
|
196
|
+
data.points.each do |data_point|
|
197
|
+
month = data_point.dimensions.detect { |dim| dim.key == :month }.value
|
198
|
+
year = data_point.dimensions.detect { |dim| dim.key == :year }.value
|
199
|
+
visitors = data_point.metrics.detect { |metric| metric.key == :visitors }.value
|
200
|
+
puts "#{month}/#{year} got #{visitors} visitors"
|
201
|
+
end
|
202
|
+
|
203
|
+
# =>
|
204
|
+
# 01/2011 got 34552 visitors
|
205
|
+
# 02/2011 got 36732 visitors
|
206
|
+
# 03/2011 got 45642 visitors
|
207
|
+
# 04/2011 got 44456 visitors
|
208
|
+
|
209
|
+
<hr />
|
210
|
+
|
211
|
+
Using Filter, Goals, and Segments
|
212
|
+
=========================
|
213
|
+
|
214
|
+
Learn more about filters: [Google Data feed filtering reference](http://code.google.com/apis/analytics/docs/gdata/gdataReference.html#filtering)
|
215
|
+
|
216
|
+
|
217
|
+
### Get profiles with goals
|
218
|
+
|
219
|
+
# Get all the profiles that have goals
|
220
|
+
profiles_with_goals = accounts.select { |account| account.goals.count > 0 }
|
221
|
+
|
222
|
+
# =>
|
223
|
+
# [{
|
224
|
+
# "id" => "http://www.google.com/analytics/feeds/accounts/ga:...",
|
225
|
+
# "updated" => Mon, 16 May 2011 16:40:30 -0700,
|
226
|
+
# "title" => "Profile Title",
|
227
|
+
# "table_id" => "ga:123456",
|
228
|
+
# "account_id" => 123456,
|
229
|
+
# "account_name" => "Account name",
|
230
|
+
# "profile_id" => 123456,
|
231
|
+
# "web_property_id" => "UA-123456-3",
|
232
|
+
# "goals"=>[{
|
233
|
+
# :active => "true",
|
234
|
+
# :name => "Goal name",
|
235
|
+
# :number => 1,
|
236
|
+
# :value => 0.0
|
237
|
+
# }]
|
238
|
+
# },
|
239
|
+
# {
|
240
|
+
# "id" => "http://www.google.com/analytics/feeds/accounts/ga:...",
|
241
|
+
# "updated" => Mon, 16 May 2011 16:40:30 -0700,
|
242
|
+
# "title" => "Profile Title",
|
243
|
+
# ...
|
244
|
+
# }]
|
245
|
+
|
246
|
+
### List available segments
|
247
|
+
|
248
|
+
# Get all the segments that are available to you
|
249
|
+
segments = ga.segments
|
250
|
+
|
251
|
+
# Segments with negative gaid are default segments from Google. Segments
|
252
|
+
# with positive gaid numbers are custom segments that you created.
|
253
|
+
# =>
|
254
|
+
# [{
|
255
|
+
# "id" => "gaid::-1",
|
256
|
+
# "name" => "All Visits",
|
257
|
+
# "definition" => " "
|
258
|
+
# },
|
259
|
+
# {
|
260
|
+
# "id" => "gaid::-2",
|
261
|
+
# "name" => "New Visitors",
|
262
|
+
# "definition" => "ga:visitorType==New Visitor"
|
263
|
+
# },
|
264
|
+
# {
|
265
|
+
# "id" => ... # more default segments
|
266
|
+
# "name" => ...
|
267
|
+
# "definition" => ...
|
268
|
+
# },
|
269
|
+
# {
|
270
|
+
# "id" => "gaid::12345678",
|
271
|
+
# "name" => "Name of segment",
|
272
|
+
# "definition" => "ga:keyword=...."
|
273
|
+
# },
|
274
|
+
# {
|
275
|
+
# "id" => ... # more custom segments
|
276
|
+
# "name" => ...
|
277
|
+
# "definition" => ...
|
278
|
+
# }]
|
279
|
+
|
280
|
+
### Query by segment
|
281
|
+
|
282
|
+
# Return visits and bounces for mobile traffic
|
283
|
+
# (Google's default user segment gaid::-11)
|
284
|
+
|
285
|
+
mobile_traffic = ga.get({
|
286
|
+
:start_date => '2011-01-01',
|
287
|
+
:end_date => '2011-02-01',
|
288
|
+
:dimensions => ['month', 'year'],
|
289
|
+
:metrics => ['visits', 'bounces'],
|
290
|
+
:segment => ['gaid::-11']
|
291
|
+
})
|
292
|
+
|
293
|
+
### Filtering
|
294
|
+
|
295
|
+
Filters are boolean expressions in strings. Here's an example of an equality:
|
296
|
+
|
297
|
+
# Filter by Firefox users
|
298
|
+
firefox_users = ga.get({
|
299
|
+
:start_date => '2010-01-01',
|
300
|
+
:end_date => '2011-01-01',
|
301
|
+
:dimensions => ['month', 'year'],
|
302
|
+
:metrics => ['visits', 'bounces'],
|
303
|
+
:filters => ['browser == Firefox']
|
304
|
+
})
|
305
|
+
|
306
|
+
Here's an example of greater-than:
|
307
|
+
|
308
|
+
# Filter where visits is >= 10000
|
309
|
+
lots_of_visits = ga.get({
|
310
|
+
:start_date => '2010-01-01',
|
311
|
+
:end_date => '2011-02-01',
|
312
|
+
:dimensions => ['month', 'year'],
|
313
|
+
:metrics => ['visits', 'bounces'],
|
314
|
+
:filters => ['visits >= 10000']
|
315
|
+
})
|
316
|
+
|
317
|
+
Multiple filters is an array. Currently, they are only joined by 'AND'.
|
318
|
+
|
319
|
+
# Firefox users and visits >= 10000
|
320
|
+
firefox_users_with_many_pageviews = ga.get({
|
321
|
+
:start_date => '2010-01-01',
|
322
|
+
:end_date => '2011-02-01',
|
323
|
+
:dimensions => ['month', 'year'],
|
324
|
+
:metrics => ['visits', 'bounces'],
|
325
|
+
:filters => ['browser == Firefox', 'visits >= 10000']
|
326
|
+
})
|
327
|
+
|
328
|
+
|
329
|
+
<hr />
|
330
|
+
|
331
|
+
Even More Examples!
|
332
|
+
===============
|
333
|
+
|
334
|
+
### Top 25 keywords that drove traffic
|
335
|
+
|
336
|
+
Output the top 25 keywords that drove traffic to your website in the first quarter of 2011.
|
337
|
+
|
338
|
+
# Get the top 25 keywords that drove traffic
|
339
|
+
data = ga.get({
|
340
|
+
:start_date => '2011-01-01',
|
341
|
+
:end_date => '2011-04-01',
|
342
|
+
:dimensions => ['keyword'],
|
343
|
+
:metrics => ['visits'],
|
344
|
+
:sort => ['-visits'],
|
345
|
+
:max_results => 25
|
346
|
+
})
|
347
|
+
|
348
|
+
# Output our results
|
349
|
+
data.points.each do |data_point|
|
350
|
+
kw = data_point.dimensions.detect { |dim| dim.key == :keyword }.value
|
351
|
+
visits = data_point.metrics.detect { |metric| metric.key == :visits }.value
|
352
|
+
puts "#{visits} visits => '#{kw}'"
|
353
|
+
end
|
354
|
+
|
355
|
+
# =>
|
356
|
+
# 19667 visits => '(not set)'
|
357
|
+
# 1677 visits => 'keyword 1'
|
358
|
+
# 178 visits => 'keyword 2'
|
359
|
+
# 165 visits => 'keyword 3'
|
360
|
+
# 161 visits => 'keyword 4'
|
361
|
+
# 112 visits => 'keyword 5'
|
362
|
+
# 105 visits => 'seo company reviews'
|
363
|
+
# ...
|
364
|
+
|
365
|
+
<hr />
|
366
|
+
|
367
|
+
Additional Options & Settings
|
368
|
+
=============================
|
369
|
+
|
370
|
+
Setting HTTP timeout
|
371
|
+
--------------------
|
372
|
+
|
373
|
+
If you have a lot of profiles in your account (like 1000+ profiles) querying for accounts may take over a minute. Net::HTTP will timeout and an exception will be raised.
|
374
|
+
|
375
|
+
To avoid this, specify a timeout when you instantiate the Gattica object:
|
376
|
+
|
377
|
+
ga = Gattica.new({
|
378
|
+
:email => 'email@gmail.com',
|
379
|
+
:password => 'password',
|
380
|
+
:timeout => 600 # Set timeout for 10 minutes!
|
381
|
+
})
|
382
|
+
|
383
|
+
The default timeout is 300 seconds (5 minutes). Change the default in: lib/gattica/settings.rb
|
384
|
+
|
385
|
+
For reference 1000 profiles with 2-5 goals each takes around 90-120 seconds.
|
386
|
+
|
387
|
+
Reusing a session token
|
388
|
+
-----------------------
|
389
|
+
|
390
|
+
You can reuse an older session if you still have the token string. Google recommends doing this to avoid authenticating over and over.
|
391
|
+
|
392
|
+
|
393
|
+
my_token = ga.token # => 'DSasdf94...'
|
394
|
+
|
395
|
+
# Sometime later, you can initialize Gattica with the same token
|
396
|
+
ga = Gattica.new({ :token => my_token })
|
397
|
+
|
398
|
+
If your token times out, you will need to re-authenticate.
|
399
|
+
|
400
|
+
Specifying your own headers
|
401
|
+
---------------------------
|
402
|
+
|
403
|
+
Google expects a special header in all HTTP requests called 'Authorization'. Gattica handles this header automatically. If you want to specify your own you can do that when you instantiate Gattica:
|
404
|
+
|
405
|
+
ga = Gattica.new({
|
406
|
+
:token => 'DSasdf94...',
|
407
|
+
:headers => {'My-Special-Header':'my_custom_value'}
|
408
|
+
})
|
409
|
+
|
410
|
+
<hr />
|
411
|
+
|
412
|
+
History
|
413
|
+
=======
|
414
|
+
|
415
|
+
Version history
|
416
|
+
---------------
|
417
|
+
### 0.6.1
|
418
|
+
* Incorporated fixes by vgololobov
|
419
|
+
* Removed circular dependency
|
420
|
+
* Fixed 1.9.3 init exception https://github.com/chrisle/gattica/pull/6
|
421
|
+
|
422
|
+
### 0.6.0
|
423
|
+
* Update to use Google Analytics v2.4 management API
|
424
|
+
|
425
|
+
TL;DR: Uses the v2.4 API now because Google deprecated <2.3.
|
426
|
+
|
427
|
+
* :) - Drop-in replacement for you.
|
428
|
+
* :) - Won't timeout anymore.
|
429
|
+
* :) - Accounts method might be faster if you have a few profiles
|
430
|
+
* :( - Accounts method is notably slower if you have >1000 profiles.
|
431
|
+
|
432
|
+
Google has changed the output of the API < 2.3. Most notable changes
|
433
|
+
were the output of what was the /management/accounts/default call. Some
|
434
|
+
of the XML changed, but most notably it didn't return everything all at
|
435
|
+
once. It used to look like this: http://bit.ly/w6Ummj
|
436
|
+
|
437
|
+
* Fixed token [deviantech]
|
438
|
+
|
439
|
+
### 0.5.1
|
440
|
+
* Added some tests - needs more work :(
|
441
|
+
|
442
|
+
### 0.4.7
|
443
|
+
* Removed version numbers [john mcgrath]
|
444
|
+
|
445
|
+
### 0.4.6
|
446
|
+
* Removed monkey patch [mathieuravaux]
|
447
|
+
|
448
|
+
### 0.4.4
|
449
|
+
* Added a configuration file to unit tests
|
450
|
+
* Removed version.rb. Not needed. (thanks John McGrath see: github.com/john)
|
451
|
+
* Migrated examples and rewrote README file
|
452
|
+
|
453
|
+
### 0.4.3
|
454
|
+
* FIXED: Typo in start-index parameter
|
455
|
+
* Refactored Engine class into it's own file.
|
456
|
+
* Began to re-style code to wrap at 80 characters
|
457
|
+
* Added some unit tests
|
458
|
+
|
459
|
+
### 0.4.2
|
460
|
+
* Added Ruby 1.9 support (Thanks @mathieuravaux https://github.com/mathieuravaux)
|
461
|
+
* Uses hpricot 0.8.4 now. 0.8.3 segfaults.
|
462
|
+
* Added ability to change the timeout when requesting analytics from Google
|
463
|
+
* Added the ability to use max_results
|
464
|
+
|
465
|
+
### 0.3.2.scottp
|
466
|
+
* scottp Added Analytics API v2 header, and basic support for "segment" argument.
|
467
|
+
|
468
|
+
### 0.3.2
|
469
|
+
* er1c updated to use standard Ruby CSV library
|
470
|
+
|
471
|
+
### 0.3.0
|
472
|
+
* Support for filters (filters are all AND'ed together, no OR yet)
|
473
|
+
|
474
|
+
### 0.2.1
|
475
|
+
* More robust error checking on HTTP calls
|
476
|
+
* Added to_xml to get raw XML output from Google
|
477
|
+
|
478
|
+
### 0.2.0 / 2009-04-27
|
479
|
+
* Changed initialization format: pass a hash of options rather than individual email, password and profile_id
|
480
|
+
* Can initialize with a valid token and use that instead of requiring email/password each time
|
481
|
+
* Can initialize with your own logger object instead of having to use the default (useful if you're using with Rails, initialize with RAILS_DEFAULT_LOGGER)
|
482
|
+
* Show error if token is invalid or expired (Google returns a 401 on any HTTP call)
|
483
|
+
* Started tests
|
484
|
+
|
485
|
+
### 0.1.4 / 2009-04-22
|
486
|
+
* Another attempt at getting the gem to build on github
|
487
|
+
|
488
|
+
### 0.1.3 / 2009-04-22
|
489
|
+
* Getting gem to build on github
|
490
|
+
|
491
|
+
### 0.1.2 / 2009-04-22
|
492
|
+
* Updated readme and examples, better documentation throughout
|
493
|
+
|
494
|
+
### 0.1.1 / 2009-04-22
|
495
|
+
* When outputting as CSV, surround each piece of data with double quotes (appears pretty common for various properties (like Browser name) to contain commas
|
496
|
+
|
497
|
+
### 0.1.0 / 2009-03-26
|
498
|
+
* Basic functionality working good. Can't use filters yet.
|
499
|
+
|
500
|
+
|
501
|
+
Maintainer history
|
502
|
+
------------------
|
503
|
+
* [Rob Cameron](https://github.com/activenetwork/gattica) (2010)
|
504
|
+
* [Mike Rumble](https://github.com/rumble/gattica) (2010)
|
505
|
+
* [Chris Le](https://github.com/chrisle/gattica) (Current)
|
506
|
+
|