ab_panel 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +14 -12
- data/ab_panel.gemspec +2 -2
- data/example/app/controllers/application_controller.rb +1 -2
- data/example/app/controllers/posts_controller.rb +5 -18
- data/example/config/environments/development.rb +2 -0
- data/example/config/environments/production.rb +2 -0
- data/example/config/mixpanel.yml +4 -3
- data/lib/ab_panel/controller_additions.rb +75 -95
- data/lib/ab_panel/javascript.rb +1 -1
- data/lib/ab_panel/mixpanel.rb +25 -8
- data/lib/ab_panel/version.rb +1 -1
- data/lib/ab_panel.rb +15 -10
- metadata +19 -43
- data/example/config/initializers/mixpanel_middleware.rb +0 -2
- data/example/public/index.html +0 -241
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3ca41b9170ae4617dee1623e58c77c4964d71caa
|
4
|
+
data.tar.gz: b0a191f70c30e6efd7521cfbfde7b0acf79872ca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb555a360068bcbda0cd7242c97d93e58f2e81f55bf2752454bd5cd65a69bb8f92359e31e3807441e894a2bdcddb775aca292cc0ea5a9f9298c382536816baf7
|
7
|
+
data.tar.gz: 05a0bc19937ba1266539051a49ec892369cdebd2b20c37fd19af6eb4bcd13f7367d87f424ce18352789e58814e1d76662fccdfa900409da77b4524ab561aa8e1
|
data/README.md
CHANGED
@@ -40,19 +40,21 @@ You can add as many experiments and conditions as you want. Every visitor
|
|
40
40
|
will be assigned randomly to one condition for each scenario for as long as
|
41
41
|
their session remains active.
|
42
42
|
|
43
|
-
To track events in [Mixpanel](https://mixpanel.com),
|
44
|
-
api key, api secret, and the token of of your
|
43
|
+
To track events in [Mixpanel](https://mixpanel.com), create a file called
|
44
|
+
`config/mixpanel.yml` with your api key, api secret, and the token of of your
|
45
|
+
project for every environment you want to run Mixpanel in, like so:
|
45
46
|
|
46
47
|
```yaml
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
production:
|
49
|
+
api_key: 383340bfea74ab839ebb667ab3c59fa3
|
50
|
+
api_secret: 3990703d6d73d2b7fd78a1d19de66605
|
51
|
+
token: 735cc06a1b1ded4827d7faff385ad6fc
|
50
52
|
```
|
51
53
|
|
52
|
-
Enable the Mixpanel Middleware by
|
54
|
+
Enable the Mixpanel Middleware by adding it in the [necessary environments](example/config/environments/production.rb#L68):
|
53
55
|
|
54
56
|
```ruby
|
55
|
-
|
57
|
+
config.middleware.use Mixpanel::Middleware, AbPanel::Mixpanel::Config.token, persist: true
|
56
58
|
```
|
57
59
|
|
58
60
|
See [Mixpanel Gem docs](https://github.com/zevarito/mixpanel#rack-middleware) on the Middleware for more info.
|
@@ -61,7 +63,7 @@ In your application controller:
|
|
61
63
|
|
62
64
|
```ruby
|
63
65
|
class ApplicationController < ActionController::Base
|
64
|
-
initialize_ab_panel!
|
66
|
+
before_filter :initialize_ab_panel!
|
65
67
|
end
|
66
68
|
```
|
67
69
|
|
@@ -69,9 +71,9 @@ Then track any event you want from your controller:
|
|
69
71
|
|
70
72
|
```ruby
|
71
73
|
class CoursesController < ApplicationController
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
def show
|
75
|
+
track_action '[visits] Course', { :course => :id }
|
76
|
+
end
|
75
77
|
end
|
76
78
|
```
|
77
79
|
|
@@ -83,7 +85,7 @@ def show
|
|
83
85
|
track_variable :id, params[:id]
|
84
86
|
|
85
87
|
# Or a hash with variables
|
86
|
-
track_variables params
|
88
|
+
track_variables { id: params[:id], email: current_user.email }
|
87
89
|
end
|
88
90
|
```
|
89
91
|
|
data/ab_panel.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'ab_panel/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ab_panel"
|
8
8
|
spec.version = AbPanel::VERSION
|
9
|
-
spec.authors = ["Wouter de Vos"]
|
10
|
-
spec.email = ["wouter@springest.com"]
|
9
|
+
spec.authors = ["Wouter de Vos", "Mark Mulder"]
|
10
|
+
spec.email = ["wouter@springest.com", "markmulder@gmail.com"]
|
11
11
|
spec.description = %q{Run A/B test experiments on your Rails 3+ site using Mixpanel as a backend.}
|
12
12
|
spec.summary = %q{Run A/B test experiments on your Rails 3+ site using Mixpanel as a backend.}
|
13
13
|
spec.homepage = "https://github.com/Springest/ab_panel"
|
@@ -1,46 +1,37 @@
|
|
1
1
|
class PostsController < ApplicationController
|
2
|
-
track_action '[visits] post', :post => :id, :only => [ :show ]
|
3
|
-
|
4
|
-
# GET /posts
|
5
|
-
# GET /posts.json
|
6
2
|
def index
|
7
3
|
@posts = Post.all
|
8
4
|
|
9
5
|
respond_to do |format|
|
10
|
-
format.html
|
6
|
+
format.html
|
11
7
|
format.json { render json: @posts }
|
12
8
|
end
|
13
9
|
end
|
14
10
|
|
15
|
-
# GET /posts/1
|
16
|
-
# GET /posts/1.json
|
17
11
|
def show
|
18
12
|
@post = Post.find(params[:id])
|
19
13
|
|
20
14
|
respond_to do |format|
|
21
|
-
format.html
|
15
|
+
format.html
|
22
16
|
format.json { render json: @post }
|
23
17
|
end
|
18
|
+
|
19
|
+
track_action '[visits] post', :post => :id
|
24
20
|
end
|
25
21
|
|
26
|
-
# GET /posts/new
|
27
|
-
# GET /posts/new.json
|
28
22
|
def new
|
29
23
|
@post = Post.new
|
30
24
|
|
31
25
|
respond_to do |format|
|
32
|
-
format.html
|
26
|
+
format.html
|
33
27
|
format.json { render json: @post }
|
34
28
|
end
|
35
29
|
end
|
36
30
|
|
37
|
-
# GET /posts/1/edit
|
38
31
|
def edit
|
39
32
|
@post = Post.find(params[:id])
|
40
33
|
end
|
41
34
|
|
42
|
-
# POST /posts
|
43
|
-
# POST /posts.json
|
44
35
|
def create
|
45
36
|
@post = Post.new(params[:post])
|
46
37
|
|
@@ -55,8 +46,6 @@ class PostsController < ApplicationController
|
|
55
46
|
end
|
56
47
|
end
|
57
48
|
|
58
|
-
# PUT /posts/1
|
59
|
-
# PUT /posts/1.json
|
60
49
|
def update
|
61
50
|
@post = Post.find(params[:id])
|
62
51
|
|
@@ -71,8 +60,6 @@ class PostsController < ApplicationController
|
|
71
60
|
end
|
72
61
|
end
|
73
62
|
|
74
|
-
# DELETE /posts/1
|
75
|
-
# DELETE /posts/1.json
|
76
63
|
def destroy
|
77
64
|
@post = Post.find(params[:id])
|
78
65
|
@post.destroy
|
@@ -64,4 +64,6 @@ Example::Application.configure do
|
|
64
64
|
# Log the query plan for queries taking more than this (works
|
65
65
|
# with SQLite, MySQL, and PostgreSQL)
|
66
66
|
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
67
|
+
|
68
|
+
config.middleware.use Mixpanel::Middleware, AbPanel::Mixpanel::Config.token, persist: true
|
67
69
|
end
|
data/example/config/mixpanel.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
development:
|
2
|
+
api_key: 383340bfea74ab839ebb667ab3c59fa3
|
3
|
+
api_secret: 3990703d6d73d2b7fd78a1d19de66605
|
4
|
+
token: 735cc06a1b1ded4827d7faff385ad6fc
|
@@ -26,114 +26,94 @@ module AbPanel
|
|
26
26
|
# own implementation, e.g.:
|
27
27
|
#
|
28
28
|
# `current_user.id` for logged in users.
|
29
|
-
def
|
30
|
-
session['
|
29
|
+
def distinct_id
|
30
|
+
session['distinct_id'] ||=
|
31
31
|
(0..4).map { |i| i.even? ? ('A'..'Z').to_a[rand(26)] : rand(10) }.join
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
def ab_panel_options
|
35
|
+
@ab_panel_options ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
# Initializes AbPanel's environment.
|
35
39
|
#
|
36
|
-
#
|
37
|
-
#
|
40
|
+
# Typically, this would go in a global before filter.
|
41
|
+
#
|
42
|
+
# class ApplicationController < ActionController::Base
|
43
|
+
# before_filter :initialize_ab_panel!
|
44
|
+
# end
|
38
45
|
#
|
39
|
-
#
|
40
|
-
|
46
|
+
# This makes sure an ab_panel session is re-initialized on every
|
47
|
+
# request. Experiment conditions and unique user id are preserved
|
48
|
+
# in the user's session.
|
49
|
+
def initialize_ab_panel!(options = {})
|
50
|
+
AbPanel.reset!
|
51
|
+
AbPanel.conditions = session['ab_panel_conditions']
|
52
|
+
session['ab_panel_conditions'] = AbPanel.conditions
|
53
|
+
|
41
54
|
{
|
42
|
-
'
|
43
|
-
'
|
44
|
-
'
|
45
|
-
|
46
|
-
|
47
|
-
|
55
|
+
'distinct_id' => distinct_id,
|
56
|
+
'rack.session' => request['rack.session'],
|
57
|
+
'ip' => request.remote_ip
|
58
|
+
}.each do |key, value|
|
59
|
+
AbPanel.set_env(key, value)
|
60
|
+
end
|
48
61
|
end
|
49
62
|
|
50
|
-
|
51
|
-
|
52
|
-
|
63
|
+
# Track controller actions visits.
|
64
|
+
#
|
65
|
+
# name - The name of the event in Mixpanel.
|
66
|
+
# properties - The properties to be associated with the event.
|
67
|
+
#
|
68
|
+
# Example:
|
69
|
+
#
|
70
|
+
# def show
|
71
|
+
# track_action '[visits] Course', { :course => :id }
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# This will track the event with the given name on CoursesController#show
|
75
|
+
# and assign an options hash:
|
76
|
+
#
|
77
|
+
# { 'course_id' => @course.id }
|
78
|
+
def track_action(name, properties = {})
|
79
|
+
funnel = properties.delete(:funnel)
|
80
|
+
AbPanel.funnels << funnel if funnel.present?
|
81
|
+
|
82
|
+
options = {
|
83
|
+
distinct_id: distinct_id,
|
84
|
+
ip: request.remote_ip,
|
85
|
+
time: Time.now.utc,
|
86
|
+
}
|
53
87
|
|
54
|
-
|
55
|
-
|
56
|
-
#
|
57
|
-
# Typically, this would go in the ApplicationController.
|
58
|
-
#
|
59
|
-
# class ApplicationController < ActionController::Base
|
60
|
-
# initialize_ab_panel!
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# This makes sure an ab_panel session is re-initialized on every
|
64
|
-
# request. Experiment conditions and unique user id are preserved
|
65
|
-
# in the user's session.
|
66
|
-
def initialize_ab_panel!(options={})
|
67
|
-
self.before_filter(options.slice(:only, :except)) do |controller|
|
68
|
-
# Persist the conditions.
|
69
|
-
AbPanel.conditions = controller.session['ab_panel_conditions']
|
70
|
-
controller.session['ab_panel_conditions'] = AbPanel.conditions
|
71
|
-
|
72
|
-
{
|
73
|
-
'ab_panel_id' => controller.ab_panel_id
|
74
|
-
}.merge(controller.ab_panel_env).each do |key, val|
|
75
|
-
AbPanel.env_set key, val
|
76
|
-
end
|
77
|
-
end
|
88
|
+
AbPanel.funnels.each do |funnel|
|
89
|
+
options["funnel_#{funnel}"] = true
|
78
90
|
end
|
79
91
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
AbPanel.funnels << funnel if funnel.present?
|
99
|
-
|
100
|
-
options = {
|
101
|
-
distinct_id: controller.ab_panel_id,
|
102
|
-
ip: controller.request.remote_ip,
|
103
|
-
time: Time.now.utc,
|
104
|
-
}
|
105
|
-
|
106
|
-
AbPanel.funnels.each do |funnel|
|
107
|
-
options["funnel_#{funnel}"] = true
|
108
|
-
end
|
109
|
-
|
110
|
-
AbPanel.experiments.each do |exp|
|
111
|
-
options[exp] = AbPanel.conditions.send(exp).condition rescue nil
|
112
|
-
end
|
113
|
-
|
114
|
-
properties.each do |key, val|
|
115
|
-
if controller.respond_to?(key)
|
116
|
-
inst = controller.send(key)
|
117
|
-
elsif controller.instance_variable_defined?("@#{key}")
|
118
|
-
inst = controller.instance_variable_get("@#{key}")
|
119
|
-
else
|
120
|
-
options[key] = val
|
121
|
-
next
|
122
|
-
end
|
123
|
-
|
124
|
-
val = *val
|
125
|
-
|
126
|
-
val.each do |m|
|
127
|
-
options["#{key}_#{m}"] = inst.send(m)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
AbPanel.identify(controller.ab_panel_id)
|
132
|
-
AbPanel.track name, options.merge(controller.ab_panel_options)
|
133
|
-
|
134
|
-
controller.session['mixpanel_events'] ||= AbPanel.env['rack.session']['mixpanel_events'] rescue []
|
92
|
+
AbPanel.experiments.each do |exp|
|
93
|
+
options[exp] = AbPanel.conditions.send(exp).condition rescue nil
|
94
|
+
end
|
95
|
+
|
96
|
+
properties.each do |key, val|
|
97
|
+
if respond_to?(key)
|
98
|
+
inst = send(key)
|
99
|
+
elsif instance_variable_defined?("@#{key}")
|
100
|
+
inst = instance_variable_get("@#{key}")
|
101
|
+
else
|
102
|
+
options[key] = val
|
103
|
+
next
|
104
|
+
end
|
105
|
+
|
106
|
+
val = *val
|
107
|
+
|
108
|
+
val.each do |m|
|
109
|
+
options["#{key}_#{m}"] = inst.send(m)
|
135
110
|
end
|
136
111
|
end
|
112
|
+
|
113
|
+
AbPanel.identify(distinct_id)
|
114
|
+
AbPanel.track(name, options.merge(ab_panel_options))
|
115
|
+
|
116
|
+
session['mixpanel_events'] ||= AbPanel.env['rack.session']['mixpanel_events'] rescue []
|
137
117
|
end
|
138
118
|
end
|
139
119
|
end
|
data/lib/ab_panel/javascript.rb
CHANGED
data/lib/ab_panel/mixpanel.rb
CHANGED
@@ -3,13 +3,14 @@ require 'mixpanel'
|
|
3
3
|
module AbPanel
|
4
4
|
module Mixpanel
|
5
5
|
class Tracker < ::Mixpanel::Tracker
|
6
|
-
def initialize(options={})
|
6
|
+
def initialize(options = {})
|
7
|
+
return if !should_track?
|
8
|
+
|
7
9
|
@tracker = ::Mixpanel::Tracker.new Config.token, ab_panel_options.merge(options)
|
8
10
|
end
|
9
11
|
|
10
12
|
def ab_panel_options
|
11
13
|
opts = {
|
12
|
-
api_key: Config.api_key,
|
13
14
|
env: AbPanel.env,
|
14
15
|
persist: true
|
15
16
|
}
|
@@ -22,26 +23,42 @@ module AbPanel
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def track(event_name, properties)
|
26
|
+
return if !should_track?
|
27
|
+
|
25
28
|
@tracker.append_track event_name, properties
|
26
29
|
end
|
27
30
|
|
28
31
|
def identify(distinct_id)
|
32
|
+
return if !should_track?
|
33
|
+
|
29
34
|
@tracker.append_identify distinct_id
|
30
35
|
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def should_track?
|
40
|
+
@should_track ||= Config.environments.include?(Rails.env)
|
41
|
+
end
|
31
42
|
end
|
32
43
|
|
33
44
|
class Config
|
34
|
-
def self.
|
35
|
-
config['
|
45
|
+
def self.token
|
46
|
+
config[Rails.env]['token']
|
36
47
|
end
|
37
48
|
|
38
|
-
def self.
|
39
|
-
config
|
49
|
+
def self.environments
|
50
|
+
config.keys
|
40
51
|
end
|
41
52
|
|
42
53
|
def self.config
|
43
|
-
@settings ||=
|
44
|
-
|
54
|
+
@settings ||= load_config
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def self.load_config
|
60
|
+
file = File.read(File.join(Rails.root, 'config', 'mixpanel.yml'))
|
61
|
+
YAML.load(file)
|
45
62
|
end
|
46
63
|
end
|
47
64
|
end
|
data/lib/ab_panel/version.rb
CHANGED
data/lib/ab_panel.rb
CHANGED
@@ -11,8 +11,8 @@ module AbPanel
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Identify
|
14
|
-
def identify(
|
15
|
-
tracker.identify
|
14
|
+
def identify(distinct_id)
|
15
|
+
tracker.identify distinct_id
|
16
16
|
end
|
17
17
|
|
18
18
|
def conditions
|
@@ -36,20 +36,25 @@ module AbPanel
|
|
36
36
|
config.scenarios experiment
|
37
37
|
end
|
38
38
|
|
39
|
-
def env_set key, val
|
40
|
-
env[key] = val
|
41
|
-
end
|
42
|
-
|
43
|
-
def funnels
|
44
|
-
env['funnels'] ||= []
|
45
|
-
end
|
46
|
-
|
47
39
|
def env
|
48
40
|
@env ||= {
|
49
41
|
'conditions' => conditions
|
50
42
|
}
|
51
43
|
end
|
52
44
|
|
45
|
+
def reset!
|
46
|
+
@env = nil
|
47
|
+
@conditions = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_env(key, value)
|
51
|
+
env[key] = value
|
52
|
+
end
|
53
|
+
|
54
|
+
def funnels
|
55
|
+
env['funnels'] ||= []
|
56
|
+
end
|
57
|
+
|
53
58
|
private # ----------------------------------------------------------------------------
|
54
59
|
|
55
60
|
def assign_conditions!(already_assigned=nil)
|
metadata
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ab_panel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Wouter de Vos
|
8
|
+
- Mark Mulder
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
17
|
requirements:
|
19
18
|
- - ~>
|
20
19
|
- !ruby/object:Gem::Version
|
@@ -22,7 +21,6 @@ dependencies:
|
|
22
21
|
type: :development
|
23
22
|
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
25
|
- - ~>
|
28
26
|
- !ruby/object:Gem::Version
|
@@ -30,7 +28,6 @@ dependencies:
|
|
30
28
|
- !ruby/object:Gem::Dependency
|
31
29
|
name: rails
|
32
30
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
31
|
requirements:
|
35
32
|
- - ~>
|
36
33
|
- !ruby/object:Gem::Version
|
@@ -38,7 +35,6 @@ dependencies:
|
|
38
35
|
type: :development
|
39
36
|
prerelease: false
|
40
37
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
38
|
requirements:
|
43
39
|
- - ~>
|
44
40
|
- !ruby/object:Gem::Version
|
@@ -46,86 +42,77 @@ dependencies:
|
|
46
42
|
- !ruby/object:Gem::Dependency
|
47
43
|
name: rake
|
48
44
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
45
|
requirements:
|
51
|
-
- -
|
46
|
+
- - '>='
|
52
47
|
- !ruby/object:Gem::Version
|
53
48
|
version: '0'
|
54
49
|
type: :development
|
55
50
|
prerelease: false
|
56
51
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
52
|
requirements:
|
59
|
-
- -
|
53
|
+
- - '>='
|
60
54
|
- !ruby/object:Gem::Version
|
61
55
|
version: '0'
|
62
56
|
- !ruby/object:Gem::Dependency
|
63
57
|
name: fakeweb
|
64
58
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
59
|
requirements:
|
67
|
-
- -
|
60
|
+
- - '>='
|
68
61
|
- !ruby/object:Gem::Version
|
69
62
|
version: '0'
|
70
63
|
type: :development
|
71
64
|
prerelease: false
|
72
65
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
66
|
requirements:
|
75
|
-
- -
|
67
|
+
- - '>='
|
76
68
|
- !ruby/object:Gem::Version
|
77
69
|
version: '0'
|
78
70
|
- !ruby/object:Gem::Dependency
|
79
71
|
name: rspec
|
80
72
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
73
|
requirements:
|
83
|
-
- -
|
74
|
+
- - '>='
|
84
75
|
- !ruby/object:Gem::Version
|
85
76
|
version: '0'
|
86
77
|
type: :development
|
87
78
|
prerelease: false
|
88
79
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
80
|
requirements:
|
91
|
-
- -
|
81
|
+
- - '>='
|
92
82
|
- !ruby/object:Gem::Version
|
93
83
|
version: '0'
|
94
84
|
- !ruby/object:Gem::Dependency
|
95
85
|
name: debugger
|
96
86
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
87
|
requirements:
|
99
|
-
- -
|
88
|
+
- - '>='
|
100
89
|
- !ruby/object:Gem::Version
|
101
90
|
version: '0'
|
102
91
|
type: :development
|
103
92
|
prerelease: false
|
104
93
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
94
|
requirements:
|
107
|
-
- -
|
95
|
+
- - '>='
|
108
96
|
- !ruby/object:Gem::Version
|
109
97
|
version: '0'
|
110
98
|
- !ruby/object:Gem::Dependency
|
111
99
|
name: mixpanel
|
112
100
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
101
|
requirements:
|
115
|
-
- -
|
102
|
+
- - '>='
|
116
103
|
- !ruby/object:Gem::Version
|
117
104
|
version: '0'
|
118
105
|
type: :runtime
|
119
106
|
prerelease: false
|
120
107
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
108
|
requirements:
|
123
|
-
- -
|
109
|
+
- - '>='
|
124
110
|
- !ruby/object:Gem::Version
|
125
111
|
version: '0'
|
126
112
|
description: Run A/B test experiments on your Rails 3+ site using Mixpanel as a backend.
|
127
113
|
email:
|
128
114
|
- wouter@springest.com
|
115
|
+
- markmulder@gmail.com
|
129
116
|
executables: []
|
130
117
|
extensions: []
|
131
118
|
extra_rdoc_files: []
|
@@ -172,7 +159,6 @@ files:
|
|
172
159
|
- example/config/initializers/backtrace_silencers.rb
|
173
160
|
- example/config/initializers/inflections.rb
|
174
161
|
- example/config/initializers/mime_types.rb
|
175
|
-
- example/config/initializers/mixpanel_middleware.rb
|
176
162
|
- example/config/initializers/secret_token.rb
|
177
163
|
- example/config/initializers/session_store.rb
|
178
164
|
- example/config/initializers/wrap_parameters.rb
|
@@ -189,7 +175,6 @@ files:
|
|
189
175
|
- example/public/422.html
|
190
176
|
- example/public/500.html
|
191
177
|
- example/public/favicon.ico
|
192
|
-
- example/public/index.html
|
193
178
|
- example/public/robots.txt
|
194
179
|
- example/script/rails
|
195
180
|
- example/test/fixtures/.gitkeep
|
@@ -220,33 +205,26 @@ files:
|
|
220
205
|
homepage: https://github.com/Springest/ab_panel
|
221
206
|
licenses:
|
222
207
|
- MIT
|
208
|
+
metadata: {}
|
223
209
|
post_install_message:
|
224
210
|
rdoc_options: []
|
225
211
|
require_paths:
|
226
212
|
- lib
|
227
213
|
required_ruby_version: !ruby/object:Gem::Requirement
|
228
|
-
none: false
|
229
214
|
requirements:
|
230
|
-
- -
|
215
|
+
- - '>='
|
231
216
|
- !ruby/object:Gem::Version
|
232
217
|
version: '0'
|
233
|
-
segments:
|
234
|
-
- 0
|
235
|
-
hash: 4086507119517691462
|
236
218
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
|
-
none: false
|
238
219
|
requirements:
|
239
|
-
- -
|
220
|
+
- - '>='
|
240
221
|
- !ruby/object:Gem::Version
|
241
222
|
version: '0'
|
242
|
-
segments:
|
243
|
-
- 0
|
244
|
-
hash: 4086507119517691462
|
245
223
|
requirements: []
|
246
224
|
rubyforge_project:
|
247
|
-
rubygems_version:
|
225
|
+
rubygems_version: 2.0.3
|
248
226
|
signing_key:
|
249
|
-
specification_version:
|
227
|
+
specification_version: 4
|
250
228
|
summary: Run A/B test experiments on your Rails 3+ site using Mixpanel as a backend.
|
251
229
|
test_files:
|
252
230
|
- example/.gitignore
|
@@ -284,7 +262,6 @@ test_files:
|
|
284
262
|
- example/config/initializers/backtrace_silencers.rb
|
285
263
|
- example/config/initializers/inflections.rb
|
286
264
|
- example/config/initializers/mime_types.rb
|
287
|
-
- example/config/initializers/mixpanel_middleware.rb
|
288
265
|
- example/config/initializers/secret_token.rb
|
289
266
|
- example/config/initializers/session_store.rb
|
290
267
|
- example/config/initializers/wrap_parameters.rb
|
@@ -301,7 +278,6 @@ test_files:
|
|
301
278
|
- example/public/422.html
|
302
279
|
- example/public/500.html
|
303
280
|
- example/public/favicon.ico
|
304
|
-
- example/public/index.html
|
305
281
|
- example/public/robots.txt
|
306
282
|
- example/script/rails
|
307
283
|
- example/test/fixtures/.gitkeep
|
data/example/public/index.html
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title>Ruby on Rails: Welcome aboard</title>
|
5
|
-
<style type="text/css" media="screen">
|
6
|
-
body {
|
7
|
-
margin: 0;
|
8
|
-
margin-bottom: 25px;
|
9
|
-
padding: 0;
|
10
|
-
background-color: #f0f0f0;
|
11
|
-
font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
|
12
|
-
font-size: 13px;
|
13
|
-
color: #333;
|
14
|
-
}
|
15
|
-
|
16
|
-
h1 {
|
17
|
-
font-size: 28px;
|
18
|
-
color: #000;
|
19
|
-
}
|
20
|
-
|
21
|
-
a {color: #03c}
|
22
|
-
a:hover {
|
23
|
-
background-color: #03c;
|
24
|
-
color: white;
|
25
|
-
text-decoration: none;
|
26
|
-
}
|
27
|
-
|
28
|
-
|
29
|
-
#page {
|
30
|
-
background-color: #f0f0f0;
|
31
|
-
width: 750px;
|
32
|
-
margin: 0;
|
33
|
-
margin-left: auto;
|
34
|
-
margin-right: auto;
|
35
|
-
}
|
36
|
-
|
37
|
-
#content {
|
38
|
-
float: left;
|
39
|
-
background-color: white;
|
40
|
-
border: 3px solid #aaa;
|
41
|
-
border-top: none;
|
42
|
-
padding: 25px;
|
43
|
-
width: 500px;
|
44
|
-
}
|
45
|
-
|
46
|
-
#sidebar {
|
47
|
-
float: right;
|
48
|
-
width: 175px;
|
49
|
-
}
|
50
|
-
|
51
|
-
#footer {
|
52
|
-
clear: both;
|
53
|
-
}
|
54
|
-
|
55
|
-
#header, #about, #getting-started {
|
56
|
-
padding-left: 75px;
|
57
|
-
padding-right: 30px;
|
58
|
-
}
|
59
|
-
|
60
|
-
|
61
|
-
#header {
|
62
|
-
background-image: url("assets/rails.png");
|
63
|
-
background-repeat: no-repeat;
|
64
|
-
background-position: top left;
|
65
|
-
height: 64px;
|
66
|
-
}
|
67
|
-
#header h1, #header h2 {margin: 0}
|
68
|
-
#header h2 {
|
69
|
-
color: #888;
|
70
|
-
font-weight: normal;
|
71
|
-
font-size: 16px;
|
72
|
-
}
|
73
|
-
|
74
|
-
|
75
|
-
#about h3 {
|
76
|
-
margin: 0;
|
77
|
-
margin-bottom: 10px;
|
78
|
-
font-size: 14px;
|
79
|
-
}
|
80
|
-
|
81
|
-
#about-content {
|
82
|
-
background-color: #ffd;
|
83
|
-
border: 1px solid #fc0;
|
84
|
-
margin-left: -55px;
|
85
|
-
margin-right: -10px;
|
86
|
-
}
|
87
|
-
#about-content table {
|
88
|
-
margin-top: 10px;
|
89
|
-
margin-bottom: 10px;
|
90
|
-
font-size: 11px;
|
91
|
-
border-collapse: collapse;
|
92
|
-
}
|
93
|
-
#about-content td {
|
94
|
-
padding: 10px;
|
95
|
-
padding-top: 3px;
|
96
|
-
padding-bottom: 3px;
|
97
|
-
}
|
98
|
-
#about-content td.name {color: #555}
|
99
|
-
#about-content td.value {color: #000}
|
100
|
-
|
101
|
-
#about-content ul {
|
102
|
-
padding: 0;
|
103
|
-
list-style-type: none;
|
104
|
-
}
|
105
|
-
|
106
|
-
#about-content.failure {
|
107
|
-
background-color: #fcc;
|
108
|
-
border: 1px solid #f00;
|
109
|
-
}
|
110
|
-
#about-content.failure p {
|
111
|
-
margin: 0;
|
112
|
-
padding: 10px;
|
113
|
-
}
|
114
|
-
|
115
|
-
|
116
|
-
#getting-started {
|
117
|
-
border-top: 1px solid #ccc;
|
118
|
-
margin-top: 25px;
|
119
|
-
padding-top: 15px;
|
120
|
-
}
|
121
|
-
#getting-started h1 {
|
122
|
-
margin: 0;
|
123
|
-
font-size: 20px;
|
124
|
-
}
|
125
|
-
#getting-started h2 {
|
126
|
-
margin: 0;
|
127
|
-
font-size: 14px;
|
128
|
-
font-weight: normal;
|
129
|
-
color: #333;
|
130
|
-
margin-bottom: 25px;
|
131
|
-
}
|
132
|
-
#getting-started ol {
|
133
|
-
margin-left: 0;
|
134
|
-
padding-left: 0;
|
135
|
-
}
|
136
|
-
#getting-started li {
|
137
|
-
font-size: 18px;
|
138
|
-
color: #888;
|
139
|
-
margin-bottom: 25px;
|
140
|
-
}
|
141
|
-
#getting-started li h2 {
|
142
|
-
margin: 0;
|
143
|
-
font-weight: normal;
|
144
|
-
font-size: 18px;
|
145
|
-
color: #333;
|
146
|
-
}
|
147
|
-
#getting-started li p {
|
148
|
-
color: #555;
|
149
|
-
font-size: 13px;
|
150
|
-
}
|
151
|
-
|
152
|
-
|
153
|
-
#sidebar ul {
|
154
|
-
margin-left: 0;
|
155
|
-
padding-left: 0;
|
156
|
-
}
|
157
|
-
#sidebar ul h3 {
|
158
|
-
margin-top: 25px;
|
159
|
-
font-size: 16px;
|
160
|
-
padding-bottom: 10px;
|
161
|
-
border-bottom: 1px solid #ccc;
|
162
|
-
}
|
163
|
-
#sidebar li {
|
164
|
-
list-style-type: none;
|
165
|
-
}
|
166
|
-
#sidebar ul.links li {
|
167
|
-
margin-bottom: 5px;
|
168
|
-
}
|
169
|
-
|
170
|
-
.filename {
|
171
|
-
font-style: italic;
|
172
|
-
}
|
173
|
-
</style>
|
174
|
-
<script type="text/javascript">
|
175
|
-
function about() {
|
176
|
-
info = document.getElementById('about-content');
|
177
|
-
if (window.XMLHttpRequest)
|
178
|
-
{ xhr = new XMLHttpRequest(); }
|
179
|
-
else
|
180
|
-
{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
|
181
|
-
xhr.open("GET","rails/info/properties",false);
|
182
|
-
xhr.send("");
|
183
|
-
info.innerHTML = xhr.responseText;
|
184
|
-
info.style.display = 'block'
|
185
|
-
}
|
186
|
-
</script>
|
187
|
-
</head>
|
188
|
-
<body>
|
189
|
-
<div id="page">
|
190
|
-
<div id="sidebar">
|
191
|
-
<ul id="sidebar-items">
|
192
|
-
<li>
|
193
|
-
<h3>Browse the documentation</h3>
|
194
|
-
<ul class="links">
|
195
|
-
<li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
|
196
|
-
<li><a href="http://api.rubyonrails.org/">Rails API</a></li>
|
197
|
-
<li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li>
|
198
|
-
<li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li>
|
199
|
-
</ul>
|
200
|
-
</li>
|
201
|
-
</ul>
|
202
|
-
</div>
|
203
|
-
|
204
|
-
<div id="content">
|
205
|
-
<div id="header">
|
206
|
-
<h1>Welcome aboard</h1>
|
207
|
-
<h2>You’re riding Ruby on Rails!</h2>
|
208
|
-
</div>
|
209
|
-
|
210
|
-
<div id="about">
|
211
|
-
<h3><a href="rails/info/properties" onclick="about(); return false">About your application’s environment</a></h3>
|
212
|
-
<div id="about-content" style="display: none"></div>
|
213
|
-
</div>
|
214
|
-
|
215
|
-
<div id="getting-started">
|
216
|
-
<h1>Getting started</h1>
|
217
|
-
<h2>Here’s how to get rolling:</h2>
|
218
|
-
|
219
|
-
<ol>
|
220
|
-
<li>
|
221
|
-
<h2>Use <code>rails generate</code> to create your models and controllers</h2>
|
222
|
-
<p>To see all available options, run it without parameters.</p>
|
223
|
-
</li>
|
224
|
-
|
225
|
-
<li>
|
226
|
-
<h2>Set up a default route and remove <span class="filename">public/index.html</span></h2>
|
227
|
-
<p>Routes are set up in <span class="filename">config/routes.rb</span>.</p>
|
228
|
-
</li>
|
229
|
-
|
230
|
-
<li>
|
231
|
-
<h2>Create your database</h2>
|
232
|
-
<p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p>
|
233
|
-
</li>
|
234
|
-
</ol>
|
235
|
-
</div>
|
236
|
-
</div>
|
237
|
-
|
238
|
-
<div id="footer"> </div>
|
239
|
-
</div>
|
240
|
-
</body>
|
241
|
-
</html>
|