jonathannelson-woopra_analytics 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +57 -0
- data/Rakefile +22 -0
- data/lib/jonathannelson/woopra_analytics.rb +137 -0
- data/rails/init.rb +3 -0
- data/tasks/woopra_analytics.rake +61 -0
- data/test/test_helper.rb +10 -0
- data/test/view_helpers_test.rb +11 -0
- data/test/woopra_analytics_test.rb +64 -0
- metadata +68 -0
data/README
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
WoopraAnalytics
|
2
|
+
===============
|
3
|
+
|
4
|
+
This module will easily enable Woopra Analytics support for your application. By default it'll output the analytics code for every single page automatically, if it's configured correctly. This is done by adding the following to your `config/environment.rb`:
|
5
|
+
|
6
|
+
JonathanNelson::WoopraAnalytics.run
|
7
|
+
|
8
|
+
If you want to disable the code insertion for particular pages, add the following to controllers that don't want it:
|
9
|
+
|
10
|
+
skip_after_filter :add_woopra_analytics_code
|
11
|
+
|
12
|
+
If you are running rails 2.1 or above add install this by adding:
|
13
|
+
|
14
|
+
config.gem 'jonathannelson-woopra_analytics', :lib => 'jonathannelsoon/woopra_analytics', :source => 'http://gems.github.com'
|
15
|
+
|
16
|
+
and run:
|
17
|
+
|
18
|
+
rake gems:install
|
19
|
+
|
20
|
+
That's it!
|
21
|
+
|
22
|
+
USING LOCAL COPIES OF THE WOOPRA ANALYTICS JAVASCRIPT FILES
|
23
|
+
|
24
|
+
Under certain circumstances you might find it valuable to serve a copy of the Analytics JavaScript directly from your server to your visitors, and not directly from Woopra. If your visitors are geographically very far from Woopra, or if they have low quality international bandwidth, the loading time for the Analytics JS might kill the user experience and force you to remove the valuable tracking code from your site.
|
25
|
+
|
26
|
+
This plugin now supports local copies Woopra JavaScript files, updated via a rake task and served courtesy of the Rails AssetTagHelper methods. So even if you use asset hosts, the JS will be served from the correct source and under the correct protocol (HTTP/HTTPS).
|
27
|
+
|
28
|
+
To enable cached copies and the following to your initialization code:
|
29
|
+
|
30
|
+
JonathanNelson::WoopraAnalytics.local_javascript = true
|
31
|
+
|
32
|
+
Use the following rake task to update the local copy of the JavaScript file:
|
33
|
+
|
34
|
+
rake woopra_analytics:updates
|
35
|
+
|
36
|
+
To keep the file updated you can add the following to your Capistrano configuration:
|
37
|
+
|
38
|
+
after "deploy:symlink", "deploy:woopra_analytics"
|
39
|
+
|
40
|
+
namespace :deploy do
|
41
|
+
desc "Update local Woopra Analytics files"
|
42
|
+
task :woopra_analytics, :role => :web do
|
43
|
+
run "cd #{current_path} && rake woopra_analytics:update RAILS_ENV=#{ENV['RAILS_ENV']}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
The above Capistrano recipe will almost certainly need some adjustments based on how you run your deployments, but you should get the idea.
|
48
|
+
|
49
|
+
OVERRIDE APPLICATION-WIDE VALUES
|
50
|
+
|
51
|
+
If you're using one Rails application to serve pages across multiple domains, you may wish to override the domain and tracker ID values on a controller-by-controller or view-by-view basis. You can do this by setting the override_domain_name properties. These properties are automatically reset after each use, so the values you set for domain_name (usually in an initializer) will apply to all other requests.
|
52
|
+
|
53
|
+
before_filter :local_analytics
|
54
|
+
|
55
|
+
def local_analytics
|
56
|
+
JonathanNelson::WoopraAnalytics.override_domain_name = 'foo.com'
|
57
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the woopra_analytics plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the woopra_analytics plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'WoopraAnalytics'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module JonathanNelson # :nodoc:
|
2
|
+
module WoopraAnalyticsMixin
|
3
|
+
def woopra_analytics_code
|
4
|
+
WoopraAnalytics.woopra_analytics_code(request.ssl?) if WoopraAnalytics.enabled?(request.format)
|
5
|
+
end
|
6
|
+
|
7
|
+
# An after_filter to automatically add the analytics code.
|
8
|
+
def add_woopra_analytics_code
|
9
|
+
if WoopraAnalytics.defer_load
|
10
|
+
response.body.sub! '</body>', "#{woopra_analytics_code}</body>" if response.body.respond_to?(:sub!)
|
11
|
+
else
|
12
|
+
response.body.sub! '<body>', "<body>#{woopra_analytics_code}" if response.body.respond_to?(:sub!)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class WoopraAnalyticsConfigurationError < StandardError; end
|
18
|
+
|
19
|
+
# The core functionality to connect a Rails application
|
20
|
+
# to a Woopra Analytics installation.
|
21
|
+
#
|
22
|
+
# * domain_name
|
23
|
+
#
|
24
|
+
# Specify a different domain name from the default. See the Woopra Analytics documentation for more
|
25
|
+
# information.
|
26
|
+
#
|
27
|
+
# * analytics_url
|
28
|
+
#
|
29
|
+
# I can't see why you'd want to do this, but you can always change the
|
30
|
+
# Woopra Analytics URL.
|
31
|
+
#
|
32
|
+
# * analytics_ssl_url
|
33
|
+
#
|
34
|
+
# I can't see why you'd want to do this, but you can always change the
|
35
|
+
# Woopra Analytics URL (ssl version).
|
36
|
+
#
|
37
|
+
# * environments
|
38
|
+
#
|
39
|
+
# The environments in which to enable the Woopra Analytics code. Defaults
|
40
|
+
# to 'production' only. Supply an array of environment names to change this.
|
41
|
+
#
|
42
|
+
# * formats
|
43
|
+
#
|
44
|
+
# The formats for which to add. Defaults to +:html+ only. Supply an array
|
45
|
+
# of formats to change this.
|
46
|
+
#
|
47
|
+
# * defer_load
|
48
|
+
#
|
49
|
+
# Set this to true (the default) if you want to load the Analytics javascript at
|
50
|
+
# the bottom of page. Set this to false if you want to load the Analytics
|
51
|
+
# javascript at the top of the page. The page will render faster if you set this to
|
52
|
+
# true.
|
53
|
+
#
|
54
|
+
# * local_javascript
|
55
|
+
#
|
56
|
+
# Set this to true to use a local copy of the woopra.js (or /js/woopra.js) file.
|
57
|
+
# This gives you the added benefit of serving the JS directly from your
|
58
|
+
# server, which in case of a big geographical difference between your server
|
59
|
+
# and Woopra's can speed things up for your visitors. Use the
|
60
|
+
# 'woopra_analytics:update' rake task to update the local JS copies.
|
61
|
+
#
|
62
|
+
# * override_domain_name
|
63
|
+
#
|
64
|
+
# Set this to override the initialized domain name for a single render. Useful
|
65
|
+
# when you're serving to multiple hosts from a single codebase. Typically you'd
|
66
|
+
# set up a before filter in the appropriate controller:
|
67
|
+
# before_filter :override_domain_name
|
68
|
+
# def override_domain_name
|
69
|
+
# JonathanNelson::WoopraAnalytics.override_domain_name = 'foo.com'
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# ...
|
73
|
+
class WoopraAnalytics
|
74
|
+
@@domain_name = nil
|
75
|
+
cattr_accessor :domain_name
|
76
|
+
|
77
|
+
@@analytics_url = 'http://static.woopra.com/js/woopra.js'
|
78
|
+
cattr_accessor :analytics_url
|
79
|
+
|
80
|
+
@@analytics_ssl_url = 'https://sec1.woopra.com/js/woopra.js'
|
81
|
+
cattr_accessor :analytics_ssl_url
|
82
|
+
|
83
|
+
@@environments = ['production']
|
84
|
+
cattr_accessor :environments
|
85
|
+
|
86
|
+
@@formats = [:html]
|
87
|
+
cattr_accessor :formats
|
88
|
+
|
89
|
+
@@defer_load = true
|
90
|
+
cattr_accessor :defer_load
|
91
|
+
|
92
|
+
@@local_javascript = false
|
93
|
+
cattr_accessor :local_javascript
|
94
|
+
|
95
|
+
cattr_accessor :override_domain_name
|
96
|
+
|
97
|
+
# Return true if the Woopra Analytics system is enabled and configured
|
98
|
+
# correctly for the specified format
|
99
|
+
def self.enabled?(format)
|
100
|
+
raise JonathanNelson::WoopraAnalyticsConfigurationError if analytics_url.blank?
|
101
|
+
environments.include?(RAILS_ENV) && formats.include?(format.to_sym)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Construct the javascript code to be inserted on the calling page.
|
105
|
+
def self.woopra_analytics_code(ssl = false)
|
106
|
+
|
107
|
+
extra_code = domain_name.blank? ? nil : "pageTracker._setDomainName(\"#{domain_name}\");"
|
108
|
+
if !override_domain_name.blank?
|
109
|
+
extra_code = "pageTracker._setDomainName(\"#{override_domain_name}\");"
|
110
|
+
self.override_domain_name = nil
|
111
|
+
end
|
112
|
+
|
113
|
+
code = if local_javascript
|
114
|
+
<<-HTML
|
115
|
+
<script src="#{LocalAssetTagHelper.new.javascript_path( '/js/woopra.js' )}" type="text/javascript">
|
116
|
+
</script>
|
117
|
+
HTML
|
118
|
+
else
|
119
|
+
<<-HTML
|
120
|
+
<!-- Woopra Code Start -->
|
121
|
+
<script type="text/javascript">
|
122
|
+
var _wh = ((document.location.protocol=="https:") ? "https://sec1.woopra.com" : "http://static.woopra.com");
|
123
|
+
document.write(unescape("%3Cscript src='" + _wh + "woopra.com/js/woopra.js' type='text/javascript'%3E%3C/script%3E"));
|
124
|
+
</script>
|
125
|
+
<!-- Woopra Code End -->
|
126
|
+
HTML
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
class LocalAssetTagHelper # :nodoc:
|
134
|
+
# For helping with local javascripts
|
135
|
+
include ActionView::Helpers::AssetTagHelper
|
136
|
+
end
|
137
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
namespace :woopra_analytics do
|
2
|
+
|
3
|
+
desc "Update local copy of Woopra Analytics JS"
|
4
|
+
task :update => :environment do
|
5
|
+
File.open( File.join( RAILS_ROOT, 'public', 'javascripts', file ), 'w+' ) do |f|
|
6
|
+
res = Net::HTTP.get_response( 'static.woopra.com', '/' + file )
|
7
|
+
f.write( res.plain_body )
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Intended to extend the Net::HTTP response object
|
13
|
+
# and adds support for decoding gzip and deflate encoded pages
|
14
|
+
#
|
15
|
+
# Author: Jason Stirk <http://griffin.oobleyboo.com>
|
16
|
+
# Home: http://griffin.oobleyboo.com/projects/http_encoding_helper
|
17
|
+
# Created: 5 September 2007
|
18
|
+
# Last Updated: 23 November 2007
|
19
|
+
#
|
20
|
+
# Usage:
|
21
|
+
#
|
22
|
+
# require 'net/http'
|
23
|
+
# require 'http_encoding_helper'
|
24
|
+
# headers={'Accept-Encoding' => 'gzip, deflate' }
|
25
|
+
# http = Net::HTTP.new('griffin.oobleyboo.com', 80)
|
26
|
+
# http.start do |h|
|
27
|
+
# request = Net::HTTP::Get.new('/', headers)
|
28
|
+
# response = http.request(request)
|
29
|
+
# content=response.plain_body # Method from our library
|
30
|
+
# puts "Transferred: #{response.body.length} bytes"
|
31
|
+
# puts "Compression: #{response['content-encoding']}"
|
32
|
+
# puts "Extracted: #{response.plain_body.length} bytes"
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
|
36
|
+
require 'net/http'
|
37
|
+
require 'zlib'
|
38
|
+
require 'stringio'
|
39
|
+
|
40
|
+
class Net::HTTPResponse
|
41
|
+
# Return the uncompressed content
|
42
|
+
def plain_body
|
43
|
+
encoding=self['content-encoding']
|
44
|
+
content=nil
|
45
|
+
if encoding then
|
46
|
+
case encoding
|
47
|
+
when 'gzip'
|
48
|
+
i=Zlib::GzipReader.new(StringIO.new(self.body))
|
49
|
+
content=i.read
|
50
|
+
when 'deflate'
|
51
|
+
i=Zlib::Inflate.new
|
52
|
+
content=i.inflate(self.body)
|
53
|
+
else
|
54
|
+
raise "Unknown encoding - #{encoding}"
|
55
|
+
end
|
56
|
+
else
|
57
|
+
content=self.body
|
58
|
+
end
|
59
|
+
return content
|
60
|
+
end
|
61
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
|
6
|
+
|
7
|
+
#config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
8
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
9
|
+
|
10
|
+
db_adapter = ENV['DB']
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
include ActionView::Helpers::UrlHelper
|
3
|
+
include ActionView::Helpers::TagHelper
|
4
|
+
|
5
|
+
class ViewHelpersTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
JonathanNelson::WoopraAnalytics.defer_load = false
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
class WoopraAnalyticsTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@wa = JonathanNelson::WoopraAnalytics.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_createable
|
12
|
+
assert_not_nil(@wa)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_domain_name_defaults_to_nil
|
16
|
+
assert_nil(@wa.domain_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_default_environments
|
20
|
+
assert_equal(false, @wa.environments.include?('test'))
|
21
|
+
assert_equal(false, @wa.environments.include?('development'))
|
22
|
+
assert_equal(true, @wa.environments.include?('production'))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_default_formats
|
26
|
+
assert_equal(false, @wa.formats.include?(:xml))
|
27
|
+
assert_equal(true, @wa.formats.include?(:html))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_defer_load_defaults_to_true
|
31
|
+
assert_equal(true, @wa.defer_load)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_local_javascript_defaults_to_false
|
35
|
+
assert_equal(false, @wa.local_javascript)
|
36
|
+
end
|
37
|
+
|
38
|
+
# test self.enabled
|
39
|
+
def test_enabled_requires_analytics_url
|
40
|
+
JonathanNelson::WoopraAnalytics.stubs(:analytics_url).returns(nil)
|
41
|
+
assert_raise(JonathanNelson::WoopraAnalyticsConfigurationError) { JonathanNelson::WoopraAnalytics.enabled?(:html) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_enabled_returns_false_if_current_environment_not_enabled
|
45
|
+
assert_equal(false, JonathanNelson::WoopraAnalytics.enabled?(:html))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_enabled_with_default_format
|
49
|
+
JonathanNelson::WoopraAnalytics.stubs(:environments).returns(['test'])
|
50
|
+
assert_equal(true, JonathanNelson::WoopraAnalytics.enabled?(:html))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_enabled_with_not_included_format
|
54
|
+
JonathanNelson::WoopraAnalytics.stubs(:environments).returns(['test'])
|
55
|
+
assert_equal(false, JonathanNelson::WoopraAnalytics.enabled?(:xml))
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_enabled_with_added_format
|
59
|
+
JonathanNelson::WoopraAnalytics.stubs(:environments).returns(['test'])
|
60
|
+
JonathanNelson::WoopraAnalytics.stubs(:formats).returns([:xml])
|
61
|
+
assert_equal(true, JonathanNelson::WoopraAnalytics.enabled?(:xml))
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jonathannelson-woopra_analytics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Nelson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-01 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: actionpack
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: "By default this gem will output Woopra code forevery page automatically, if it's configured correctly.This is done by adding: JonathanNelson::WoopraAnalytics.run"
|
25
|
+
email: nelsojona@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- rails/init.rb
|
36
|
+
- test/woopra_analytics_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
- test/view_helpers_test.rb
|
39
|
+
- lib/jonathannelson/woopra_analytics.rb
|
40
|
+
- tasks/woopra_analytics.rake
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/jonathannelson/woopra_analytics/tree/master
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project: woopra_analytics
|
63
|
+
rubygems_version: 1.2.0
|
64
|
+
signing_key:
|
65
|
+
specification_version: 2
|
66
|
+
summary: "[Rails] This is a quick 'n' dirty module to easily enableWoopra Analytics support in your application."
|
67
|
+
test_files: []
|
68
|
+
|