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.
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
+