kameleoon-client-ruby 3.1.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kameleoon/configuration/custom_data_info.rb +43 -0
- data/lib/kameleoon/configuration/data_file.rb +30 -2
- data/lib/kameleoon/configuration/rule.rb +4 -1
- data/lib/kameleoon/configuration/variation_exposition.rb +1 -1
- data/lib/kameleoon/data/browser.rb +19 -0
- data/lib/kameleoon/data/cookie.rb +14 -0
- data/lib/kameleoon/data/custom_data.rb +2 -0
- data/lib/kameleoon/data/data.rb +2 -0
- data/lib/kameleoon/data/geolocation.rb +45 -0
- data/lib/kameleoon/data/manager/assigned_variation.rb +2 -1
- data/lib/kameleoon/data/manager/page_view_visit.rb +16 -2
- data/lib/kameleoon/data/manager/visitor.rb +64 -14
- data/lib/kameleoon/data/manager/visitor_manager.rb +23 -1
- data/lib/kameleoon/data/operating_system.rb +72 -0
- data/lib/kameleoon/data/page_view.rb +2 -2
- data/lib/kameleoon/data/visitor_visits.rb +13 -0
- data/lib/kameleoon/kameleoon_client.rb +75 -94
- data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +57 -0
- data/lib/kameleoon/managers/remote_data/remote_visitor_data.rb +162 -0
- data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +3 -1
- data/lib/kameleoon/network/access_token_source.rb +22 -5
- data/lib/kameleoon/network/network_manager.rb +10 -10
- data/lib/kameleoon/network/response.rb +1 -1
- data/lib/kameleoon/network/url_provider.rb +15 -12
- data/lib/kameleoon/targeting/condition.rb +22 -2
- data/lib/kameleoon/targeting/condition_factory.rb +36 -6
- data/lib/kameleoon/targeting/conditions/cookie_condition.rb +55 -0
- data/lib/kameleoon/targeting/conditions/exclusive_feature_flag_condition.rb +27 -0
- data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +33 -0
- data/lib/kameleoon/targeting/conditions/number_condition.rb +38 -0
- data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +27 -0
- data/lib/kameleoon/targeting/conditions/page_view_number_condition.rb +28 -0
- data/lib/kameleoon/targeting/conditions/previous_page_condition.rb +35 -0
- data/lib/kameleoon/targeting/conditions/segment_condition.rb +42 -0
- data/lib/kameleoon/targeting/conditions/target_feature_flag_condition.rb +63 -0
- data/lib/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.rb +30 -0
- data/lib/kameleoon/targeting/conditions/visit_number_today_condition.rb +28 -0
- data/lib/kameleoon/targeting/conditions/visit_number_total_condition.rb +21 -0
- data/lib/kameleoon/targeting/conditions/visitor_new_return_condition.rb +33 -0
- data/lib/kameleoon/targeting/targeting_manager.rb +66 -0
- data/lib/kameleoon/types/remote_visitor_data_filter.rb +24 -0
- data/lib/kameleoon/utils.rb +1 -0
- data/lib/kameleoon/version.rb +1 -1
- metadata +24 -4
- data/lib/kameleoon/targeting/conditions/exclusive_experiment.rb +0 -18
- data/lib/kameleoon/targeting/conditions/target_experiment.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8dea61e52fdfa38f0fc3d2161711fe169940de6053d9d372fef06b30e70975f
|
4
|
+
data.tar.gz: 201acbdb7b3597d4637207c6f599c04dc9bbf0984de60fb93904569193152230
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3ecf83261db7d1ed52d231c141521df16ea5f2d0e42240c80db684537dd5ab32f5047430446fe1779f40485357b37ea455416369d5dce0f748c76ed7b132103
|
7
|
+
data.tar.gz: f5e1641dd1311bac6620c6db63f396fbe7d46f96eecab69713eef49e9e81f67a24c5644f68b7fdff4dd99455a5c480be57ab26e7372947b02eefec3033d310fc
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
# Module which contains all internal data of SDK
|
5
|
+
module Configuration
|
6
|
+
|
7
|
+
class CustomDataInfo
|
8
|
+
attr_reader :local_only, :visitor_scope, :mapping_identifier_index
|
9
|
+
SCOPE_VISITOR = 'VISITOR'
|
10
|
+
|
11
|
+
def initialize(hashes, log_func = nil)
|
12
|
+
@local_only = Set[]
|
13
|
+
@visitor_scope = Set[]
|
14
|
+
@log_func = log_func
|
15
|
+
unless hashes.nil?
|
16
|
+
for hash in hashes
|
17
|
+
index = hash['index']
|
18
|
+
@local_only.add(index) if hash['localOnly']
|
19
|
+
@visitor_scope.add(index) if hash['scope'] == SCOPE_VISITOR
|
20
|
+
if hash['isMappingIdentifier']
|
21
|
+
if @mapping_identifier_index != nil
|
22
|
+
@log_func&.call('More than one mapping identifier is set. Undefined behavior may occur on cross-device reconciliation.')
|
23
|
+
end
|
24
|
+
@mapping_identifier_index = index
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def local_only? (index)
|
31
|
+
@local_only.include?(index)
|
32
|
+
end
|
33
|
+
|
34
|
+
def mapping_identifier? (index)
|
35
|
+
index == @mapping_identifier_index
|
36
|
+
end
|
37
|
+
|
38
|
+
def visitor_scope? (index)
|
39
|
+
@visitor_scope.include?(index)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,16 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'kameleoon/configuration/settings'
|
4
|
+
require 'kameleoon/configuration/feature_flag'
|
5
|
+
require 'kameleoon/configuration/custom_data_info'
|
4
6
|
|
5
7
|
module Kameleoon
|
6
8
|
module Configuration
|
7
9
|
class DataFile
|
8
|
-
attr_reader :settings, :feature_flags, :has_any_targeted_delivery_rule
|
10
|
+
attr_reader :settings, :feature_flags, :has_any_targeted_delivery_rule, :feature_flag_by_id, :rule_by_segment_id, :variation_by_id, :custom_data_info
|
9
11
|
|
10
|
-
def initialize(environment)
|
12
|
+
def initialize(environment, log_func = nil)
|
11
13
|
@settings = Settings.new
|
12
14
|
@feature_flags = {}
|
13
15
|
@environment = environment
|
16
|
+
@log_func = log_func
|
17
|
+
collect_indices
|
18
|
+
@custom_data_info = Kameleoon::Configuration::CustomDataInfo.new(nil, @log_func)
|
14
19
|
end
|
15
20
|
|
16
21
|
def init(configuration)
|
@@ -20,6 +25,8 @@ module Kameleoon
|
|
20
25
|
@feature_flags[ff.feature_key] = ff
|
21
26
|
end
|
22
27
|
@has_any_targeted_delivery_rule = any_targeted_delivery_rule?
|
28
|
+
collect_indices
|
29
|
+
@custom_data_info = CustomDataInfo.new(configuration['customData'], @log_func)
|
23
30
|
self
|
24
31
|
end
|
25
32
|
|
@@ -36,6 +43,27 @@ module Kameleoon
|
|
36
43
|
def any_targeted_delivery_rule?
|
37
44
|
@feature_flags.any? { |_, ff| ff.environment_enabled && ff.rules.any?(&:targeted_delivery_type?) }
|
38
45
|
end
|
46
|
+
|
47
|
+
def collect_indices
|
48
|
+
@feature_flag_by_id = {}
|
49
|
+
@rule_by_segment_id = {}
|
50
|
+
@variation_by_id = {}
|
51
|
+
|
52
|
+
@feature_flags.each_value do |feature_flag|
|
53
|
+
next if feature_flag.rules.nil?
|
54
|
+
|
55
|
+
feature_flag.rules.each do |rule|
|
56
|
+
@feature_flag_by_id[feature_flag.id] = feature_flag
|
57
|
+
@rule_by_segment_id[rule.segment_id] = rule
|
58
|
+
rule.variation_by_exposition.each do |variation|
|
59
|
+
@variation_by_id[variation.variation_id] = variation
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@feature_flag_by_id.freeze
|
64
|
+
@rule_by_segment_id.freeze
|
65
|
+
@variation_by_id.freeze
|
66
|
+
end
|
39
67
|
end
|
40
68
|
end
|
41
69
|
end
|
@@ -29,7 +29,7 @@ module Kameleoon
|
|
29
29
|
|
30
30
|
# Rule is a class for new rules of feature flags
|
31
31
|
class Rule
|
32
|
-
attr_reader :id, :order, :type, :exposition, :experiment_id, :variation_by_exposition, :respool_time
|
32
|
+
attr_reader :id, :order, :type, :exposition, :experiment_id, :variation_by_exposition, :respool_time, :segment_id, :first_variation
|
33
33
|
attr_accessor :targeting_segment
|
34
34
|
|
35
35
|
def self.create_from_array(array)
|
@@ -44,7 +44,10 @@ module Kameleoon
|
|
44
44
|
@experiment_id = hash['experimentId']
|
45
45
|
@respool_time = hash['respoolTime']
|
46
46
|
@variation_by_exposition = VariationByExposition.create_from_array(hash['variationByExposition'])
|
47
|
+
@variation_by_exposition.freeze
|
48
|
+
@first_variation = @variation_by_exposition.first
|
47
49
|
@targeting_segment = Kameleoon::Targeting::Segment.new((hash['segment'])) if hash['segment']
|
50
|
+
@segment_id = @targeting_segment != nil ? targeting_segment.id : -1
|
48
51
|
end
|
49
52
|
|
50
53
|
def get_variation(hash_double)
|
@@ -5,7 +5,7 @@ module Kameleoon
|
|
5
5
|
module Configuration
|
6
6
|
# VariationByExposition represents a variation with exposition rate for rule
|
7
7
|
class VariationByExposition
|
8
|
-
|
8
|
+
attr_reader :variation_key, :variation_id, :exposition
|
9
9
|
|
10
10
|
def self.create_from_array(array)
|
11
11
|
array&.map { |it| VariationByExposition.new(it) }
|
@@ -12,6 +12,25 @@ module Kameleoon
|
|
12
12
|
SAFARI = 3
|
13
13
|
OPERA = 4
|
14
14
|
OTHER = 5
|
15
|
+
|
16
|
+
def self.from_name(name)
|
17
|
+
case name
|
18
|
+
when 'CHROME'
|
19
|
+
BrowserType::CHROME
|
20
|
+
when 'INTERNET_EXPLORER'
|
21
|
+
BrowserType::INTERNET_EXPLORER
|
22
|
+
when 'FIREFOX'
|
23
|
+
BrowserType::FIREFOX
|
24
|
+
when 'SAFARI'
|
25
|
+
BrowserType::SAFARI
|
26
|
+
when 'OPERA'
|
27
|
+
BrowserType::OPERA
|
28
|
+
when 'OTHER'
|
29
|
+
BrowserType::OTHER
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
15
34
|
end
|
16
35
|
|
17
36
|
# Represents browser data for tracking calls
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
# Cookie contains information about the cookie stored on the visitor's device
|
5
|
+
class Cookie
|
6
|
+
attr_reader :cookies
|
7
|
+
|
8
|
+
# @param [Hash] cookies
|
9
|
+
def initialize(cookies)
|
10
|
+
@cookies = cookies
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -8,6 +8,7 @@ module Kameleoon
|
|
8
8
|
# Represents any custom data for targeting conditions
|
9
9
|
class CustomData < DuplicationUnsafeData
|
10
10
|
attr_reader :id, :values
|
11
|
+
attr_accessor :is_mapping_identifier
|
11
12
|
|
12
13
|
# @param [Integer] id Id of the custom data
|
13
14
|
# @param [String] value Value of the custom data
|
@@ -50,6 +51,7 @@ module Kameleoon
|
|
50
51
|
overwrite: 'true',
|
51
52
|
nonce: nonce
|
52
53
|
}
|
54
|
+
params[:mappingIdentifier] = is_mapping_identifier if is_mapping_identifier
|
53
55
|
Kameleoon::Network::UriHelper.encode_query(params)
|
54
56
|
end
|
55
57
|
end
|
data/lib/kameleoon/data/data.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
# Geolocation contains the visitor's geolocation details
|
5
|
+
class Geolocation < DuplicationUnsafeData
|
6
|
+
attr_reader :country, :region, :city, :postal_code, :latitude, :longitude
|
7
|
+
|
8
|
+
# @param [String] country Country of visitor's geolocation. Required
|
9
|
+
# @param [String] region Region of visitor's geolocation. Optional
|
10
|
+
# @param [String] city City of visitor's geolocation. Optional
|
11
|
+
# @param [String] postal_code Postal code of visitor's geolocation. Optional
|
12
|
+
# @param [Float] latitude Latitude of visitor's geolocation. Optional
|
13
|
+
# @param [Float] longitude Longitude of visitor's geolocation. Optional
|
14
|
+
def initialize(country, region = nil, city = nil, postal_code = nil, latitude = Float::NAN, longitude = Float::NAN)
|
15
|
+
super(DataType::GEOLOCATION)
|
16
|
+
@country = country
|
17
|
+
@region = region
|
18
|
+
@city = city
|
19
|
+
@postal_code = postal_code
|
20
|
+
@latitude = latitude
|
21
|
+
@longitude = longitude
|
22
|
+
end
|
23
|
+
|
24
|
+
def obtain_full_post_text_line
|
25
|
+
params = {
|
26
|
+
eventType: 'staticData',
|
27
|
+
nonce: nonce
|
28
|
+
}
|
29
|
+
params[:country] = @country if @country.is_a?(String)
|
30
|
+
params[:region] = @region if @region.is_a?(String)
|
31
|
+
params[:city] = @city if @city.is_a?(String)
|
32
|
+
params[:postalCode] = @postal_code if @postal_code.is_a?(String)
|
33
|
+
params[:latitude] = @latitude if valid_number?(@latitude)
|
34
|
+
params[:longitude] = @longitude if valid_number?(@longitude)
|
35
|
+
Kameleoon::Network::UriHelper.encode_query(params)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def valid_number?(value)
|
41
|
+
value.is_a?(Integer) || (value.is_a?(Float) && !value.nan?)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'kameleoon/data/data'
|
4
4
|
require 'kameleoon/network/uri_helper'
|
5
|
+
require 'kameleoon/configuration/rule'
|
5
6
|
|
6
7
|
module Kameleoon
|
7
8
|
module DataManager
|
@@ -12,7 +13,7 @@ module Kameleoon
|
|
12
13
|
|
13
14
|
attr_reader :experiment_id, :variation_id, :rule_type, :assignment_time
|
14
15
|
|
15
|
-
def initialize(experiment_id, variation_id, rule_type, assignment_time: nil)
|
16
|
+
def initialize(experiment_id, variation_id, rule_type = Kameleoon::Configuration::RuleType::UNKNOWN, assignment_time: nil)
|
16
17
|
super(DataType::ASSIGNED_VARIATION)
|
17
18
|
@experiment_id = experiment_id
|
18
19
|
@variation_id = variation_id
|
@@ -3,17 +3,31 @@
|
|
3
3
|
module Kameleoon
|
4
4
|
module DataManager
|
5
5
|
class PageViewVisit
|
6
|
-
attr_reader :page_view, :count
|
6
|
+
attr_reader :page_view, :count, :last_timestamp
|
7
7
|
|
8
|
-
def initialize(page_view, count = 1)
|
8
|
+
def initialize(page_view, count = 1, timestamp = nil)
|
9
9
|
@page_view = page_view
|
10
10
|
@count = count
|
11
|
+
@last_timestamp = timestamp != nil ? timestamp : Time.new.to_i
|
11
12
|
end
|
12
13
|
|
14
|
+
# Not thread-save method, should be called in synchronized code
|
15
|
+
# We need to return a new PageViewVisit for case if PageView was already sent and it's new visit
|
13
16
|
def overwrite(page_view)
|
14
17
|
@page_view = page_view
|
15
18
|
@count += 1
|
16
19
|
end
|
20
|
+
|
21
|
+
# Not thread-save method, should be called in synchronized code
|
22
|
+
def merge (page_view_visit)
|
23
|
+
@count += page_view_visit.count
|
24
|
+
@last_timestamp = [@last_timestamp, page_view_visit.last_timestamp].max
|
25
|
+
end
|
26
|
+
|
27
|
+
# Not thread-save method, should be called in synchronized code
|
28
|
+
def increase_page_visits
|
29
|
+
@count += 1
|
30
|
+
end
|
17
31
|
end
|
18
32
|
end
|
19
33
|
end
|
@@ -18,8 +18,8 @@ module Kameleoon
|
|
18
18
|
# Visitor is a container of all data assigned to a visitor.
|
19
19
|
# It is thread-safe
|
20
20
|
class Visitor
|
21
|
-
attr_reader :last_activity_time, :user_agent, :device, :browser
|
22
|
-
attr_accessor :legal_consent
|
21
|
+
attr_reader :last_activity_time, :user_agent, :device, :browser, :geolocation, :operating_system, :cookie, :visitor_visits
|
22
|
+
attr_accessor :legal_consent, :mapping_identifier
|
23
23
|
|
24
24
|
def initialize
|
25
25
|
@mutex = Concurrent::ReadWriteLock.new
|
@@ -34,6 +34,8 @@ module Kameleoon
|
|
34
34
|
def enumerate_sendable_data(&blk)
|
35
35
|
blk.call(@device) unless @device.nil?
|
36
36
|
blk.call(@browser) unless @browser.nil?
|
37
|
+
blk.call(@operating_system) unless @operating_system.nil?
|
38
|
+
blk.call(@geolocation) unless @geolocation.nil?
|
37
39
|
@mutex.with_read_lock do
|
38
40
|
@custom_data_map&.each { |_, cd| blk.call(cd) }
|
39
41
|
@page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
|
@@ -47,6 +49,8 @@ module Kameleoon
|
|
47
49
|
@mutex.with_read_lock do
|
48
50
|
count += 1 unless @device.nil?
|
49
51
|
count += 1 unless @browser.nil?
|
52
|
+
count += 1 unless @geolocation.nil?
|
53
|
+
count += 1 unless @operating_system.nil?
|
50
54
|
count += @custom_data_map.size unless @custom_data_map.nil?
|
51
55
|
count += @page_view_visits.size unless @page_view_visits.nil?
|
52
56
|
count += @conversions.size unless @conversions.nil?
|
@@ -71,22 +75,34 @@ module Kameleoon
|
|
71
75
|
DataMapStorage.new(@mutex, @variations)
|
72
76
|
end
|
73
77
|
|
74
|
-
def add_data(log_func, *args)
|
78
|
+
def add_data(log_func, *args, overwrite: true)
|
75
79
|
@mutex.with_write_lock do
|
76
80
|
args.each do |data|
|
77
81
|
case data
|
78
82
|
when Kameleoon::UserAgent
|
79
|
-
|
83
|
+
set_user_agent(data)
|
84
|
+
when Kameleoon::DataManager::AssignedVariation
|
85
|
+
add_variation(data, overwrite)
|
80
86
|
when Kameleoon::Device
|
81
|
-
|
87
|
+
set_device(data, overwrite)
|
82
88
|
when Kameleoon::Browser
|
83
|
-
|
89
|
+
set_browser(data, overwrite)
|
84
90
|
when Kameleoon::CustomData
|
85
|
-
add_custom_data(data)
|
91
|
+
add_custom_data(data, overwrite)
|
86
92
|
when Kameleoon::PageView
|
87
93
|
add_page_view(data)
|
94
|
+
when Kameleoon::DataManager::PageViewVisit
|
95
|
+
add_page_view_visit(data)
|
88
96
|
when Kameleoon::Conversion
|
89
97
|
add_conversion(data)
|
98
|
+
when Kameleoon::Cookie
|
99
|
+
set_cookie(data)
|
100
|
+
when Kameleoon::OperatingSystem
|
101
|
+
set_operating_system(data, overwrite)
|
102
|
+
when Kameleoon::Geolocation
|
103
|
+
set_geolocation(data, overwrite)
|
104
|
+
when Kameleoon::VisitorVisits
|
105
|
+
set_visitor_visits(data)
|
90
106
|
else
|
91
107
|
log_func&.call("Data has unsupported type '#{data.class}'")
|
92
108
|
end
|
@@ -103,21 +119,28 @@ module Kameleoon
|
|
103
119
|
|
104
120
|
private
|
105
121
|
|
106
|
-
def
|
122
|
+
def set_user_agent(user_agent)
|
107
123
|
@user_agent = user_agent.value
|
108
124
|
end
|
109
125
|
|
110
|
-
def
|
111
|
-
@device = device
|
126
|
+
def set_device(device, overwrite)
|
127
|
+
@device = device if overwrite || @device == nil
|
112
128
|
end
|
113
129
|
|
114
|
-
def
|
115
|
-
@
|
130
|
+
def add_variation(variation, overwrite)
|
131
|
+
@variations = {} if @variations == nil
|
132
|
+
if overwrite || !@variations.include?(variation.experiment_id)
|
133
|
+
@variations[variation.experiment_id] = variation
|
134
|
+
end
|
116
135
|
end
|
117
136
|
|
118
|
-
def
|
137
|
+
def set_browser(browser, overwrite)
|
138
|
+
@browser = browser if overwrite || @browser == nil
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_custom_data(custom_data, overwrite)
|
119
142
|
@custom_data_map = {} if @custom_data_map.nil?
|
120
|
-
@custom_data_map[custom_data.id] = custom_data
|
143
|
+
@custom_data_map[custom_data.id] = custom_data if overwrite || !@custom_data_map.include?(custom_data.id)
|
121
144
|
end
|
122
145
|
|
123
146
|
def add_page_view(page_view)
|
@@ -133,10 +156,37 @@ module Kameleoon
|
|
133
156
|
@page_view_visits[page_view.url] = visit
|
134
157
|
end
|
135
158
|
|
159
|
+
def add_page_view_visit(page_view_visit)
|
160
|
+
@page_view_visits = {} if @page_view_visits.nil?
|
161
|
+
visit = @page_view_visits[page_view_visit.page_view.url]
|
162
|
+
if visit.nil?
|
163
|
+
visit = page_view_visit
|
164
|
+
@page_view_visits[page_view_visit.page_view.url] = visit
|
165
|
+
else
|
166
|
+
visit.merge(page_view_visit)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
136
170
|
def add_conversion(conversion)
|
137
171
|
@conversions = [] if @conversions.nil?
|
138
172
|
@conversions.push(conversion)
|
139
173
|
end
|
174
|
+
|
175
|
+
def set_geolocation(geolocation, overwrite)
|
176
|
+
@geolocation = geolocation if overwrite || @geolocation == nil
|
177
|
+
end
|
178
|
+
|
179
|
+
def set_cookie(cookie)
|
180
|
+
@cookie = cookie
|
181
|
+
end
|
182
|
+
|
183
|
+
def set_operating_system(operating_system, overwrite)
|
184
|
+
@operating_system = operating_system if overwrite || @operating_system == nil
|
185
|
+
end
|
186
|
+
|
187
|
+
def set_visitor_visits(visitor_visits)
|
188
|
+
@visitor_visits = visitor_visits
|
189
|
+
end
|
140
190
|
end
|
141
191
|
end
|
142
192
|
end
|
@@ -11,10 +11,12 @@ module Kameleoon
|
|
11
11
|
# It is thread-safe except `stop` method
|
12
12
|
class VisitorManager
|
13
13
|
attr_reader :expiration_period
|
14
|
+
attr_accessor :custom_data_info
|
14
15
|
|
15
|
-
def initialize(expiration_period)
|
16
|
+
def initialize(expiration_period, log_func = nil)
|
16
17
|
@expiration_period = expiration_period
|
17
18
|
@visitors = Concurrent::Map.new
|
19
|
+
@log_func = log_func
|
18
20
|
start
|
19
21
|
end
|
20
22
|
|
@@ -49,6 +51,26 @@ module Kameleoon
|
|
49
51
|
@visitors.size
|
50
52
|
end
|
51
53
|
|
54
|
+
def add_data(visitor_code, *args)
|
55
|
+
visitor = get_or_create_visitor(visitor_code)
|
56
|
+
for custom_data in args
|
57
|
+
next unless custom_data.is_a?(Kameleoon::CustomData)
|
58
|
+
# We shouldn't send custom data with local only type
|
59
|
+
custom_data.mark_as_sent if @custom_data_info.local_only?(custom_data.id)
|
60
|
+
# If mappingIdentifier is passed, we should link anonymous visitor with real unique userId.
|
61
|
+
# After authorization, customer must be able to continue work with userId, but hash for variation
|
62
|
+
# should be calculated based on anonymous visitor code, that's why set MappingIdentifier to visitor.
|
63
|
+
if @custom_data_info.mapping_identifier?(custom_data.id) && custom_data.values.size > 0 && custom_data.values[0].size > 0
|
64
|
+
custom_data.is_mapping_identifier = true
|
65
|
+
visitor.mapping_identifier = visitor_code
|
66
|
+
target_visitor_code = custom_data.values[0]
|
67
|
+
@visitors[target_visitor_code] = visitor if visitor_code != target_visitor_code
|
68
|
+
end
|
69
|
+
end
|
70
|
+
visitor.add_data(@log_func, *args)
|
71
|
+
visitor
|
72
|
+
end
|
73
|
+
|
52
74
|
private
|
53
75
|
|
54
76
|
def purge
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
module OperatingSystemType
|
5
|
+
WINDOWS = 0
|
6
|
+
MAC = 1
|
7
|
+
IOS = 2
|
8
|
+
LINUX = 3
|
9
|
+
ANDROID = 4
|
10
|
+
WINDOWS_PHONE = 5
|
11
|
+
|
12
|
+
def self.from_name(name)
|
13
|
+
case name
|
14
|
+
when 'WINDOWS'
|
15
|
+
WINDOWS
|
16
|
+
when 'MAC'
|
17
|
+
MAC
|
18
|
+
when 'IOS'
|
19
|
+
IOS
|
20
|
+
when 'LINUX'
|
21
|
+
LINUX
|
22
|
+
when 'ANDROID'
|
23
|
+
ANDROID
|
24
|
+
when 'WINDOWS_PHONE'
|
25
|
+
WINDOWS_PHONE
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.name_from_type(operating_system_type)
|
32
|
+
case operating_system_type
|
33
|
+
when OperatingSystemType::WINDOWS
|
34
|
+
'WINDOWS'
|
35
|
+
when OperatingSystemType::MAC
|
36
|
+
'MAC'
|
37
|
+
when OperatingSystemType::IOS
|
38
|
+
'IOS'
|
39
|
+
when OperatingSystemType::LINUX
|
40
|
+
'LINUX'
|
41
|
+
when OperatingSystemType::ANDROID
|
42
|
+
'ANDROID'
|
43
|
+
when OperatingSystemType::WINDOWS_PHONE
|
44
|
+
'WINDOWS_PHONE'
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# OperatingSystem contains information about the operating system on the visitor's device
|
52
|
+
class OperatingSystem < DuplicationUnsafeData
|
53
|
+
attr_reader :os_type
|
54
|
+
|
55
|
+
# @param [OperatingSystemType] os_type Operating system type, can be: WINDOWS, MAC, IOS, LINUX, ANDROID, WINDOWS_PHONE
|
56
|
+
def initialize(os_type)
|
57
|
+
super(DataType::OPERATING_SYSTEM)
|
58
|
+
@os_type = os_type
|
59
|
+
end
|
60
|
+
|
61
|
+
def obtain_full_post_text_line
|
62
|
+
params = {
|
63
|
+
eventType: 'staticData',
|
64
|
+
os: OperatingSystemType.name_from_type(@os_type),
|
65
|
+
osIndex: @os_type,
|
66
|
+
nonce: nonce
|
67
|
+
}
|
68
|
+
Kameleoon::Network::UriHelper.encode_query(params)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -10,9 +10,9 @@ module Kameleoon
|
|
10
10
|
attr_reader :url, :title, :referrer
|
11
11
|
|
12
12
|
# @param [String] url Url of the page
|
13
|
-
# @param [String] title
|
13
|
+
# @param [String] title Optional field - title of the page
|
14
14
|
# @param [Array] referrers Optional field - Referrer ids
|
15
|
-
def initialize(url, title, referrers = nil)
|
15
|
+
def initialize(url, title = nil, referrers = nil)
|
16
16
|
super(DataType::PAGE_VIEW)
|
17
17
|
@url = url || ''
|
18
18
|
print('Kameleoon SDK: Url for PageView is required parameter, the data will be ignored.') if url == ''
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kameleoon
|
4
|
+
class VisitorVisits
|
5
|
+
attr_reader :previous_visit_timestamps
|
6
|
+
|
7
|
+
def initialize(previous_visit_timestamps = [])
|
8
|
+
@previous_visit_timestamps = previous_visit_timestamps
|
9
|
+
@previous_visit_timestamps.freeze
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|