satellite 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -3
- data/Gemfile.lock +20 -0
- data/VERSION +1 -1
- data/lib/satellite/adapters/google_analytics.rb +281 -0
- data/lib/satellite/controllers/google_analytics.rb +38 -0
- data/lib/satellite.rb +45 -57
- data/lib/support/object.rb +34 -0
- data/lib/support/string.rb +65 -0
- data/satellite.gemspec +63 -0
- data/test/helper.rb +3 -0
- data/test/test_satellite.rb +53 -2
- metadata +10 -4
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.6.4)
|
6
|
+
bundler (~> 1.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rake (0.9.2)
|
10
|
+
rcov (0.9.10)
|
11
|
+
shoulda (2.11.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler (~> 1.0.0)
|
18
|
+
jeweler (~> 1.6.4)
|
19
|
+
rcov
|
20
|
+
shoulda
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
@@ -0,0 +1,281 @@
|
|
1
|
+
module Satellite
|
2
|
+
module Adapters
|
3
|
+
class GoogleAnalytics
|
4
|
+
|
5
|
+
def initialize(params, use_ssl=false)
|
6
|
+
self.utm_params = extend_with_default_params(params)
|
7
|
+
self.utm_location = (use_ssl ? 'https://ssl' : 'http://www') + UTM_GIF_LOCATION
|
8
|
+
end
|
9
|
+
|
10
|
+
def track
|
11
|
+
#puts utm_params.inspect
|
12
|
+
|
13
|
+
utm_url = tracking_url
|
14
|
+
|
15
|
+
puts "--------sending request to GA-----------------------"
|
16
|
+
puts utm_url
|
17
|
+
|
18
|
+
open(utm_url, { "User-Agent" => 'Satellite/0.0.0', "Accept-Language" => 'de' })
|
19
|
+
|
20
|
+
# reset events / custom variables here
|
21
|
+
utm_params.delete(:utme)
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def tracking_url
|
26
|
+
utm_location + "?" + utm_params.to_query
|
27
|
+
end
|
28
|
+
|
29
|
+
def track_event(category, action, label=nil, value=nil)
|
30
|
+
utm_params[:utme].set_event(category, action, label, value)
|
31
|
+
track
|
32
|
+
end
|
33
|
+
|
34
|
+
def track_page_view(path=nil)
|
35
|
+
utm_params.merge({ :utmp => path }) if path
|
36
|
+
track
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_custom_variable(index, name, value, scope=nil)
|
40
|
+
utm_params[:utme].set_custom_variable(index, name, value, scope)
|
41
|
+
end
|
42
|
+
|
43
|
+
def unset_custom_variable(index)
|
44
|
+
utm_params[:utme].unset_custom_variable(index)
|
45
|
+
end
|
46
|
+
|
47
|
+
def []=(key, value)
|
48
|
+
value = Utme.parse(value) if key.to_s == 'utme'
|
49
|
+
utm_params[key] = value
|
50
|
+
end
|
51
|
+
|
52
|
+
def [](key)
|
53
|
+
utm_params[key]
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
attr_accessor :account_id
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
attr_accessor :utm_params, :utm_location
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# seems to be the current version
|
67
|
+
# search for 'utmwv' in http://www.google-analytics.com/ga.js
|
68
|
+
VERSION = "4.4sh" #"5.1.5"
|
69
|
+
UTM_GIF_LOCATION = ".google-analytics.com/__utm.gif"
|
70
|
+
|
71
|
+
# adds default params
|
72
|
+
def extend_with_default_params(params)
|
73
|
+
utme = params.delete(:utme)
|
74
|
+
{
|
75
|
+
:utmac => self.class.account_id,
|
76
|
+
:utmcc => '__utma%3D999.999.999.999.999.1%3B', # stub for non-existent cookie,
|
77
|
+
:utmcs => 'UTF-8',
|
78
|
+
:utme => Utme.parse(utme),
|
79
|
+
:utmhid => rand(0x7fffffff).to_s,
|
80
|
+
:utmn => rand(0x7fffffff).to_s,
|
81
|
+
:utmvid => rand(0x7fffffff).to_s,
|
82
|
+
:utmwv => VERSION,
|
83
|
+
# should get configured when initializing
|
84
|
+
#:utmhn => 'google-analytics.satellite.local',
|
85
|
+
#:utmr => 'https://rubygems.org/gems/satellite',
|
86
|
+
#:utmp => '/google-analytics',
|
87
|
+
#:utmip => '127.0.0.1',
|
88
|
+
}.merge(params)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
module Satellite
|
96
|
+
module Adapters
|
97
|
+
class GoogleAnalytics::Utme
|
98
|
+
|
99
|
+
def initialize
|
100
|
+
@custom_variables = CustomVariables.new
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_event(category, action, label=nil, value=nil)
|
104
|
+
@event = Event.new(category, action, label, value)
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_custom_variable(slot, name, value, scope=nil)
|
109
|
+
@custom_variables.set_custom_variable(slot, CustomVariable.new(name, value, scope))
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def unset_custom_variable(slot)
|
114
|
+
@custom_variables.unset_custom_variable(slot)
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_s
|
119
|
+
@event.to_s + @custom_variables.to_s
|
120
|
+
end
|
121
|
+
|
122
|
+
alias_method :to_param, :to_s
|
123
|
+
|
124
|
+
class << self
|
125
|
+
|
126
|
+
@@regex_event = /5\((\w+)\*(\w+)(\*(\w+))?\)(\((\d+)\))?/
|
127
|
+
@@regex_custom_variables = /8\(([^\)]*)\)9\(([^\)]*)\)(11\(([^\)]*)\))?/
|
128
|
+
@@regex_custom_variable_value = /((\d)!)?(\w+)/
|
129
|
+
|
130
|
+
def parse(args)
|
131
|
+
return self.new if args.nil?
|
132
|
+
case args
|
133
|
+
when String
|
134
|
+
return self.from_string(args)
|
135
|
+
when self
|
136
|
+
return args
|
137
|
+
else
|
138
|
+
raise ArgumentError, "Could parse argument neither as String nor GATracker::Utme"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def from_string(str)
|
143
|
+
utme = self.new
|
144
|
+
|
145
|
+
# parse event
|
146
|
+
str.gsub!(@@regex_event) do |match|
|
147
|
+
utme.set_event($1, $2, $4, $6)
|
148
|
+
''
|
149
|
+
end
|
150
|
+
|
151
|
+
# parse custom variables
|
152
|
+
str.gsub!(@@regex_custom_variables) do |match|
|
153
|
+
custom_vars = { }
|
154
|
+
match_names, match_values, match_scopes = $1, $2, $4
|
155
|
+
|
156
|
+
names = match_names.to_s.split('*')
|
157
|
+
values = match_values.to_s.split('*')
|
158
|
+
scopes = match_scopes.to_s.split('*')
|
159
|
+
|
160
|
+
raise ArgumentError, "Each custom variable must have a value defined." if names.length != values.length
|
161
|
+
|
162
|
+
names.each_with_index do |raw_name, i|
|
163
|
+
match_data = raw_name.match(@@regex_custom_variable_value)
|
164
|
+
slot, name = (match_data[2] || i+1).to_i, match_data[3]
|
165
|
+
custom_vars[slot] = { :name => name }
|
166
|
+
end
|
167
|
+
|
168
|
+
values.each_with_index do |raw_value, i|
|
169
|
+
match_data = raw_value.match(@@regex_custom_variable_value)
|
170
|
+
slot, value = (match_data[2] || i+1).to_i, match_data[3]
|
171
|
+
custom_vars[slot][:value] = value
|
172
|
+
end
|
173
|
+
|
174
|
+
scopes.each_with_index do |raw_scope, i|
|
175
|
+
match_data = raw_scope.match(@@regex_custom_variable_value)
|
176
|
+
slot, scope = (match_data[2] || i+1).to_i, match_data[3]
|
177
|
+
# silently ignore scope if there's no corresponding custom variable
|
178
|
+
custom_vars[slot][:scope] = scope if custom_vars[slot]
|
179
|
+
end
|
180
|
+
|
181
|
+
# finally set all the gathered custom vars
|
182
|
+
custom_vars.each do |key, custom_var|
|
183
|
+
utme.set_custom_variable(key, custom_var[:name], custom_var[:value], custom_var[:scope])
|
184
|
+
end
|
185
|
+
''
|
186
|
+
end
|
187
|
+
|
188
|
+
utme
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
Event = Struct.new(:category, :action, :opt_label, :opt_value) do
|
195
|
+
def to_s
|
196
|
+
output = "5(#{category}*#{action}"
|
197
|
+
output += "*#{opt_label}" if opt_label
|
198
|
+
output += ")"
|
199
|
+
output += "(#{opt_value})" if opt_value
|
200
|
+
output
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
CustomVariable = Struct.new(:name, :value, :opt_scope)
|
205
|
+
|
206
|
+
class CustomVariables
|
207
|
+
|
208
|
+
@@valid_keys = 1..5
|
209
|
+
|
210
|
+
def initialize
|
211
|
+
@contents = { }
|
212
|
+
end
|
213
|
+
|
214
|
+
def set_custom_variable(slot, custom_variable)
|
215
|
+
raise ArgumentError, "Cannot set a slot other than #{@@valid_keys}. Given #{slot}" if not @@valid_keys.include?(slot)
|
216
|
+
@contents[slot] = custom_variable
|
217
|
+
end
|
218
|
+
|
219
|
+
def unset_custom_variable(slot)
|
220
|
+
raise ArgumentError, "Cannot unset a slot other than #{@@valid_keys}. Given #{slot}" if not @@valid_keys.include?(slot)
|
221
|
+
@contents.delete(slot)
|
222
|
+
end
|
223
|
+
|
224
|
+
# follows google custom variable format
|
225
|
+
#
|
226
|
+
# 8(NAMES)9(VALUES)11(SCOPES)
|
227
|
+
#
|
228
|
+
# best explained by examples
|
229
|
+
#
|
230
|
+
# 1)
|
231
|
+
# pageTracker._setCustomVar(1,"foo", "val", 1)
|
232
|
+
# ==> 8(foo)9(bar)11(1)
|
233
|
+
#
|
234
|
+
# 2)
|
235
|
+
# pageTracker._setCustomVar(1,"foo", "val", 1)
|
236
|
+
# pageTracker._setCustomVar(2,"bar", "vok", 3)
|
237
|
+
# ==> 8(foo*bar)9(val*vok)11(1*3)
|
238
|
+
#
|
239
|
+
# 3)
|
240
|
+
# pageTracker._setCustomVar(1,"foo", "val", 1)
|
241
|
+
# pageTracker._setCustomVar(2,"bar", "vok", 3)
|
242
|
+
# pageTracker._setCustomVar(4,"baz", "vol", 1)
|
243
|
+
# ==> 8(foo*bar*4!baz)9(val*vak*4!vol)11(1*3*4!1)
|
244
|
+
#
|
245
|
+
# 4)
|
246
|
+
# pageTracker._setCustomVar(4,"foo", "bar", 1)
|
247
|
+
# ==> 8(4!foo)9(4!bar)11(4!1)
|
248
|
+
#
|
249
|
+
def to_s
|
250
|
+
return '' if @contents.empty?
|
251
|
+
|
252
|
+
ordered_keys = @contents.keys.sort
|
253
|
+
names = values = scopes = ''
|
254
|
+
|
255
|
+
ordered_keys.each do |slot|
|
256
|
+
custom_variable = @contents[slot]
|
257
|
+
predecessor = @contents[slot-1]
|
258
|
+
|
259
|
+
has_predecessor = !!predecessor
|
260
|
+
has_scoped_predecessor = !!(predecessor.try(:opt_scope))
|
261
|
+
|
262
|
+
star = names.empty? ? '' : '*'
|
263
|
+
bang = (slot == 1 || has_predecessor) ? '' : "#{slot}!"
|
264
|
+
|
265
|
+
scope_star = scopes.empty? ? '' : '*'
|
266
|
+
scope_bang = (slot == 1 || has_scoped_predecessor) ? '' : "#{slot}!"
|
267
|
+
|
268
|
+
names += "#{star}#{bang}#{custom_variable.name}"
|
269
|
+
values += "#{star}#{bang}#{custom_variable.value}"
|
270
|
+
scopes += "#{scope_star}#{scope_bang}#{custom_variable.opt_scope}" if custom_variable.opt_scope
|
271
|
+
end
|
272
|
+
|
273
|
+
output = "8(#{names})9(#{values})"
|
274
|
+
output += "11(#{scopes})" if not scopes.empty?
|
275
|
+
output
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Satellite
|
2
|
+
module Controllers
|
3
|
+
class GoogleAnalyticsController
|
4
|
+
|
5
|
+
def tracker
|
6
|
+
@tracker ||= Satellite.get_tracker(:google_analytics, ga_params)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def ga_visitor_id
|
12
|
+
"#{request.env["HTTP_USER_AGENT"]}#{rand(0x7fffffff).to_s}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def ga_params
|
16
|
+
# domain specific stuff
|
17
|
+
domain_name = (request.env["SERVER_NAME"].nil? || request.env["SERVER_NAME"].blank?) ? "" : request.env["SERVER_NAME"]
|
18
|
+
referral = request.env['HTTP_REFERER'] || ''
|
19
|
+
path = request.env["REQUEST_URI"] || ''
|
20
|
+
|
21
|
+
# Capture the first three octects of the IP address and replace the forth
|
22
|
+
# with 0, e.g. 124.455.3.123 becomes 124.455.3.0
|
23
|
+
remote_address = request.env["REMOTE_ADDR"].to_s
|
24
|
+
ip = (remote_address.nil? || remote_address.blank?) ? '' : remote_address.gsub!(/([^.]+\.[^.]+\.[^.]+\.)[^.]+/, "\\1") + "0"
|
25
|
+
|
26
|
+
visitor_uuid = Digest::MD5.hexdigest(ga_visitor_id)
|
27
|
+
|
28
|
+
{
|
29
|
+
:utmhn => domain_name,
|
30
|
+
:utmr => referral,
|
31
|
+
:utmp => path,
|
32
|
+
:utmip => ip,
|
33
|
+
:utmvid => visitor_uuid
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/satellite.rb
CHANGED
@@ -1,76 +1,64 @@
|
|
1
1
|
require 'open-uri'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
self.utm_location = (use_ssl ? 'https://ssl' : 'http://www') + UTM_GIF_LOCATION
|
8
|
-
end
|
9
|
-
|
10
|
-
def track
|
3
|
+
# stub some ActiveSupport functionality
|
4
|
+
unless Object.const_defined?("ActiveSupport")
|
5
|
+
Dir.glob(File.dirname(__FILE__) + '/support/*') { |file| require file }
|
6
|
+
end
|
11
7
|
|
12
|
-
|
8
|
+
# load tracking adapters
|
9
|
+
Dir.glob(File.dirname(__FILE__) + '/satellite/adapters/*') { |file| require file }
|
13
10
|
|
14
|
-
|
15
|
-
puts utm_url
|
16
|
-
open(utm_url)
|
11
|
+
module Satellite
|
17
12
|
|
18
|
-
|
19
|
-
utm_params.delete(:utme)
|
13
|
+
class NoAdapterError < NameError
|
20
14
|
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
class TrackerInterface
|
17
|
+
def initialize(adapter)
|
18
|
+
@adapter = adapter
|
19
|
+
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
21
|
+
def track_page_view(path=nil)
|
22
|
+
@adapter.track_page_view(path)
|
23
|
+
end
|
31
24
|
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
def track_event(category, action, label=nil, value=nil)
|
26
|
+
@adapter.track_event(category, action, label, value)
|
27
|
+
end
|
35
28
|
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
def set_custom_variable(slot, name, value, scope=nil)
|
30
|
+
@adapter.set_custom_variable(slot, name, value, scope)
|
31
|
+
end
|
39
32
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def [](key)
|
46
|
-
utm_params[key]
|
47
|
-
end
|
33
|
+
def unset_custom_variable(slot)
|
34
|
+
@adapter.unset_custom_variable(slot)
|
35
|
+
end
|
48
36
|
|
49
|
-
|
50
|
-
|
51
|
-
|
37
|
+
def tracking_url
|
38
|
+
@adapter.tracking_url
|
39
|
+
end
|
52
40
|
|
53
|
-
|
41
|
+
def type
|
42
|
+
@adapter.class
|
43
|
+
end
|
54
44
|
|
55
|
-
|
45
|
+
def []=(key, value)
|
46
|
+
@adapter[key] = value
|
47
|
+
end
|
56
48
|
|
57
|
-
|
49
|
+
def [](key)
|
50
|
+
@adapter[key]
|
51
|
+
end
|
52
|
+
end
|
58
53
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
def self.get_tracker(type, params = { })
|
55
|
+
begin
|
56
|
+
tracker_klass = "Satellite::Adapters::#{type.to_s.camelcase}".constantize
|
57
|
+
rescue
|
58
|
+
raise NoAdapterError, "There is no such adapter like 'Satellite::Adapters::#{type.to_s.camelcase}'"
|
59
|
+
end
|
63
60
|
|
64
|
-
|
65
|
-
def extend_with_default_params(params)
|
66
|
-
params.reverse_merge({
|
67
|
-
:utme => Utme.parse(params[:utme]),
|
68
|
-
:utmwv => VERSION,
|
69
|
-
:utmn => rand(0x7fffffff).to_s,
|
70
|
-
:utmac => GATracker.account_id
|
71
|
-
})
|
61
|
+
TrackerInterface.new(tracker_klass.new(params))
|
72
62
|
end
|
73
63
|
|
74
|
-
end
|
75
|
-
|
76
|
-
require 'satellite/utme'
|
64
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
unless Object.const_defined?("ActiveSupport")
|
2
|
+
class Object
|
3
|
+
def to_query(key)
|
4
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
5
|
+
|
6
|
+
puts self.inspect
|
7
|
+
puts to_param
|
8
|
+
|
9
|
+
"#{CGI.escape(key.to_s).gsub(/%(5B|5D)/n) { [$1].pack('H*') }}=#{CGI.escape(to_param.to_s)}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_param
|
13
|
+
to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def try(method, *args, &block)
|
17
|
+
begin
|
18
|
+
send(method, *args, &block)
|
19
|
+
rescue
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Hash
|
26
|
+
def to_param(namespace = nil)
|
27
|
+
collect do |key, value|
|
28
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
29
|
+
end.sort * '&'
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :to_query, :to_param
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
unless Object.const_defined?("ActiveSupport")
|
2
|
+
class String
|
3
|
+
def camelize(first_letter = :upper)
|
4
|
+
case first_letter
|
5
|
+
when :upper then
|
6
|
+
ActiveSupport::Inflector.camelize(self, true)
|
7
|
+
when :lower then
|
8
|
+
ActiveSupport::Inflector.camelize(self, false)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method :camelcase, :camelize
|
13
|
+
|
14
|
+
def constantize
|
15
|
+
ActiveSupport::Inflector.constantize(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def underscore
|
19
|
+
ActiveSupport::Inflector.underscore(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def demodulize
|
23
|
+
ActiveSupport::Inflector.demodulize(self)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ActiveSupport
|
28
|
+
module Inflector
|
29
|
+
extend self
|
30
|
+
|
31
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
32
|
+
if first_letter_in_uppercase
|
33
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
34
|
+
else
|
35
|
+
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def underscore(camel_cased_word)
|
40
|
+
word = camel_cased_word.to_s.dup
|
41
|
+
word.gsub!(/::/, '/')
|
42
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
43
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
44
|
+
word.tr!("-", "_")
|
45
|
+
word.downcase!
|
46
|
+
word
|
47
|
+
end
|
48
|
+
|
49
|
+
def demodulize(class_name_in_module)
|
50
|
+
class_name_in_module.to_s.gsub(/^.*::/, '')
|
51
|
+
end
|
52
|
+
|
53
|
+
def constantize(camel_cased_word)
|
54
|
+
names = camel_cased_word.split('::')
|
55
|
+
names.shift if names.empty? || names.first.empty?
|
56
|
+
|
57
|
+
constant = Object
|
58
|
+
names.each do |name|
|
59
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
60
|
+
end
|
61
|
+
constant
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/satellite.gemspec
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{satellite}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = [%q{Maik Vlcek}]
|
12
|
+
s.date = %q{2011-08-25}
|
13
|
+
s.description = %q{Ruby on Rails server-side Analytics Tracker for Google and more}
|
14
|
+
s.email = %q{maik.vlcek@mymobai.de}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/satellite.rb",
|
28
|
+
"lib/satellite/adapters/google_analytics.rb",
|
29
|
+
"lib/satellite/controllers/google_analytics.rb",
|
30
|
+
"lib/support/object.rb",
|
31
|
+
"lib/support/string.rb",
|
32
|
+
"satellite.gemspec",
|
33
|
+
"test/helper.rb",
|
34
|
+
"test/test_satellite.rb"
|
35
|
+
]
|
36
|
+
s.homepage = %q{http://github.com/mediavrog/satellite}
|
37
|
+
s.licenses = [%q{MIT}]
|
38
|
+
s.require_paths = [%q{lib}]
|
39
|
+
s.rubygems_version = %q{1.8.9}
|
40
|
+
s.summary = %q{Ruby on Rails server-side Analytics Tracker for Google and more}
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
49
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
52
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
54
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
58
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
59
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
60
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/test/helper.rb
CHANGED
@@ -14,5 +14,8 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
14
14
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
15
|
require 'satellite'
|
16
16
|
|
17
|
+
# used for storing private data like google account_id
|
18
|
+
require 'local_conf' if File.exists?('local_conf.rb')
|
19
|
+
|
17
20
|
class Test::Unit::TestCase
|
18
21
|
end
|
data/test/test_satellite.rb
CHANGED
@@ -1,7 +1,58 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class TestSatellite < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
should "create a proper google adapter" do
|
6
|
+
tracker = Satellite.get_tracker(:google_analytics)
|
7
|
+
assert_equal tracker.type, Satellite::Adapters::GoogleAnalytics
|
8
|
+
end
|
9
|
+
|
10
|
+
should "return any created tracker as tracker interface" do
|
11
|
+
tracker = Satellite.get_tracker(:google_analytics)
|
12
|
+
assert_equal tracker.class, Satellite::TrackerInterface
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'google_adapter' do
|
16
|
+
|
17
|
+
#http://www.google-analytics.com/__utm.gif?
|
18
|
+
#utmwv
|
19
|
+
#utms
|
20
|
+
#utmn
|
21
|
+
#utmhn
|
22
|
+
#utme
|
23
|
+
#utmcs
|
24
|
+
#utmsr
|
25
|
+
#utmsc
|
26
|
+
#utmul
|
27
|
+
#utmje
|
28
|
+
#utmfl
|
29
|
+
#utmdt=
|
30
|
+
#utmhid
|
31
|
+
#utmr
|
32
|
+
#utmp
|
33
|
+
#utmac
|
34
|
+
#utmcc
|
35
|
+
#utmu
|
36
|
+
should "properly track a page view" do
|
37
|
+
tracker = Satellite.get_tracker(:google_analytics, {
|
38
|
+
:utms => 1,
|
39
|
+
#:utmn => 123456789, autogenerated
|
40
|
+
:utmhn => 'api.mymobai.com',
|
41
|
+
:utme => '5(controller*action*coupon_redeem)(10)8(test)9(Please_track_this)11(1)',
|
42
|
+
:utmcn => 1,
|
43
|
+
:utmcs => 'UTF-8',
|
44
|
+
:utmsr => '1440x900',
|
45
|
+
:utmul => 'de',
|
46
|
+
:utmje => '1',
|
47
|
+
:utmfl => '10.3%20r183',
|
48
|
+
:utmdt => 'Properly track a page view',
|
49
|
+
#:utmhid => '1655425535', auto
|
50
|
+
:utmr => 'test.local/properly track a page view',
|
51
|
+
:utmp => '/test/properly-track-page-view',
|
52
|
+
:utmac => GOOGLE_ACCOUNT_ID
|
53
|
+
})
|
54
|
+
|
55
|
+
assert_equal tracker.track_page_view, true
|
56
|
+
end
|
6
57
|
end
|
7
58
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: satellite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Maik Vlcek
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-25 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -89,11 +89,17 @@ extra_rdoc_files:
|
|
89
89
|
files:
|
90
90
|
- .document
|
91
91
|
- Gemfile
|
92
|
+
- Gemfile.lock
|
92
93
|
- LICENSE.txt
|
93
94
|
- README.rdoc
|
94
95
|
- Rakefile
|
95
96
|
- VERSION
|
96
97
|
- lib/satellite.rb
|
98
|
+
- lib/satellite/adapters/google_analytics.rb
|
99
|
+
- lib/satellite/controllers/google_analytics.rb
|
100
|
+
- lib/support/object.rb
|
101
|
+
- lib/support/string.rb
|
102
|
+
- satellite.gemspec
|
97
103
|
- test/helper.rb
|
98
104
|
- test/test_satellite.rb
|
99
105
|
homepage: http://github.com/mediavrog/satellite
|