kameleoon-client-ruby 3.1.1 → 3.2.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kameleoon/configuration/custom_data_info.rb +43 -0
  3. data/lib/kameleoon/configuration/data_file.rb +30 -2
  4. data/lib/kameleoon/configuration/rule.rb +4 -1
  5. data/lib/kameleoon/configuration/variation_exposition.rb +1 -1
  6. data/lib/kameleoon/data/browser.rb +19 -0
  7. data/lib/kameleoon/data/cookie.rb +14 -0
  8. data/lib/kameleoon/data/custom_data.rb +2 -0
  9. data/lib/kameleoon/data/data.rb +2 -0
  10. data/lib/kameleoon/data/geolocation.rb +45 -0
  11. data/lib/kameleoon/data/manager/assigned_variation.rb +2 -1
  12. data/lib/kameleoon/data/manager/page_view_visit.rb +16 -2
  13. data/lib/kameleoon/data/manager/visitor.rb +64 -14
  14. data/lib/kameleoon/data/manager/visitor_manager.rb +23 -1
  15. data/lib/kameleoon/data/operating_system.rb +72 -0
  16. data/lib/kameleoon/data/page_view.rb +2 -2
  17. data/lib/kameleoon/data/visitor_visits.rb +13 -0
  18. data/lib/kameleoon/kameleoon_client.rb +75 -94
  19. data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +57 -0
  20. data/lib/kameleoon/managers/remote_data/remote_visitor_data.rb +162 -0
  21. data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +3 -1
  22. data/lib/kameleoon/network/access_token_source.rb +22 -5
  23. data/lib/kameleoon/network/network_manager.rb +10 -10
  24. data/lib/kameleoon/network/response.rb +1 -1
  25. data/lib/kameleoon/network/url_provider.rb +15 -12
  26. data/lib/kameleoon/targeting/condition.rb +22 -2
  27. data/lib/kameleoon/targeting/condition_factory.rb +36 -6
  28. data/lib/kameleoon/targeting/conditions/cookie_condition.rb +55 -0
  29. data/lib/kameleoon/targeting/conditions/exclusive_feature_flag_condition.rb +27 -0
  30. data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +33 -0
  31. data/lib/kameleoon/targeting/conditions/number_condition.rb +38 -0
  32. data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +27 -0
  33. data/lib/kameleoon/targeting/conditions/page_view_number_condition.rb +28 -0
  34. data/lib/kameleoon/targeting/conditions/previous_page_condition.rb +35 -0
  35. data/lib/kameleoon/targeting/conditions/segment_condition.rb +42 -0
  36. data/lib/kameleoon/targeting/conditions/target_feature_flag_condition.rb +63 -0
  37. data/lib/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.rb +30 -0
  38. data/lib/kameleoon/targeting/conditions/visit_number_today_condition.rb +28 -0
  39. data/lib/kameleoon/targeting/conditions/visit_number_total_condition.rb +21 -0
  40. data/lib/kameleoon/targeting/conditions/visitor_new_return_condition.rb +33 -0
  41. data/lib/kameleoon/targeting/targeting_manager.rb +66 -0
  42. data/lib/kameleoon/types/remote_visitor_data_filter.rb +24 -0
  43. data/lib/kameleoon/utils.rb +1 -0
  44. data/lib/kameleoon/version.rb +1 -1
  45. metadata +24 -4
  46. data/lib/kameleoon/targeting/conditions/exclusive_experiment.rb +0 -18
  47. 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: 3a2ae21c547d82441a35f311ca195d4d0b15be760535eb2d2cd33763cdaa5d3f
4
- data.tar.gz: ae9e41be3beda39be11c259d115d0543179e5b4a0549aa73b05c253d99cbd950
3
+ metadata.gz: b8dea61e52fdfa38f0fc3d2161711fe169940de6053d9d372fef06b30e70975f
4
+ data.tar.gz: 201acbdb7b3597d4637207c6f599c04dc9bbf0984de60fb93904569193152230
5
5
  SHA512:
6
- metadata.gz: 8e99dc556e6f39202765a6ac8da2f0c0ccf3d6f7ebccee7996f9741d5608eb485d6802b1920aaa78f881b0f66d05c63d89102df75ed20853aae562fc87787cf5
7
- data.tar.gz: 161950ca9c72591a7ffa59e82d231c01b478d504449557852b79570b97cb94cacf686033343275915653cc9f66cb9395563a542dc6955ed9b93354d4fa43c525
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
- attr_accessor :variation_key, :variation_id, :exposition
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
@@ -14,6 +14,8 @@ module Kameleoon
14
14
  DEVICE = 'DEVICE'
15
15
  PAGE_VIEW = 'PAGE_VIEW'
16
16
  ASSIGNED_VARIATION = 'ASSIGNED_VARIATION'
17
+ OPERATING_SYSTEM = 'OPERATING_SYSTEM'
18
+ GEOLOCATION = 'GEOLOCATION'
17
19
  end
18
20
 
19
21
  # Represents base class for any Kameleoon data
@@ -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
- add_user_agent(data)
83
+ set_user_agent(data)
84
+ when Kameleoon::DataManager::AssignedVariation
85
+ add_variation(data, overwrite)
80
86
  when Kameleoon::Device
81
- add_device(data)
87
+ set_device(data, overwrite)
82
88
  when Kameleoon::Browser
83
- add_browser(data)
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 add_user_agent(user_agent)
122
+ def set_user_agent(user_agent)
107
123
  @user_agent = user_agent.value
108
124
  end
109
125
 
110
- def add_device(device)
111
- @device = device
126
+ def set_device(device, overwrite)
127
+ @device = device if overwrite || @device == nil
112
128
  end
113
129
 
114
- def add_browser(browser)
115
- @browser = browser
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 add_custom_data(custom_data)
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 Title of the page
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
+