analytics_goo 0.1.2

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/.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