fluidfeatures-rails 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ class FluidFeatureAjaxController < ApplicationController
|
|
3
3
|
|
4
4
|
def index
|
5
5
|
render :json => {
|
6
|
-
:enabled => fluidfeature(params[:feature_name])
|
6
|
+
:enabled => fluidfeature(params[:feature_name], params[:version_name])
|
7
7
|
}, :status => 200
|
8
8
|
end
|
9
9
|
end
|
@@ -14,7 +14,7 @@ end
|
|
14
14
|
|
15
15
|
class FluidGoalAjaxController < ApplicationController
|
16
16
|
def index
|
17
|
-
fluidgoal(params[:goal_name],
|
17
|
+
fluidgoal(params[:goal_name], params[:goal_version])
|
18
18
|
render :json => {}, :status => 200
|
19
19
|
end
|
20
20
|
end
|
data/lib/fluidfeatures/rails.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
|
-
require "fluidfeatures
|
2
|
+
require "fluidfeatures"
|
3
3
|
|
4
4
|
module FluidFeatures
|
5
5
|
module Rails
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :enabled
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :ff_app
|
10
10
|
end
|
11
11
|
|
12
12
|
#
|
@@ -31,24 +31,17 @@ module FluidFeatures
|
|
31
31
|
end
|
32
32
|
$stderr.puts "=> fluidfeatures-rails initializing as app #{ENV["FLUIDFEATURES_APPID"]} with #{ENV["FLUIDFEATURES_BASEURI"]}"
|
33
33
|
|
34
|
-
|
35
|
-
require 'net/http'
|
36
|
-
require 'persistent_http'
|
37
|
-
|
38
34
|
::Rails::Application.initializer "fluidfeatures.initializer" do
|
39
35
|
ActiveSupport.on_load(:action_controller) do
|
40
36
|
api_baseuri = ENV["FLUIDFEATURES_BASEURI"]
|
41
37
|
api_appid = ENV["FLUIDFEATURES_APPID"]
|
42
38
|
api_secret = ENV["FLUIDFEATURES_SECRET"]
|
43
39
|
|
44
|
-
::FluidFeatures::Rails.
|
40
|
+
::FluidFeatures::Rails.ff_app = ::FluidFeatures.app(
|
45
41
|
api_baseuri,
|
46
42
|
api_appid,
|
47
43
|
api_secret,
|
48
|
-
|
49
|
-
{
|
50
|
-
:logger => nil,#::Rails.logger
|
51
|
-
}
|
44
|
+
#::Rails.logger
|
52
45
|
)
|
53
46
|
|
54
47
|
ActionController::Base.append_before_filter :fluidfeatures_request_before
|
@@ -58,13 +51,13 @@ module FluidFeatures
|
|
58
51
|
|
59
52
|
@enabled = true
|
60
53
|
end
|
61
|
-
|
54
|
+
|
62
55
|
end
|
63
56
|
end
|
64
57
|
|
65
58
|
module ActionController
|
66
59
|
class Base
|
67
|
-
|
60
|
+
|
68
61
|
# allow fluidfeature to be called from templates
|
69
62
|
helper_method :fluidfeature
|
70
63
|
|
@@ -76,42 +69,48 @@ module ActionController
|
|
76
69
|
#
|
77
70
|
def fluidfeatures_initialize_user
|
78
71
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
72
|
+
# call app defined method "fluidfeatures_current_user"
|
73
|
+
user = nil
|
74
|
+
begin
|
75
|
+
user = fluidfeatures_current_user(verbose=true)
|
76
|
+
rescue NoMethodError
|
77
|
+
::Rails.logger.error "[FF] Method fluidfeatures_current_user is not defined in your ApplicationController"
|
78
|
+
return nil
|
79
|
+
end
|
80
|
+
unless user.is_a? Hash
|
81
|
+
raise "fluidfeatures_current_user returned invalid user (Hash expected) : #{user}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# default to anonymous is not user id given
|
85
|
+
user[:anonymous] = false unless user[:id]
|
86
|
+
|
87
|
+
# if no user id given, then attempt to get the unique id of this visitor from the cookie
|
88
|
+
user[:id] ||= cookies[:fluidfeatures_anonymous]
|
82
89
|
|
83
|
-
|
84
|
-
|
90
|
+
@ff_user = ::FluidFeatures::Rails.ff_app.user(
|
91
|
+
user[:id],
|
92
|
+
user[:name],
|
93
|
+
!!user[:anonymous],
|
94
|
+
user[:uniques],
|
95
|
+
user[:cohorts]
|
96
|
+
)
|
97
|
+
|
98
|
+
# Set/delete cookies for anonymous users
|
99
|
+
if @ff_user.anonymous
|
100
|
+
# update the cookie, with the unique id of this user
|
101
|
+
cookies[:fluidfeatures_anonymous] = @ff_user.unique_id
|
102
|
+
else
|
103
|
+
# We are no longer an anoymous user. Delete the cookie
|
85
104
|
if cookies.has_key? :fluidfeatures_anonymous
|
86
105
|
cookies.delete(:fluidfeatures_anonymous)
|
87
106
|
end
|
88
|
-
else
|
89
|
-
# We're an anonymous user
|
90
|
-
user[:anonymous] = true
|
91
|
-
|
92
|
-
# if we were not given a user[:id] for this anonymous user, then get
|
93
|
-
# it from an existing cookie or create a new one.
|
94
|
-
unless user[:id]
|
95
|
-
# Have we seen them before?
|
96
|
-
if cookies.has_key? :fluidfeatures_anonymous
|
97
|
-
user[:id] = cookies[:fluidfeatures_anonymous]
|
98
|
-
else
|
99
|
-
# Create new cookie. Use rand + micro-seconds of current time
|
100
|
-
user[:id] = "anon-" + Random.rand(9999999999).to_s + "-" + ((Time.now.to_f * 1000000).to_i % 1000000).to_s
|
101
|
-
end
|
102
|
-
end
|
103
|
-
# update the cookie, with whatever the user[:id] has been set to
|
104
|
-
cookies[:fluidfeatures_anonymous] = user[:id]
|
105
107
|
end
|
106
|
-
|
107
|
-
@ff_user
|
108
|
+
|
109
|
+
@ff_user
|
108
110
|
end
|
109
111
|
|
110
112
|
def fluidfeatures_user
|
111
|
-
|
112
|
-
fluidfeatures_initialize_user
|
113
|
-
end
|
114
|
-
@ff_user
|
113
|
+
@ff_user ||= fluidfeatures_initialize_user
|
115
114
|
end
|
116
115
|
|
117
116
|
#
|
@@ -120,51 +119,25 @@ module ActionController
|
|
120
119
|
# current user.
|
121
120
|
# We call user_id to get the current user's unique id.
|
122
121
|
#
|
123
|
-
def fluidfeature(feature_name,
|
124
|
-
if
|
125
|
-
|
122
|
+
def fluidfeature(feature_name, version_name=nil, default_enabled=nil)
|
123
|
+
if default_enabled == nil and (version_name.is_a? FalseClass or version_name.is_a? TrueClass)
|
124
|
+
default_enabled = version_name
|
125
|
+
version_name = nil
|
126
126
|
end
|
127
|
-
unless
|
128
|
-
|
127
|
+
unless default_enabled.is_a? FalseClass or default_enabled.is_a? TrueClass
|
128
|
+
default_enabled = fluidfeatures_default_enabled
|
129
129
|
end
|
130
|
-
|
131
|
-
|
132
|
-
if not @ff_features
|
133
|
-
fluidfeatures_retrieve_user_features
|
134
|
-
end
|
135
|
-
if @ff_features.has_key? feature_name
|
136
|
-
if @ff_features[feature_name].is_a? FalseClass or @ff_features[feature_name].is_a? TrueClass
|
137
|
-
enabled = @ff_features[feature_name]
|
138
|
-
elsif @ff_features[feature_name].is_a? Hash
|
139
|
-
if @ff_features[feature_name].has_key? version_name
|
140
|
-
enabled = @ff_features[feature_name][version_name]
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
if enabled === nil
|
145
|
-
enabled = defaults[:enabled] || global_defaults[:enabled]
|
146
|
-
|
147
|
-
# Tell FluidFeatures about this amazing new feature...
|
148
|
-
options = Hash.new(defaults)
|
149
|
-
options[:enabled] = enabled
|
150
|
-
if options.has_key? :version
|
151
|
-
options.remove(:version)
|
152
|
-
end
|
153
|
-
::Rails.logger.debug "fluidfeature: seeing feature '#{feature_name.to_s}' (version '#{version_name.to_s}') for the first time."
|
154
|
-
::FluidFeatures::Rails.client.unknown_feature_hit(feature_name, version_name, options)
|
155
|
-
end
|
156
|
-
if enabled
|
157
|
-
@ff_features_hit[feature_name] ||= {}
|
158
|
-
@ff_features_hit[feature_name][version_name.to_s] = {}
|
130
|
+
unless ::FluidFeatures::Rails.enabled
|
131
|
+
return default_enabled || false
|
159
132
|
end
|
160
|
-
|
133
|
+
fluidfeatures_user.feature_enabled?(feature_name, version_name, default_enabled)
|
161
134
|
end
|
162
135
|
|
163
|
-
def fluidgoal(goal_name,
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
136
|
+
def fluidgoal(goal_name, goal_version_name=nil)
|
137
|
+
unless ::FluidFeatures::Rails.enabled
|
138
|
+
return default_enabled || false
|
139
|
+
end
|
140
|
+
fluidfeatures_user.goal_hit(goal_name, goal_version_name)
|
168
141
|
end
|
169
142
|
|
170
143
|
#
|
@@ -172,19 +145,15 @@ module ActionController
|
|
172
145
|
#
|
173
146
|
def fluidfeatures_request_before
|
174
147
|
@ff_request_start_time = Time.now
|
175
|
-
@ff_features = nil
|
176
|
-
@ff_features_hit = {}
|
177
|
-
@ff_goals_hit = {}
|
178
148
|
end
|
179
|
-
|
149
|
+
|
180
150
|
#
|
181
151
|
# Returns the features enabled for this request's user.
|
182
152
|
#
|
183
153
|
def fluidfeatures_retrieve_user_features
|
184
|
-
|
185
|
-
@ff_features = ::FluidFeatures::Rails.client.get_user_features(user)
|
154
|
+
fluidfeatures_user.features
|
186
155
|
end
|
187
|
-
|
156
|
+
|
188
157
|
#
|
189
158
|
# After the rails request is complete we will log which features we
|
190
159
|
# encountered, including the default settings (eg. enabled) for each
|
@@ -195,37 +164,28 @@ module ActionController
|
|
195
164
|
def fluidfeatures_request_after
|
196
165
|
request_duration = Time.now - @ff_request_start_time
|
197
166
|
url = "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
:stats => {
|
167
|
+
fluidfeatures_user.end_transaction(
|
168
|
+
url,
|
169
|
+
# stats
|
170
|
+
{
|
203
171
|
:request => {
|
204
172
|
:duration => request_duration
|
205
173
|
}
|
206
|
-
}
|
207
|
-
|
208
|
-
:feature => @ff_features_hit,
|
209
|
-
:goal => @ff_goals_hit
|
210
|
-
},
|
211
|
-
:url => url
|
212
|
-
}
|
213
|
-
[:name, :anonymous, :unique, :cohorts].each do |key|
|
214
|
-
if fluidfeatures_user[key]
|
215
|
-
(payload[:user] ||= {})[key] = fluidfeatures_user[key]
|
216
|
-
end
|
217
|
-
end
|
218
|
-
::FluidFeatures::Rails.client.log_request(fluidfeatures_user[:id], payload)
|
174
|
+
}
|
175
|
+
)
|
219
176
|
end
|
220
|
-
|
221
|
-
def
|
177
|
+
|
178
|
+
def fluidfeatures_default_enabled
|
222
179
|
# By default unknown features are disabled.
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
180
|
+
false
|
181
|
+
end
|
182
|
+
|
183
|
+
def fluidfeatures_default_version_name
|
184
|
+
"default"
|
227
185
|
end
|
228
186
|
|
187
|
+
alias :ff? :fluidfeature
|
188
|
+
|
229
189
|
end
|
230
190
|
end
|
231
191
|
|
data/test/testapp/Gemfile
CHANGED
@@ -3,6 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
gem 'rake'
|
4
4
|
gem 'railties'
|
5
5
|
gem 'tzinfo'
|
6
|
+
if ENV["FF_DEV"] and File.directory? '../../../fluidfeatures-ruby'
|
7
|
+
# (used this for development of the fluidfeature gems)
|
8
|
+
gem 'fluidfeatures', :path => '../../../fluidfeatures-ruby'
|
9
|
+
end
|
6
10
|
gem 'fluidfeatures-rails', :path => '../..'
|
7
11
|
gem "rspec-rails", "~> 2.0"
|
8
12
|
gem "fakeweb"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluidfeatures-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,23 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-10-31 00:00:00.000000000 Z
|
13
|
-
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: fluidfeatures
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
13
|
+
dependencies: []
|
30
14
|
description: Ruby on Rails client for the FluidFeatures service.
|
31
15
|
email:
|
32
16
|
- phil@fluidfeatures.com
|