analytics_goo 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ coverage
2
+ pkg
3
+ rdoc
4
+ tags
5
+ test/tmp
6
+ test/version_tmp
7
+ tmp
data/CHANGELOG ADDED
@@ -0,0 +1,44 @@
1
+ [3b07757 | Tue Jun 02 19:39:50 UTC 2009] Rob Christie <robchristie@gmail.com>
2
+
3
+ * More changes to support rails environments.
4
+
5
+ [3452913 | Tue Jun 02 18:39:51 UTC 2009] Rob Christie <robchristie@gmail.com>
6
+
7
+ * Changed configuration to optionally allow mixins to Rails core classes. Changed to the use of markdown for my readme.
8
+
9
+ [e75017f | Tue Jun 02 07:18:37 UTC 2009] Rob Christie <robchristie@gmail.com>
10
+
11
+ * Migrating to a gem installation.
12
+
13
+ [5b7698f | Tue Jun 02 06:00:49 UTC 2009] Rob Christie <robchristie@gmail.com>
14
+
15
+ * Updated name of project.
16
+
17
+ [00a001f | Tue Jun 02 05:16:40 UTC 2009] Rob Christie <robchristie@gmail.com>
18
+
19
+ * Updated based on naming and configuration changes.
20
+
21
+ [17529a1 | Mon Jun 01 20:10:51 UTC 2009] Rob Christie <robchristie@gmail.com>
22
+
23
+ * Updated class so that random values are changed on each call to track_page_view.
24
+
25
+ [e0d96e7 | Mon Jun 01 19:14:54 UTC 2009] Rob Christie <robchristie@gmail.com>
26
+
27
+ * Updated changelog.
28
+
29
+ [b6ec97c | Mon Jun 01 19:12:50 UTC 2009] Rob Christie <robchristie@gmail.com>
30
+
31
+ * Renamed #track_it to #track_page_view, so you can eventually add other Analytics supported methods like #track_event.
32
+
33
+ [99e5798 | Mon Jun 01 18:55:32 UTC 2009] Rob Christie <robchristie@gmail.com>
34
+
35
+ * Updated CHANGELOG after running script to pull and format messages from git.
36
+
37
+ [bbc664d | Mon Jun 01 18:48:16 UTC 2009] Rob Christie <robchristie@gmail.com>
38
+
39
+ * Remove the AnalyticsConfig object and we now pass in a hash of initialization values. Also added support for passing in multiple hashes of initialization values.
40
+
41
+ [81ce0f8 | Wed May 20 14:29:06 UTC 2009] Rob Christie <robchristie@gmail.com>
42
+
43
+ * initial commit
44
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,77 @@
1
+ # AnalyticsGoo
2
+
3
+ AnalyticsGoo is a gem (or plugin) that provides server side non-javascript tracking using google analytics. The original version tried to mock-up the tracking for use with the UA-* web property ids. The problem with going that route was that all tracking occurs under a single IP address. I have made changes so that it now support google's new MO-* mobile site tracking that allows you to pass the remote IP address via a parameter. The initial intent was to make this look like a logger object. With a single instance that can be used throughout the system; however that is no longer what is needed for our system. We actually need a new version for each request, so the code is still changing.
4
+
5
+ ## Install
6
+
7
+ gem install eyestreet-analytics_goo
8
+
9
+
10
+ ## Newer usage pattern
11
+ Initially I made an adapter pattern thinking that we would support multiple analytics packages. So far I only need Google Analytics:
12
+
13
+ tracker = AnalyticsGoo::GoogleAnalyticsAdapter.new(:analytics_id => "MO-11685745-3",
14
+ :domain => "shor.tswit.ch",
15
+ :remote_address => "75.103.6.17",
16
+ :user_agent => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6",
17
+ :http_accept_language => "en-us,en;q=0.5")
18
+ tracker.track_page_view("/testFoo/myPage.html")
19
+
20
+
21
+
22
+
23
+ ## Example
24
+ The simple usage is the following:
25
+
26
+ tracker = AnalyticsGoo.config(:google_analytics,
27
+ :analytics_id => "MO-11685745-3",
28
+ :domain => "demo.eyestreet.com")
29
+
30
+ tracker.track_page_view("/foo")
31
+
32
+ The first parameter passed to the config initializes the desired analytics adapter. Currently we only support
33
+ Google Analytics. The subsequent hash provide a name for the account, the analytics id, and a domain.
34
+
35
+ ## Rails Usage
36
+
37
+ In your environment.rb add the following:
38
+
39
+ config.gem "analytics_goo", :lib => "analytics_goo"
40
+
41
+
42
+ You can call things in the same way as above, or you can mix in some additional rails specific functionality that is shown below.
43
+ In an intializer like config/initializers/analytics_goo.rb or in your appropriate environment.rb file
44
+
45
+ AnalyticsGoo.config(:google_analytics, :analytics_id => "MO-11685745-3",
46
+ :domain => "demo.eyestreet.com",
47
+ :rails_core_mixins => true,
48
+ :environment => "production")
49
+
50
+ * analytics type - Currently we only support :google_analytics
51
+
52
+ The analytics option hash takes the following:
53
+
54
+ * :analytics_id
55
+ * :domain
56
+ * :rails_core_mixins - Defaults to false. If set to true then you get an accessor method on rails core classes for analytics_goo
57
+ * :environment - The RAILS_ENV environment that the analytics code should be called in. In all other environments it is a noop.
58
+
59
+ Then in your models, controllers, and mailers you can do the following:
60
+
61
+ user = User.find(:first)
62
+ user.analytics_goo.track_page_view("/found_my_first_user")
63
+
64
+ ## Testing
65
+
66
+ Check test/test_helper.rb to make sure you have the required gems installed.
67
+
68
+ rake test
69
+ or
70
+ autotest
71
+
72
+ # Credits
73
+
74
+ AnalyticsGoo is maintained by [Rob Christie](mailto:rob.christie@eyestreet.com) and is funded by [EyeStreet Software](http://www.eyestreet.com).
75
+
76
+
77
+ Copyright (c) 2009 rwc9u, Eyestreet Software released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "analytics_goo"
9
+ gem.summary = %Q{TODO}
10
+ gem.email = "robchristie@gmail.com"
11
+ gem.homepage = "http://github.com/eyestreet/analytics_goo"
12
+ gem.files.include "rails/**/*"
13
+ gem.authors = ["Rob Christie"]
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ desc 'Default: run unit tests.'
22
+ task :default => :test
23
+
24
+ desc 'Test the analytics_goo plugin.'
25
+ Rake::TestTask.new(:test) do |t|
26
+ t.libs << 'lib'
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = true
30
+ end
31
+
32
+ desc 'Generate documentation for the analytics_goo plugin.'
33
+ Rake::RDocTask.new(:rdoc) do |rdoc|
34
+ rdoc.rdoc_dir = 'rdoc'
35
+ rdoc.title = 'AnalyticsGoo'
36
+ rdoc.options << '--line-numbers' << '--inline-source'
37
+ rdoc.rdoc_files.include('README')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
data/TODO ADDED
@@ -0,0 +1,9 @@
1
+ * Add javascript-less support for google analytics event tracking.
2
+
3
+ * Allow an asynchronous operation mode so that tracking has the option of not being done synchronously.
4
+
5
+ * Clean up tests.
6
+
7
+ * Pass along additional header information to google in the image request so that items like browser can be specified.
8
+
9
+ * Peak at the cookies that came in on the most recent request and then use those to build our utmcc.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{analytics_goo}
5
+ s.version = "0.1.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Rob Christie"]
9
+ s.date = %q{2010-03-08}
10
+ s.email = %q{robchristie@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "README.markdown"
13
+ ]
14
+ s.files = [
15
+ ".gitignore",
16
+ "CHANGELOG",
17
+ "MIT-LICENSE",
18
+ "README.markdown",
19
+ "Rakefile",
20
+ "TODO",
21
+ "VERSION",
22
+ "analytics_goo.gemspec",
23
+ "autotest/CHANGELOG",
24
+ "autotest/LICENSE",
25
+ "autotest/README.rdoc",
26
+ "autotest/discover.rb",
27
+ "autotest/railsplugin.rb",
28
+ "autotest/railsplugin_rspec.rb",
29
+ "init.rb",
30
+ "lib/analytics_goo.rb",
31
+ "lib/analytics_goo/google_analytics_adapter.rb",
32
+ "rails/init.rb",
33
+ "rails/init.rb",
34
+ "tasks/analytics_goo.rake",
35
+ "test/analytics_goo_test.rb",
36
+ "test/test_helper.rb"
37
+ ]
38
+ s.has_rdoc = true
39
+ s.homepage = %q{http://github.com/eyestreet/analytics_goo}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.1}
43
+ s.summary = %q{analytics_goo provides a ruby wrapper for performing Google Analytics tracking server side using their Mobile API.}
44
+ s.test_files = [
45
+ "test/analytics_goo_test.rb",
46
+ "test/test_helper.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 2
52
+
53
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
+ else
55
+ end
56
+ else
57
+ end
58
+ end
@@ -0,0 +1,7 @@
1
+
2
+ Git Master
3
+
4
+ * Added RSpec support [Adam Meehan]
5
+ * Added path_to_classname so that failed tests that pass run the suite again. [Ken Collins]
6
+
7
+
data/autotest/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+
2
+ Copyright (c) 2008 Action Moniker LLC., http://www.actionmoniker.com/
3
+
4
+ Permission is hereby granted, free of charge, to any person
5
+ obtaining a copy of this software and associated documentation
6
+ files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following
11
+ 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
18
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ OTHER DEALINGS IN THE SOFTWARE.
24
+
@@ -0,0 +1,40 @@
1
+
2
+ == Autotest::Railsplugin: Use autotest to develop your rails plugins!
3
+
4
+ This is a work in progress. To date the mappings for this autotest class are working
5
+ very well for me. Please read the 'railsplugin.rb' file for details. The short story is
6
+ that default autotest does not map well to rails test naming and this class addresses
7
+ that. Works for test/unit and rspec.
8
+
9
+
10
+ === INSTALLATION
11
+
12
+ * From your plugin root run this
13
+
14
+ git clone git://github.com/metaskills/autotest_railsplugin.git autotest
15
+
16
+ * You can now use autotest.
17
+
18
+ $ autotest
19
+ loading autotest/railsplugin
20
+
21
+
22
+ === CUSTOMISATION
23
+
24
+ If you need to customize the exceptions or mappings, create an .autotest file in the root
25
+ of the plugin and place them in there. An example below of adding a custom exception
26
+
27
+ Autotest.add_hook :initialize do |at|
28
+ at.add_exception %r%^\./spec/dont_touch%
29
+ end
30
+
31
+
32
+ === HELPING OUT
33
+
34
+ If you find that this class is not doing what you think it should. Perhaps when you
35
+ save a file it does not running the corresponding test and you want me to fix it, please
36
+ do the following.
37
+
38
+ Email the directory structure of both the library file and the test file you expected it
39
+ to run to ken *[at]* metaskills.net
40
+
@@ -0,0 +1,6 @@
1
+
2
+ Autotest.add_discovery do
3
+ 'railsplugin'
4
+ end
5
+
6
+
@@ -0,0 +1,53 @@
1
+ class Autotest::Railsplugin < Autotest
2
+
3
+ def initialize
4
+ super
5
+
6
+ # Default libs for autotest. So far they suit us just fine.
7
+ # self.libs = %w[. lib test].join(File::PATH_SEPARATOR)
8
+
9
+ # Ignore these directories in the plugin.
10
+ add_exception %r%^\./(?:autotest|tasks)%
11
+
12
+ # Ignore these ruby files in the root of the plugin folder.
13
+ add_exception %r%^\./(install|uninstall)\.rb$%
14
+
15
+ # Ignore these misc files in the root of the plugin folder.
16
+ add_exception %r%^\./(.*LICENSE|Rakefile|README.*|CHANGELOG.*)$%i
17
+
18
+ # Ignore any log file.
19
+ add_exception %r%.*\.log$%
20
+
21
+ clear_mappings
22
+
23
+ # Easy start. Any test file saved runs that file
24
+ self.add_mapping(%r%^test/.*_test.rb$%) do |filename, matchs|
25
+ filename
26
+ end
27
+
28
+ # If any file in lib matches up to a file in the same directory structure of
29
+ # the test directory, ofcourse having _test.rb at the end, will run that test.
30
+ self.add_mapping(%r%^lib/(.*)\.rb$%) do |filename, matchs|
31
+ filename_path = matchs[1]
32
+ files_matching %r%^test/#{filename_path}_test\.rb$%
33
+ end
34
+
35
+ # If any core test file like the helper, boot, database.yml change, then run
36
+ # all matching .*_test.rb files in the test directory.
37
+ add_mapping %r%^test/(boot|helper|test_helper|factories)\.rb|database.yml% do
38
+ files_matching %r%^test/.*_test\.rb$%
39
+ end
40
+
41
+ end
42
+
43
+ def path_to_classname(s)
44
+ sep = File::SEPARATOR
45
+ f = s.sub(/^test#{sep}?/, '').sub(/\.rb$/, '').split(sep)
46
+ f = f.map { |path| path.split(/_/).map { |seg| seg.capitalize }.join }
47
+ # f = f.map { |path| path =~ /Test$/ ? path : "#{path}Test" }
48
+ f.join('::')
49
+ end
50
+
51
+
52
+ end
53
+
@@ -0,0 +1,29 @@
1
+ require 'autotest/rspec'
2
+
3
+ class Autotest::RailspluginRspec < Autotest::Rspec
4
+
5
+ def initialize
6
+ super
7
+
8
+ # Default libs for autospec. So far they suit us just fine.
9
+ # self.libs = %w[. lib spec].join(File::PATH_SEPARATOR)
10
+
11
+ # Ignore these directories in the plugin.
12
+ add_exception %r%^\./(?:autotest|tasks)%
13
+
14
+ # Ignore these ruby files in the root of the plugin folder.
15
+ add_exception %r%^\./(install|uninstall)\.rb$%
16
+
17
+ # Ignore these misc files in the root of the plugin folder.
18
+ add_exception %r%^\./(.*LICENSE|Rakefile|README.*|CHANGELOG.*)$%i
19
+
20
+ # Ignore any log file.
21
+ add_exception %r%.*\.log$%
22
+
23
+ add_mapping %r%^spec/(boot|helper|factories)\.rb|database.yml% do
24
+ files_matching %r%^spec/.*_spec\.rb$%
25
+ end
26
+
27
+ end
28
+
29
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'rails', 'init')
@@ -0,0 +1,214 @@
1
+
2
+ # AnalyticsGoo
3
+ # The following came from :
4
+ # http://code.google.com/apis/analytics/docs/tracking/gaTrackingTroubleshooting.html
5
+
6
+ # The following parameters are currently not implemented but do not affect basic usage.
7
+ # utme X10 Data Parameter Value is encoded.
8
+
9
+ # utmipc
10
+ # Product Code. This is the sku code for a given product.
11
+ # utmipc=989898ajssi
12
+ # utmipn
13
+ # Product Name, which is a URL-encoded string. utmipn=tee%20shirt
14
+ # utmipr
15
+ # Unit Price. Set at the item level. Value is set to numbers only in U.S. currency format.
16
+ # utmipr=17100.32
17
+ # utmiqt
18
+ # Quantity. utmiqt=4
19
+ # utmiva
20
+ # Variations on an item. For example: large, medium, small, pink, white, black, green. String is URL-encoded.
21
+ # utmiva=red;
22
+ # utmt
23
+ # A special type variable applied to events, transactions, items and user-defined variables. utmt=Dog%20Owner
24
+ # utmtci
25
+ # Billing City utmtci=San%20Diego
26
+ # utmtco
27
+ # Billing Country utmtco=United%20Kingdom
28
+ # utmtid
29
+ # Order ID, URL-encoded string. utmtid=a2343898
30
+ # utmtrg
31
+ # Billing region, URL-encoded string. utmtrg=New%20Brunswick
32
+ # utmtsp
33
+ # Shipping cost. Values as for unit and price. utmtsp=23.95
34
+ # utmtst
35
+ # Affiliation. Typically used for brick and mortar applications in ecommerce. utmtst=google%20mtv%20store
36
+ # utmtto
37
+ # Total. Values as for unit and price. utmtto=334.56
38
+ # utmttx
39
+ # Tax. Values as for unit and price. utmttx=29.16
40
+
41
+ module AnalyticsGoo
42
+ class GoogleAnalyticsAdapter
43
+ attr_accessor :domain, :analytics_id, :env, :noop, :page_title, :remote_address, :referrer, :user_agent, :http_accept_language
44
+ # utmdt
45
+ # Page title, which is a URL-encoded string. utmdt=analytics%20page%20test
46
+
47
+ def initialize(ac)
48
+ # sets the environment that this should be run in
49
+ @analytics_id = ac[:analytics_id]
50
+ @domain = ac[:domain]
51
+ @env = ac[:environment]
52
+ @noop = ac[:noop] || false
53
+ @page_title = ac[:page_title] || ""
54
+ @referrer = ac[:referrer] || "-"
55
+ @remote_address = ac[:remote_address]
56
+ @user_agent = ac[:user_agent] || ""
57
+ @http_accept_language = ac[:http_accept_language] || ""
58
+ end
59
+
60
+ GA_DOMAIN = "www.google-analytics.com"
61
+ GA_IMAGE = "__utm.gif"
62
+
63
+ def urchin_url(ssl = false)
64
+ protocol = (ssl == true) ? "https":"http"
65
+ "#{protocol}://#{GA_DOMAIN}/#{GA_IMAGE}"
66
+ end
67
+
68
+ # utmac Account String. Appears on all requests. utmac=UA-2202604-2
69
+ def utmac
70
+ self.analytics_id
71
+ end
72
+
73
+ # utmhn
74
+ # Host Name, which is a URL-encoded string. utmhn=x343.gmodules.com
75
+ def utmhn
76
+ self.domain
77
+ end
78
+
79
+ # utmcs
80
+ # Language encoding for the browser. Some browsers don't set this, in which case it is set to "-"
81
+ # utmcs=ISO-8859-1
82
+ def utmcs
83
+ "UTF-8"
84
+ end
85
+
86
+ # utmje
87
+ # Indicates if browser is Java-enabled. 1 is true. utmje=1
88
+ def utmje
89
+ "1"
90
+ end
91
+
92
+ # utmn
93
+ # Unique ID generated for each GIF request to prevent caching of the GIF image. utmn=1142651215
94
+ def utmn
95
+ ActiveSupport::SecureRandom.random_number(9999999999).to_s
96
+ end
97
+
98
+ # utmsc
99
+ # Screen color depth utmsc=24-bit
100
+ def utmsc
101
+ "0-bit"
102
+ end
103
+
104
+ # utmsr
105
+ # Screen resolution utmsr=2400x1920&
106
+ def utmsr
107
+ "0x0"
108
+ end
109
+
110
+ # utmul
111
+ # Browser language. utmul=pt-br
112
+ def utmul
113
+ "en-us"
114
+ end
115
+
116
+ # utmwv
117
+ # Tracking code version utmwv=1
118
+ def utmwv
119
+ "4.4sj"
120
+ end
121
+
122
+ # utmp
123
+ # Page request of the current page. utmp=/testDirectory/myPage.html
124
+ # def utmp
125
+ # self.path
126
+ # end
127
+
128
+ # utmr
129
+ # Referral, complete URL. utmr=http://www.example.com/aboutUs/index.php?var=selected
130
+ def utmr
131
+ self.referrer
132
+ end
133
+
134
+ # utmip
135
+ # Remote IP address
136
+ def utmip
137
+ return '' if self.remote_address.blank?
138
+ # Capture the first three octects of the IP address and replace the forth
139
+ # with 0, e.g. 124.455.3.123 becomes 124.455.3.0
140
+ ip = self.remote_address.to_s.gsub!(/([^.]+\.[^.]+\.[^.]+\.)[^.]+/,"\\1") + "0"
141
+ ip
142
+ end
143
+
144
+
145
+ # may not be needed
146
+
147
+ # utmcn Starts a new campaign session. Either utmcn or utmcr is present on any given request. Changes the campaign tracking data; but does not start a new session
148
+ # utmcn=1
149
+ def utmcn
150
+ "1"
151
+ end
152
+
153
+ # utmcr
154
+ # Indicates a repeat campaign visit. This is set when any subsequent clicks occur on the same link. Either utmcn or utmcr is present on any given request.
155
+ # utmcr=1
156
+ def utmcr
157
+ "1"
158
+ end
159
+
160
+ # utmcc
161
+ # Cookie values. This request parameter sends all the cookies requested from the page.
162
+ # utmcc=__utma%3D117243.1695285.22%3B%2B __utmz%3D117945243.1202416366.21.10. utmcsr%3Db%7C utmccn%3D(referral)%7C utmcmd%3Dreferral%7C utmcct%3D%252Fissue%3B%2B
163
+ def utmcc
164
+ "__utma%3D999.999.999.999.999.1%3B"
165
+ end
166
+
167
+ def utmdt
168
+ self.page_title
169
+ end
170
+
171
+ # send a request to get the image from google
172
+ def track_page_view(path)
173
+ res = ""
174
+ unless @noop == true
175
+ res = track_it(path)
176
+ end
177
+ res
178
+ end
179
+
180
+ protected
181
+ def track_it(path)
182
+ # puts "/__utm.gif?utmwv=#{self.utmwv}&utmn=#{self.utmn}&utmhn=#{self.utmhn}&utmcs=#{self.utmcs}&utmsr=#{self.utmsr}&utmsc=#{self.utmsc}&utmul=#{self.utmul}&utmje=#{self.utmje}&utmfl=#{URI::escape(self.utmfl)}&utmdt=#{URI::escape(self.utmdt)}&utmhid=#{utmhid}&utmr=#{self.utmr}&utmp=#{path}&utmac=#{self.utmac}&utmcc=#{self.utmcc} \n"
183
+ utm_uri = "/__utm.gif?" +
184
+ "utmwv=" + self.utmwv +
185
+ "&utmn=" + self.utmn +
186
+ "&utmhn=" + CGI.escape(self.utmhn) +
187
+ "&utmr=" + CGI.escape(self.utmr) +
188
+ "&utmp=" + CGI.escape(path) +
189
+ "&utmac=" + self.utmac +
190
+ "&utmcc=" + self.utmcc +
191
+ "&utmvid="+ self.utmvid +
192
+ "&utmip=" + self.utmip
193
+ Net::HTTP.start(GA_DOMAIN) {|http|
194
+ http.request_get(utm_uri, {"User-Agent" => self.user_agent, "Accept-Language" => self.http_accept_language})
195
+ }
196
+ end
197
+
198
+ def utmcc_cookie
199
+ ActiveSupport::SecureRandom.random_number(89999999) + 10000000
200
+ end
201
+
202
+ def utmcc_random
203
+ ActiveSupport::SecureRandom.random_number(1147483647) + 1000000000
204
+ end
205
+
206
+ def utmcc_time
207
+ Time.new.to_i
208
+ end
209
+
210
+ def utmvid
211
+ "0x" + ActiveSupport::SecureRandom.hex[0,16]
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,67 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'net/http'
4
+ require 'activesupport'
5
+ require 'analytics_goo/google_analytics_adapter'
6
+
7
+ module AnalyticsGoo
8
+ # generic adapter not found exception
9
+ class AnalyticsAdapterNotFound < StandardError
10
+ end
11
+
12
+
13
+ class AnalyticsAdapter
14
+ def initialize(adapter)
15
+ @adapter = adapter
16
+ end
17
+
18
+ def track_page_view(path)
19
+ @adapter.track_page_view(path)
20
+ end
21
+
22
+ def env
23
+ @adapter.env
24
+ end
25
+ end
26
+
27
+ # Factory for returning the appropriate analytics object. The <tt>type</tt> is
28
+ # a symbol that defines the type of analytics tracker you want to create. Currently,
29
+ # the only acceptable value is :google_analytics. The <tt>analytics</tt> hash holds
30
+ # the required keys of analytics_id and the domain of the adapter that you are configuring.
31
+ # Setting the key <tt>rails_core_mixins</tt> to
32
+ # true will mixin an accessor for this object into the core rails framework classes (active_record, action_controller and action_mailer). The default
33
+ # for this is false so that there are no rails dependencies on the gem. The key <tt>environment</tt> by default is set to "production". The
34
+ # rails mixin functionality checks this value against its RAILS_ENV then it calls out to the analytics only if the value is nil or matches.
35
+ def self.config(type, analytics = {})
36
+ begin
37
+ s = type.to_s + "_adapter"
38
+ adapter = "AnalyticsGoo::" + s.camelize
39
+ analytics[:environment] = "production" if analytics[:environment].nil?
40
+ if analytics[:rails_core_mixins] == true
41
+ analytics[:noop] = (RAILS_ENV != analytics[:environment])
42
+ tracker = adapter.constantize.new(analytics)
43
+ for framework in ([ :active_record, :action_controller, :action_mailer ])
44
+ framework.to_s.camelize.constantize.const_get("Base").send :include, AnalyticsGoo::InstanceMethods
45
+ end
46
+ silence_warnings { Object.const_set "ANALYTICS_TRACKER", AnalyticsGoo::AnalyticsAdapter.new(tracker) }
47
+ else
48
+ tracker = adapter.constantize.new(analytics)
49
+ end
50
+ AnalyticsGoo::AnalyticsAdapter.new(tracker)
51
+ rescue StandardError
52
+ raise AnalyticsAdapterNotFound
53
+ end
54
+ end
55
+
56
+ module InstanceMethods
57
+ # any methods here will apply to instances
58
+ def analytics_goo
59
+ if defined?(ANALYTICS_TRACKER)
60
+ ANALYTICS_TRACKER
61
+ else
62
+ nil
63
+ end
64
+ end
65
+ end
66
+ end
67
+
data/rails/init.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "analytics_goo"
2
+
3
+ # add our functionality to rails core classes
4
+ # for framework in ([ :active_record, :action_controller, :action_mailer ])
5
+ # framework.to_s.camelize.constantize.const_get("Base").send :include, AnalyticsGoo::InstanceMethods
6
+ # end
7
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :rails_analytics do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,156 @@
1
+ require 'test_helper'
2
+ require 'analytics_goo'
3
+
4
+ class AnalyticsGooTest < ActiveSupport::TestCase
5
+
6
+ context "AnalyticsGoo " do
7
+ setup do
8
+ @analytics_config = { :analytics_id => "MO-11685745-3",:domain => "test.local" }
9
+ end
10
+ context "contains a GoogleAnalyticsAdapter which when passed initialization data" do
11
+ should "be a valid class" do
12
+ assert AnalyticsGoo::GoogleAnalyticsAdapter.new(@analytics_config)
13
+ end
14
+ end
15
+ context "contains a GoogleAnalyticsAdapter when instantiated with the config method" do
16
+ should "be a valid class" do
17
+ assert AnalyticsGoo.config(:google_analytics, @analytics_config)
18
+ end
19
+ end
20
+ should "raise an exception when instantiated with an invalid adapter" do
21
+ assert_raise AnalyticsGoo::AnalyticsAdapterNotFound do
22
+ AnalyticsGoo.config(:moogle_analytics, @analytics_config)
23
+ end
24
+ end
25
+ context "can pass along an environment variable that" do
26
+ setup do
27
+ @analytics_config[:environment] = "test"
28
+ end
29
+ should "be passed along to the instantiated class" do
30
+ assert_equal "test", AnalyticsGoo.config(:google_analytics, @analytics_config).env
31
+ end
32
+ end
33
+ end
34
+
35
+ context "AnalyticsGoo " do
36
+ setup do
37
+ @analytics_config = { :analytics_id => "MO-11685745-3",:domain => "test.local", :page_title => "This is the page title"}
38
+ @ga = AnalyticsGoo::GoogleAnalyticsAdapter.new(@analytics_config)
39
+ end
40
+ context "when initialized with an analytics id" do
41
+ should "return that id" do
42
+ assert_equal "MO-11685745-3", @ga.utmac
43
+ end
44
+ end
45
+ context "when initialized with a domain" do
46
+ should "return that domain" do
47
+ assert_equal "test.local", @ga.domain
48
+ end
49
+ end
50
+ context "that has been initialized" do
51
+ should "have an urchin url" do
52
+ assert_equal "http://www.google-analytics.com/__utm.gif", @ga.urchin_url
53
+ end
54
+ end
55
+ context "when included and told that the url needs to be ssl" do
56
+ should "have an https URL" do
57
+ assert_equal "https://www.google-analytics.com/__utm.gif", @ga.urchin_url(true)
58
+ end
59
+ end
60
+ context "creates an image URL that " do
61
+ should "have a utmac equal to the specified analytics id" do
62
+ assert_equal "MO-11685745-3", @ga.utmac
63
+ end
64
+ should "have a utmhn equal to the host name" do
65
+ assert_equal "test.local", @ga.domain
66
+ end
67
+ should "have a utmcs equal to the language encoding used for the browser." do
68
+ assert_equal "UTF-8", @ga.utmcs
69
+ end
70
+ should "have a utmdt equal to the Page Title of the page" do
71
+ assert_equal "This is the page title", @ga.utmdt
72
+ end
73
+ should "have a utmje equal to 1" do
74
+ assert_equal "1", @ga.utmje
75
+ end
76
+ should "have a utmn equal to a random number that is generated to prevent caching" do
77
+ assert @ga.utmn != @ga.utmn
78
+ end
79
+ should "have a utmsr equal to the screen resolution" do
80
+ assert_equal "0x0", @ga.utmsr
81
+ end
82
+ should "have a utmsc equal to the screen color depth" do
83
+ assert_equal "0-bit", @ga.utmsc
84
+ end
85
+ should "have a utmul equal to the browser language" do
86
+ assert_equal "en-us", @ga.utmul
87
+ end
88
+ should "have a utmwv equal to the tracking code version" do
89
+ assert_equal "4.4sj", @ga.utmwv
90
+ end
91
+ should "have a utmr equal to the referring page" do
92
+ assert_equal "-", @ga.utmr
93
+ end
94
+ should "have a utmcr set to 1" do
95
+ assert_equal "1", @ga.utmcr
96
+ end
97
+ end
98
+ end
99
+ context "Rails Analytics" do
100
+ setup do
101
+ @ga2 = AnalyticsGoo::GoogleAnalyticsAdapter.new(:analytics_id => "MO-11685745-3",:domain => "shor.tswit.ch", :remote_address => "75.103.6.17")
102
+ # @ga2.expects(:utmcc_cookie).times(2).returns(10000001)
103
+ # @ga2.expects(:utmcc_random).returns(1147483647)
104
+ # @now = Time.now.to_i
105
+ # @ga2.expects(:utmcc_time).times(4).returns(@now)
106
+ end
107
+ should "return a well formed utmcc cookie that is stubbed to the value provided in google analytic mobile tracker docs" do
108
+ assert_equal "__utma%3D999.999.999.999.999.1%3B", @ga2.utmcc
109
+ end
110
+ end
111
+ # TODO: mock this test. Currently it actually does do a request. Was using this to verify that it actually was working.
112
+ context "An analytics tracking event" do
113
+ setup do
114
+ @ga3 = AnalyticsGoo::GoogleAnalyticsAdapter.new(:analytics_id => "MO-11685745-3",
115
+ :domain => "shor.tswit.ch",
116
+ :remote_address => "75.103.6.17",
117
+ :user_agent => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6",
118
+ :http_accept_language => "en-us,en;q=0.5")
119
+ end
120
+ context "makes a request for an image on the google analytics server" do
121
+ setup do
122
+ @resp = @ga3.track_page_view("/testFoo/myPage.html")
123
+ end
124
+ should "be a valid response" do
125
+ assert @resp.is_a?(Net::HTTPOK)
126
+ end
127
+ end
128
+ end
129
+ context "An analytics tracking event using the adapter class" do
130
+ setup do
131
+ @test_ad = AnalyticsGoo::GoogleAnalyticsAdapter.new(:analytics_id => "MO-11685745-3",
132
+ :domain => "shor.tswit.ch",
133
+ :remote_address => "127.0.0.1",
134
+ :user_agent => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6",
135
+ :http_accept_language => "en-us,en;q=0.5")
136
+ @ga4 = AnalyticsGoo::AnalyticsAdapter.new(@test_ad)
137
+ end
138
+ context "makes a request for an image on the google analytics server" do
139
+ setup do
140
+ path = "/__utm.gif?utmwv=4.4sj&utmn=1277734430&utmhn=shor.tswit.ch&utmr=-&utmp=%2Fadmin%2F1&utmac=MO-11685745-3&utmcc=__utma%3D999.999.999.999.999.1%3B&utmvid=0x5719fb3b1e05e909&utmip=127.0.0.0"
141
+ header_hash = {'User-Agent' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6', 'Accept-Language' => 'en-us,en;q=0.5'}
142
+ @test_ad.expects(:utmn).returns("1277734430")
143
+ @test_ad.expects(:utmvid).returns("0x5719fb3b1e05e909")
144
+ # mock the underlying HTTP object
145
+ ht = Net::HTTP.new("127.0.0.1")
146
+ ht.expects(:request_get).with(path, header_hash)
147
+
148
+ Net::HTTP.expects(:start).with(AnalyticsGoo::GoogleAnalyticsAdapter::GA_DOMAIN).yields(ht).returns(Net::HTTPOK.new("1.2","OK",nil))
149
+ @resp = @ga4.track_page_view("/admin/1")
150
+ end
151
+ should "be a valid response" do
152
+ assert @resp.is_a?(Net::HTTPOK)
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
4
+ require 'active_support/test_case'
5
+ gem 'thoughtbot-shoulda', ">= 2.10.1"
6
+ require 'shoulda'
7
+ require 'mocha'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: analytics_goo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Rob Christie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-08 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: robchristie@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - .gitignore
26
+ - CHANGELOG
27
+ - MIT-LICENSE
28
+ - README.markdown
29
+ - Rakefile
30
+ - TODO
31
+ - VERSION
32
+ - analytics_goo.gemspec
33
+ - autotest/CHANGELOG
34
+ - autotest/LICENSE
35
+ - autotest/README.rdoc
36
+ - autotest/discover.rb
37
+ - autotest/railsplugin.rb
38
+ - autotest/railsplugin_rspec.rb
39
+ - init.rb
40
+ - lib/analytics_goo.rb
41
+ - lib/analytics_goo/google_analytics_adapter.rb
42
+ - rails/init.rb
43
+ - tasks/analytics_goo.rake
44
+ - test/analytics_goo_test.rb
45
+ - test/test_helper.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/eyestreet/analytics_goo
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: analytics_goo provides a ruby wrapper for performing Google Analytics tracking server side using their Mobile API.
74
+ test_files:
75
+ - test/analytics_goo_test.rb
76
+ - test/test_helper.rb