fluidfeatures-rails 0.3.0 → 0.3.1

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.
@@ -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], { :version => params[:goal_version] })
17
+ fluidgoal(params[:goal_name], params[:goal_version])
18
18
  render :json => {}, :status => 200
19
19
  end
20
20
  end
@@ -1,5 +1,5 @@
1
1
  module FluidFeatures
2
2
  module Rails
3
- VERSION = '0.3.0'
3
+ VERSION = '0.3.1'
4
4
  end
5
5
  end
@@ -1,12 +1,12 @@
1
1
 
2
- require "fluidfeatures/client"
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 :client
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.client = ::FluidFeatures::Client.new(
40
+ ::FluidFeatures::Rails.ff_app = ::FluidFeatures.app(
45
41
  api_baseuri,
46
42
  api_appid,
47
43
  api_secret,
48
- # options
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
- # TODO: Do not always get verbose user details.
80
- # Get for new users and then less frequently.
81
- user = fluidfeature_current_user(verbose=true)
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
- if user[:id] and not user[:anonymous]
84
- # We are no longer an anoymous users. Delete the cookie
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
- user[:anonymous] = !!user[:anonymous]
107
- @ff_user = user
108
+
109
+ @ff_user
108
110
  end
109
111
 
110
112
  def fluidfeatures_user
111
- unless @ff_user
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, defaults={})
124
- if defaults === true or defaults === false
125
- defaults = { :enabled => defaults }
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 ::FluidFeatures::Rails.enabled
128
- return defaults[:enabled] || false
127
+ unless default_enabled.is_a? FalseClass or default_enabled.is_a? TrueClass
128
+ default_enabled = fluidfeatures_default_enabled
129
129
  end
130
- global_defaults = fluidfeatures_defaults || {}
131
- version_name = (defaults[:version] || global_defaults[:version]).to_s
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
- enabled
133
+ fluidfeatures_user.feature_enabled?(feature_name, version_name, default_enabled)
161
134
  end
162
135
 
163
- def fluidgoal(goal_name, defaults={})
164
- global_defaults = fluidfeatures_defaults || {}
165
- version_name = (defaults[:version] || global_defaults[:version]).to_s
166
- @ff_goals_hit[goal_name] ||= {}
167
- @ff_goals_hit[goal_name][version_name.to_s] = {}
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
- user = fluidfeatures_user
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
- payload = {
199
- :user => {
200
- :id => fluidfeatures_user[:id]
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
- :hits => {
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 fluidfeatures_defaults
177
+
178
+ def fluidfeatures_default_enabled
222
179
  # By default unknown features are disabled.
223
- {
224
- :enabled => false,
225
- :version => :default
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.0
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