kameleoon-client-ruby 3.3.0 → 3.4.0
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.
- checksums.yaml +4 -4
- data/lib/kameleoon/configuration/custom_data_info.rb +16 -8
- data/lib/kameleoon/configuration/data_file.rb +37 -15
- data/lib/kameleoon/configuration/feature_flag.rb +10 -0
- data/lib/kameleoon/configuration/rule.rb +4 -0
- data/lib/kameleoon/configuration/settings.rb +13 -8
- data/lib/kameleoon/configuration/variation_exposition.rb +4 -0
- data/lib/kameleoon/data/browser.rb +4 -0
- data/lib/kameleoon/data/conversion.rb +4 -0
- data/lib/kameleoon/data/cookie.rb +4 -0
- data/lib/kameleoon/data/custom_data.rb +11 -3
- data/lib/kameleoon/data/data.rb +30 -4
- data/lib/kameleoon/data/device.rb +4 -0
- data/lib/kameleoon/data/geolocation.rb +5 -0
- data/lib/kameleoon/data/kcs_heat.rb +4 -0
- data/lib/kameleoon/data/manager/assigned_variation.rb +5 -0
- data/lib/kameleoon/data/manager/data_array_storage.rb +7 -0
- data/lib/kameleoon/data/manager/data_map_storage.rb +7 -0
- data/lib/kameleoon/data/manager/page_view_visit.rb +4 -0
- data/lib/kameleoon/data/manager/visitor.rb +197 -73
- data/lib/kameleoon/data/manager/visitor_manager.rb +54 -17
- data/lib/kameleoon/data/mapping_identifier.rb +33 -0
- data/lib/kameleoon/data/operating_system.rb +4 -0
- data/lib/kameleoon/data/page_view.rb +6 -1
- data/lib/kameleoon/data/unique_identifier.rb +11 -0
- data/lib/kameleoon/data/user_agent.rb +4 -0
- data/lib/kameleoon/data/visitor_visits.rb +4 -0
- data/lib/kameleoon/hybrid/manager.rb +13 -4
- data/lib/kameleoon/kameleoon_client.rb +303 -148
- data/lib/kameleoon/kameleoon_client_config.rb +64 -17
- data/lib/kameleoon/kameleoon_client_factory.rb +15 -2
- data/lib/kameleoon/logging/default_logger.rb +20 -0
- data/lib/kameleoon/logging/kameleoon_logger.rb +77 -0
- data/lib/kameleoon/logging/logger.rb +12 -0
- data/lib/kameleoon/managers/data/data_manager.rb +36 -0
- data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +32 -15
- data/lib/kameleoon/managers/tracking/tracking_builder.rb +149 -0
- data/lib/kameleoon/managers/tracking/tracking_manager.rb +97 -0
- data/lib/kameleoon/managers/tracking/visitor_tracking_registry.rb +94 -0
- data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +22 -5
- data/lib/kameleoon/network/access_token_source.rb +46 -14
- data/lib/kameleoon/network/cookie/cookie_manager.rb +45 -7
- data/lib/kameleoon/network/net_provider.rb +2 -3
- data/lib/kameleoon/network/network_manager.rb +16 -21
- data/lib/kameleoon/network/request.rb +14 -3
- data/lib/kameleoon/network/response.rb +4 -0
- data/lib/kameleoon/network/url_provider.rb +4 -4
- data/lib/kameleoon/real_time/real_time_configuration_service.rb +10 -11
- data/lib/kameleoon/sdk_version.rb +31 -0
- data/lib/kameleoon/targeting/condition.rb +4 -2
- data/lib/kameleoon/targeting/conditions/browser_condition.rb +3 -3
- data/lib/kameleoon/targeting/conditions/cookie_condition.rb +10 -10
- data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +0 -1
- data/lib/kameleoon/targeting/conditions/number_condition.rb +4 -4
- data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +1 -2
- data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +2 -1
- data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
- data/lib/kameleoon/targeting/conditions/string_value_condition.rb +2 -1
- data/lib/kameleoon/targeting/models.rb +0 -14
- data/lib/kameleoon/targeting/targeting_manager.rb +35 -7
- data/lib/kameleoon/targeting/tree_builder.rb +10 -5
- data/lib/kameleoon/types/remote_visitor_data_filter.rb +13 -0
- data/lib/kameleoon/types/variable.rb +4 -0
- data/lib/kameleoon/types/variation.rb +4 -0
- data/lib/kameleoon/utils.rb +18 -0
- data/lib/kameleoon/version.rb +1 -27
- metadata +12 -2
@@ -5,12 +5,15 @@ require 'kameleoon/data/browser'
|
|
5
5
|
require 'kameleoon/data/conversion'
|
6
6
|
require 'kameleoon/data/custom_data'
|
7
7
|
require 'kameleoon/data/device'
|
8
|
+
require 'kameleoon/data/kcs_heat'
|
8
9
|
require 'kameleoon/data/page_view'
|
10
|
+
require 'kameleoon/data/unique_identifier'
|
9
11
|
require 'kameleoon/data/user_agent'
|
10
12
|
require 'kameleoon/data/manager/assigned_variation'
|
11
13
|
require 'kameleoon/data/manager/page_view_visit'
|
12
14
|
require 'kameleoon/data/manager/data_map_storage'
|
13
15
|
require 'kameleoon/data/manager/data_array_storage'
|
16
|
+
require 'kameleoon/logging/kameleoon_logger'
|
14
17
|
|
15
18
|
module Kameleoon
|
16
19
|
module DataManager
|
@@ -18,132 +21,265 @@ module Kameleoon
|
|
18
21
|
# Visitor is a container of all data assigned to a visitor.
|
19
22
|
# It is thread-safe
|
20
23
|
class Visitor
|
21
|
-
attr_reader :
|
22
|
-
:kcs_heat, :visitor_visits
|
23
|
-
attr_accessor :legal_consent, :mapping_identifier
|
24
|
+
attr_reader :data, :is_unique_identifier
|
24
25
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
26
|
+
def to_s
|
27
|
+
"Visitor{}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(source = nil)
|
31
|
+
if source.nil?
|
32
|
+
@data = VisitorData.new
|
33
|
+
@is_unique_identifier = false
|
34
|
+
else
|
35
|
+
@data = source.data
|
36
|
+
@is_unique_identifier = source.is_unique_identifier
|
37
|
+
end
|
28
38
|
update_last_activity_time
|
29
39
|
end
|
30
40
|
|
41
|
+
def last_activity_time
|
42
|
+
@data.last_activity_time
|
43
|
+
end
|
44
|
+
|
31
45
|
def update_last_activity_time
|
32
|
-
@last_activity_time = Time.new.to_i
|
46
|
+
@data.last_activity_time = Time.new.to_i
|
33
47
|
end
|
34
48
|
|
35
49
|
def enumerate_sendable_data(&blk)
|
36
|
-
|
37
|
-
blk.call(@browser) unless @browser.nil?
|
38
|
-
blk.call(@operating_system) unless @operating_system.nil?
|
39
|
-
blk.call(@geolocation) unless @geolocation.nil?
|
40
|
-
@mutex.with_read_lock do
|
41
|
-
@custom_data_map&.each { |_, cd| blk.call(cd) }
|
42
|
-
@page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
|
43
|
-
@conversions&.each { |c| blk.call(c) }
|
44
|
-
@variations&.each { |_, av| blk.call(av) }
|
45
|
-
end
|
50
|
+
@data.enumerate_sendable_data(&blk)
|
46
51
|
end
|
47
52
|
|
48
53
|
def count_sendable_data
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
count_sendable_data = @data.count_sendable_data
|
55
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.count_sendable_data -> (count_sendable_data: %s)', count_sendable_data)
|
56
|
+
count_sendable_data
|
57
|
+
end
|
58
|
+
|
59
|
+
def user_agent
|
60
|
+
user_agent = @data.user_agent
|
61
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.user_agent -> (user_agent: %s)', user_agent)
|
62
|
+
user_agent
|
63
|
+
end
|
64
|
+
|
65
|
+
def device
|
66
|
+
device = @data.device
|
67
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.device -> (device: %s)', device)
|
68
|
+
device
|
69
|
+
end
|
70
|
+
|
71
|
+
def browser
|
72
|
+
browser = @data.browser
|
73
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.browser -> (browser: %s)', browser)
|
74
|
+
browser
|
75
|
+
end
|
76
|
+
|
77
|
+
def geolocation
|
78
|
+
geolocation = @data.geolocation
|
79
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.geolocation -> (geolocation: %s)', geolocation)
|
80
|
+
geolocation
|
81
|
+
end
|
82
|
+
|
83
|
+
def operating_system
|
84
|
+
operating_system = @data.operating_system
|
85
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.operating_system -> (operating_system: %s)', operating_system)
|
86
|
+
operating_system
|
87
|
+
end
|
88
|
+
|
89
|
+
def cookie
|
90
|
+
cookie = @data.cookie
|
91
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.cookie -> (cookie: %s)', cookie)
|
92
|
+
cookie
|
93
|
+
end
|
94
|
+
|
95
|
+
def kcs_heat
|
96
|
+
kcs_heat = @data.kcs_heat
|
97
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.kcs_heat -> (kcs_heat: %s)', kcs_heat)
|
98
|
+
kcs_heat
|
99
|
+
end
|
100
|
+
|
101
|
+
def visitor_visits
|
102
|
+
visitor_visits = @data.visitor_visits
|
103
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.visitor_visits -> (visitor_visits: %s)', visitor_visits)
|
104
|
+
visitor_visits
|
105
|
+
end
|
106
|
+
|
107
|
+
def legal_consent
|
108
|
+
legal_consent = @data.legal_consent
|
109
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.legal_consent -> (legal_consent: %s)', legal_consent)
|
110
|
+
legal_consent
|
111
|
+
end
|
112
|
+
|
113
|
+
def legal_consent=(value)
|
114
|
+
@data.legal_consent = value
|
115
|
+
end
|
116
|
+
|
117
|
+
def mapping_identifier
|
118
|
+
mapping_identifier = @data.mapping_identifier
|
119
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.mapping_identifier -> (mapping_identifier: %s)',
|
120
|
+
mapping_identifier)
|
121
|
+
mapping_identifier
|
122
|
+
end
|
123
|
+
|
124
|
+
def mapping_identifier=(value)
|
125
|
+
@data.mapping_identifier = value
|
61
126
|
end
|
62
127
|
|
63
128
|
def custom_data
|
64
|
-
|
129
|
+
custom_data = @data.custom_data
|
130
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.custom_data -> (custom_data: %s)', custom_data)
|
131
|
+
custom_data
|
65
132
|
end
|
66
133
|
|
67
134
|
def page_view_visits
|
68
|
-
|
135
|
+
page_view_visits = @data.page_view_visits
|
136
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.page_view_visits -> (page_view_visits: %s)',
|
137
|
+
page_view_visits)
|
138
|
+
page_view_visits
|
69
139
|
end
|
70
140
|
|
71
141
|
def conversions
|
72
|
-
|
142
|
+
conversions = @data.conversions
|
143
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.conversions -> (conversions: %s)', conversions)
|
144
|
+
conversions
|
73
145
|
end
|
74
146
|
|
75
147
|
def variations
|
76
|
-
|
148
|
+
variations = @data.variations
|
149
|
+
Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.variations -> (variations: %s)', variations)
|
150
|
+
variations
|
77
151
|
end
|
78
152
|
|
79
|
-
def add_data(
|
80
|
-
|
153
|
+
def add_data(*args, overwrite: true)
|
154
|
+
Logging::KameleoonLogger.debug('CALL: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
|
155
|
+
@data.mutex.with_write_lock do
|
81
156
|
args.each do |data|
|
82
157
|
case data
|
83
158
|
when Kameleoon::UserAgent
|
84
|
-
|
159
|
+
@data.user_agent = data.value
|
85
160
|
when Kameleoon::DataManager::AssignedVariation
|
86
|
-
add_variation(data, overwrite)
|
161
|
+
@data.add_variation(data, overwrite)
|
87
162
|
when Kameleoon::Device
|
88
|
-
set_device(data, overwrite)
|
163
|
+
@data.set_device(data, overwrite)
|
89
164
|
when Kameleoon::Browser
|
90
|
-
set_browser(data, overwrite)
|
165
|
+
@data.set_browser(data, overwrite)
|
91
166
|
when Kameleoon::CustomData
|
92
|
-
add_custom_data(data, overwrite)
|
167
|
+
@data.add_custom_data(data, overwrite)
|
93
168
|
when Kameleoon::PageView
|
94
|
-
add_page_view(data)
|
169
|
+
@data.add_page_view(data)
|
95
170
|
when Kameleoon::DataManager::PageViewVisit
|
96
|
-
add_page_view_visit(data)
|
171
|
+
@data.add_page_view_visit(data)
|
97
172
|
when Kameleoon::Conversion
|
98
|
-
add_conversion(data)
|
173
|
+
@data.add_conversion(data)
|
99
174
|
when Kameleoon::Cookie
|
100
|
-
|
175
|
+
@data.cookie = data
|
101
176
|
when Kameleoon::OperatingSystem
|
102
|
-
set_operating_system(data, overwrite)
|
177
|
+
@data.set_operating_system(data, overwrite)
|
103
178
|
when Kameleoon::Geolocation
|
104
|
-
set_geolocation(data, overwrite)
|
179
|
+
@data.set_geolocation(data, overwrite)
|
105
180
|
when Kameleoon::KcsHeat
|
106
|
-
|
181
|
+
@data.kcs_heat = data
|
107
182
|
when Kameleoon::VisitorVisits
|
108
|
-
|
183
|
+
@data.visitor_visits = data
|
184
|
+
when Kameleoon::UniqueIdentifier
|
185
|
+
@is_unique_identifier = data.value
|
109
186
|
else
|
110
|
-
|
187
|
+
Logging::KameleoonLogger.warning("Data has unsupported type '%s'", data.class)
|
111
188
|
end
|
112
189
|
end
|
113
190
|
end
|
191
|
+
Logging::KameleoonLogger.debug('RETURN: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
|
114
192
|
end
|
115
193
|
|
116
194
|
def assign_variation(variation)
|
117
|
-
@mutex.with_write_lock do
|
118
|
-
@
|
119
|
-
|
195
|
+
@data.mutex.with_write_lock do
|
196
|
+
@data.add_variation(variation, true)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def clone
|
201
|
+
Visitor.new(self)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class VisitorData
|
206
|
+
attr_reader :mutex, :device, :browser, :geolocation, :operating_system
|
207
|
+
attr_accessor :last_activity_time, :legal_consent, :user_agent, :cookie, :kcs_heat, :visitor_visits,
|
208
|
+
:mapping_identifier
|
209
|
+
|
210
|
+
def initialize
|
211
|
+
Logging::KameleoonLogger.debug('CALL: VisitorData.new')
|
212
|
+
@mutex = Concurrent::ReadWriteLock.new
|
213
|
+
@legal_consent = false
|
214
|
+
Logging::KameleoonLogger.debug('RETURN: VisitorData.new')
|
215
|
+
end
|
216
|
+
|
217
|
+
def enumerate_sendable_data(&blk)
|
218
|
+
blk.call(@device) unless @device.nil?
|
219
|
+
blk.call(@browser) unless @browser.nil?
|
220
|
+
blk.call(@operating_system) unless @operating_system.nil?
|
221
|
+
blk.call(@geolocation) unless @geolocation.nil?
|
222
|
+
@mutex.with_read_lock do
|
223
|
+
@custom_data_map&.each { |_, cd| blk.call(cd) }
|
224
|
+
@page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
|
225
|
+
@conversions&.each { |c| blk.call(c) }
|
226
|
+
@variations&.each { |_, av| blk.call(av) }
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def count_sendable_data
|
231
|
+
Logging::KameleoonLogger.debug('CALL: Visitor.count_sendable_data')
|
232
|
+
count = 0
|
233
|
+
@mutex.with_read_lock do
|
234
|
+
count += 1 unless @device.nil?
|
235
|
+
count += 1 unless @browser.nil?
|
236
|
+
count += 1 unless @geolocation.nil?
|
237
|
+
count += 1 unless @operating_system.nil?
|
238
|
+
count += @custom_data_map.size unless @custom_data_map.nil?
|
239
|
+
count += @page_view_visits.size unless @page_view_visits.nil?
|
240
|
+
count += @conversions.size unless @conversions.nil?
|
241
|
+
count += @variations.size unless @variations.nil?
|
120
242
|
end
|
243
|
+
Logging::KameleoonLogger.debug('RETURN: VisitorData.count_sendable_data -> (count: %s)', count)
|
244
|
+
count
|
121
245
|
end
|
122
246
|
|
123
|
-
|
247
|
+
def custom_data
|
248
|
+
DataMapStorage.new(@mutex, @custom_data_map)
|
249
|
+
end
|
124
250
|
|
125
|
-
def
|
126
|
-
@
|
251
|
+
def page_view_visits
|
252
|
+
DataMapStorage.new(@mutex, @page_view_visits)
|
253
|
+
end
|
254
|
+
|
255
|
+
def conversions
|
256
|
+
DataArrayStorage.new(@mutex, @conversions)
|
257
|
+
end
|
258
|
+
|
259
|
+
def variations
|
260
|
+
DataMapStorage.new(@mutex, @variations)
|
127
261
|
end
|
128
262
|
|
129
263
|
def set_device(device, overwrite)
|
130
|
-
@device = device if overwrite || @device
|
264
|
+
@device = device if overwrite || @device.nil?
|
131
265
|
end
|
132
266
|
|
133
267
|
def add_variation(variation, overwrite)
|
134
|
-
@variations = {} if @variations
|
268
|
+
@variations = {} if @variations.nil?
|
135
269
|
if overwrite || !@variations.include?(variation.experiment_id)
|
136
270
|
@variations[variation.experiment_id] = variation
|
137
271
|
end
|
138
272
|
end
|
139
273
|
|
140
274
|
def set_browser(browser, overwrite)
|
141
|
-
@browser = browser if overwrite || @browser
|
275
|
+
@browser = browser if overwrite || @browser.nil?
|
142
276
|
end
|
143
277
|
|
144
278
|
def add_custom_data(custom_data, overwrite)
|
145
279
|
@custom_data_map = {} if @custom_data_map.nil?
|
146
|
-
|
280
|
+
if overwrite || !@custom_data_map.include?(custom_data.id)
|
281
|
+
@custom_data_map[custom_data.id] = custom_data
|
282
|
+
end
|
147
283
|
end
|
148
284
|
|
149
285
|
def add_page_view(page_view)
|
@@ -176,23 +312,11 @@ module Kameleoon
|
|
176
312
|
end
|
177
313
|
|
178
314
|
def set_geolocation(geolocation, overwrite)
|
179
|
-
@geolocation = geolocation if overwrite || @geolocation
|
180
|
-
end
|
181
|
-
|
182
|
-
def set_cookie(cookie)
|
183
|
-
@cookie = cookie
|
315
|
+
@geolocation = geolocation if overwrite || @geolocation.nil?
|
184
316
|
end
|
185
317
|
|
186
318
|
def set_operating_system(operating_system, overwrite)
|
187
|
-
@operating_system = operating_system if overwrite || @operating_system
|
188
|
-
end
|
189
|
-
|
190
|
-
def set_kcs_heat(kcs_heat)
|
191
|
-
@kcs_heat = kcs_heat
|
192
|
-
end
|
193
|
-
|
194
|
-
def set_visitor_visits(visitor_visits)
|
195
|
-
@visitor_visits = visitor_visits
|
319
|
+
@operating_system = operating_system if overwrite || @operating_system.nil?
|
196
320
|
end
|
197
321
|
end
|
198
322
|
end
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'concurrent'
|
4
4
|
require 'rufus/scheduler'
|
5
|
+
require 'kameleoon/configuration/custom_data_info'
|
6
|
+
require 'kameleoon/data/mapping_identifier'
|
5
7
|
require 'kameleoon/data/manager/visitor'
|
8
|
+
require 'kameleoon/logging/kameleoon_logger'
|
6
9
|
|
7
10
|
module Kameleoon
|
8
11
|
module DataManager
|
@@ -11,36 +14,52 @@ module Kameleoon
|
|
11
14
|
# It is thread-safe except `stop` method
|
12
15
|
class VisitorManager
|
13
16
|
attr_reader :expiration_period
|
14
|
-
attr_accessor :custom_data_info
|
15
17
|
|
16
|
-
def initialize(expiration_period,
|
18
|
+
def initialize(data_manager, expiration_period, scheduler)
|
19
|
+
Logging::KameleoonLogger.debug(
|
20
|
+
'CALL: VisitorManager.new(data_manager, expiration_period: %s, scheduler)', expiration_period
|
21
|
+
)
|
22
|
+
@data_manager = data_manager
|
17
23
|
@expiration_period = expiration_period
|
24
|
+
@scheduler = scheduler
|
18
25
|
@visitors = Concurrent::Map.new
|
19
|
-
@log_func = log_func
|
20
26
|
start
|
27
|
+
Logging::KameleoonLogger.debug(
|
28
|
+
'RETURN: VisitorManager.new(data_manager, expiration_period: %s, scheduler)', expiration_period
|
29
|
+
)
|
21
30
|
end
|
22
31
|
|
23
32
|
def stop
|
24
|
-
|
25
|
-
|
26
|
-
@purge_job.unschedule
|
33
|
+
Logging::KameleoonLogger.debug('CALL: VisitorManager.stop')
|
34
|
+
@purge_job&.unschedule
|
27
35
|
@purge_job = nil
|
36
|
+
Logging::KameleoonLogger.debug('RETURN: VisitorManager.stop')
|
28
37
|
end
|
29
38
|
|
30
39
|
def get_visitor(visitor_code)
|
31
|
-
|
40
|
+
Logging::KameleoonLogger.debug("CALL: VisitorManager.get_visitor(visitor_code: '%s')", visitor_code)
|
41
|
+
visitor = @visitors.compute_if_present(visitor_code) do |visitor|
|
32
42
|
visitor.update_last_activity_time
|
33
43
|
visitor
|
34
44
|
end
|
45
|
+
Logging::KameleoonLogger.debug("RETURN: VisitorManager.get_visitor(visitor_code: '%s') -> (visitor: %s)",
|
46
|
+
visitor_code, visitor)
|
47
|
+
visitor
|
35
48
|
end
|
36
49
|
|
37
50
|
def get_or_create_visitor(visitor_code)
|
38
|
-
|
51
|
+
Logging::KameleoonLogger.debug("CALL: VisitorManager.get_or_create_visitor(visitor_code: '%s')",
|
52
|
+
visitor_code)
|
53
|
+
visitor = @visitors.compute(visitor_code) do |former_v|
|
39
54
|
next DataManager::Visitor.new if former_v.nil?
|
40
55
|
|
41
56
|
former_v.update_last_activity_time
|
42
57
|
former_v
|
43
58
|
end
|
59
|
+
Logging::KameleoonLogger.debug(
|
60
|
+
"RETURN: VisitorManager.get_or_create_visitor(visitor_code: '%s') -> (visitor)", visitor_code
|
61
|
+
)
|
62
|
+
visitor
|
44
63
|
end
|
45
64
|
|
46
65
|
def enumerate(&blk)
|
@@ -51,42 +70,60 @@ module Kameleoon
|
|
51
70
|
@visitors.size
|
52
71
|
end
|
53
72
|
|
54
|
-
def add_data(visitor_code, *args)
|
73
|
+
def add_data(visitor_code, *args, overwrite: true)
|
74
|
+
Logging::KameleoonLogger.debug("CALL: VisitorManager.add_data(visitor_code: '%s', args: %s, overwrite: %s)",
|
75
|
+
visitor_code, args, overwrite)
|
55
76
|
visitor = get_or_create_visitor(visitor_code)
|
56
|
-
|
77
|
+
cdi = @data_manager.data_file.custom_data_info
|
78
|
+
args.size.times do |i|
|
79
|
+
custom_data = args[i]
|
57
80
|
next unless custom_data.is_a?(Kameleoon::CustomData)
|
81
|
+
|
58
82
|
# We shouldn't send custom data with local only type
|
59
|
-
custom_data.mark_as_sent if
|
83
|
+
custom_data.mark_as_sent if cdi.local_only?(custom_data.id)
|
60
84
|
# If mappingIdentifier is passed, we should link anonymous visitor with real unique userId.
|
61
85
|
# After authorization, customer must be able to continue work with userId, but hash for variation
|
62
86
|
# should be calculated based on anonymous visitor code, that's why set MappingIdentifier to visitor.
|
63
|
-
if
|
64
|
-
custom_data.is_mapping_identifier = true
|
87
|
+
if Configuration::CustomDataInfo.mapping_identifier?(cdi, custom_data)
|
65
88
|
visitor.mapping_identifier = visitor_code
|
66
|
-
|
67
|
-
|
89
|
+
user_id = custom_data.values[0]
|
90
|
+
args[i] = MappingIdentifier.new(custom_data)
|
91
|
+
if visitor_code != user_id
|
92
|
+
@visitors[user_id] = visitor.clone
|
93
|
+
Logging::KameleoonLogger.info(-> { "Linked anonymous visitor '#{visitor_code}' with user '#{user_id}'" })
|
94
|
+
end
|
68
95
|
end
|
69
96
|
end
|
70
|
-
visitor.add_data(
|
97
|
+
visitor.add_data(*args, overwrite: overwrite)
|
98
|
+
Logging::KameleoonLogger.debug(
|
99
|
+
"RETURN: VisitorManager.add_data(visitor_code: '%s', args: %s, overwrite: %s) -> (visitor)",
|
100
|
+
visitor_code, args, overwrite
|
101
|
+
)
|
71
102
|
visitor
|
72
103
|
end
|
73
104
|
|
74
105
|
private
|
75
106
|
|
76
107
|
def purge
|
108
|
+
Logging::KameleoonLogger.debug('CALL: VisitorManager.purge')
|
77
109
|
expired_time = Time.new.to_i - @expiration_period
|
78
110
|
@visitors.each_pair do |vc, v|
|
79
111
|
next if v.last_activity_time >= expired_time
|
80
112
|
|
81
113
|
@visitors.compute_if_present(vc) { |visitor| v.last_activity_time < expired_time ? nil : visitor }
|
82
114
|
end
|
115
|
+
Logging::KameleoonLogger.debug('RETURN: VisitorManager.purge')
|
116
|
+
@visitors
|
83
117
|
end
|
84
118
|
|
85
119
|
def start
|
120
|
+
Logging::KameleoonLogger.debug('CALL: VisitorManager.start')
|
86
121
|
stop unless @purge_job.nil?
|
87
|
-
@purge_job =
|
122
|
+
@purge_job = @scheduler.schedule_every @expiration_period do
|
88
123
|
purge
|
89
124
|
end
|
125
|
+
Logging::KameleoonLogger.debug('RETURN: VisitorManager.start')
|
126
|
+
@purge_job
|
90
127
|
end
|
91
128
|
end
|
92
129
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kameleoon/data/custom_data'
|
4
|
+
require 'kameleoon/network/uri_helper'
|
5
|
+
|
6
|
+
module Kameleoon
|
7
|
+
class MappingIdentifier < CustomData
|
8
|
+
def initialize(custom_data)
|
9
|
+
super(custom_data.id, *custom_data.values)
|
10
|
+
end
|
11
|
+
|
12
|
+
def unsent
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def transmitting
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def sent
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def obtain_full_post_text_line
|
25
|
+
mip = Kameleoon::Network::UriHelper.encode_query({ mappingIdentifier: true })
|
26
|
+
"#{super}&#{mip}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"MappingIdentifier{id:#{@id},values:#{@values}}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -52,6 +52,10 @@ module Kameleoon
|
|
52
52
|
class OperatingSystem < DuplicationUnsafeData
|
53
53
|
attr_reader :os_type
|
54
54
|
|
55
|
+
def to_s
|
56
|
+
"OperatingSystem{os_type:#{@os_type}}"
|
57
|
+
end
|
58
|
+
|
55
59
|
# @param [OperatingSystemType] os_type Operating system type, can be: WINDOWS, MAC, IOS, LINUX, ANDROID, WINDOWS_PHONE
|
56
60
|
def initialize(os_type)
|
57
61
|
super(DataType::OPERATING_SYSTEM)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
+
require 'kameleoon/logging/kameleoon_logger'
|
4
5
|
require 'kameleoon/network/uri_helper'
|
5
6
|
require_relative 'data'
|
6
7
|
|
@@ -9,13 +10,17 @@ module Kameleoon
|
|
9
10
|
class PageView < DuplicationSafeData
|
10
11
|
attr_reader :url, :title, :referrer
|
11
12
|
|
13
|
+
def to_s
|
14
|
+
"PageView{url:'#{@url}',title:'#{@title}',referrers:#{@referrers}}"
|
15
|
+
end
|
16
|
+
|
12
17
|
# @param [String] url Url of the page
|
13
18
|
# @param [String] title Optional field - title of the page
|
14
19
|
# @param [Array] referrers Optional field - Referrer ids
|
15
20
|
def initialize(url, title = nil, referrers = nil)
|
16
21
|
super(DataType::PAGE_VIEW)
|
17
22
|
@url = url || ''
|
18
|
-
|
23
|
+
Logging::KameleoonLogger.error('Url for PageView is required parameter, the data will be ignored.') if @url == ''
|
19
24
|
@title = title || ''
|
20
25
|
@referrers = referrers.instance_of?(Integer) ? [referrers] : referrers
|
21
26
|
end
|
@@ -4,6 +4,10 @@ module Kameleoon
|
|
4
4
|
class VisitorVisits
|
5
5
|
attr_reader :previous_visit_timestamps
|
6
6
|
|
7
|
+
def to_s
|
8
|
+
"VisitorVisits{previous_visit_timestamps:#{@previous_visit_timestamps}}"
|
9
|
+
end
|
10
|
+
|
7
11
|
def initialize(previous_visit_timestamps = [])
|
8
12
|
@previous_visit_timestamps = previous_visit_timestamps
|
9
13
|
@previous_visit_timestamps.freeze
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'kameleoon/logging/kameleoon_logger'
|
4
|
+
|
3
5
|
module Kameleoon
|
4
6
|
module Hybrid
|
5
7
|
TC_INIT = 'window.kameleoonQueue=window.kameleoonQueue||[];'
|
@@ -17,14 +19,16 @@ module Kameleoon
|
|
17
19
|
|
18
20
|
# Implementation of Cache with auto cleaning feature
|
19
21
|
class ManagerImpl < Manager
|
20
|
-
def initialize(expiration_time
|
22
|
+
def initialize(expiration_time)
|
21
23
|
super()
|
24
|
+
Logging::KameleoonLogger.debug('CALL: HybridManager.new(expiration_time: %s)', expiration_time)
|
22
25
|
@expiration_time = expiration_time
|
23
|
-
|
24
|
-
@log.call('Hybrid Manager was successfully initialized')
|
26
|
+
Logging::KameleoonLogger.debug('RETURN: HybridManager.new(expiration_time: %s)', expiration_time)
|
25
27
|
end
|
26
28
|
|
27
29
|
def get_engine_tracking_code(visitor_variations)
|
30
|
+
Logging::KameleoonLogger.debug('CALL: HybridManager.get_engine_tracking_code(visitor_variations: %s)',
|
31
|
+
visitor_variations)
|
28
32
|
tracking_code = [TC_INIT]
|
29
33
|
unless visitor_variations.nil?
|
30
34
|
expired_time = (Time.now - @expiration_time).to_i
|
@@ -35,7 +39,12 @@ module Kameleoon
|
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
38
|
-
tracking_code.join
|
42
|
+
tracking_code = tracking_code.join
|
43
|
+
Logging::KameleoonLogger.debug(
|
44
|
+
"RETURN: HybridManager.get_engine_tracking_code(visitor_variations: %s) -> (tracking_code: '%s')",
|
45
|
+
visitor_variations, tracking_code
|
46
|
+
)
|
47
|
+
tracking_code
|
39
48
|
end
|
40
49
|
end
|
41
50
|
end
|