vwo-sdk 1.3.0 → 1.14.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require_relative '../logger'
17
+ require_relative '../enums'
18
+ require_relative '../constants'
19
+ require_relative './impression'
20
+
21
+ # Utility module for helper math and random functions
22
+ class VWO
23
+ module Utils
24
+ module CustomDimensions
25
+ include VWO::CONSTANTS
26
+ include VWO::Enums
27
+ include VWO::Utils::Impression
28
+
29
+ def get_url_params(settings_file, tag_key, tag_value, user_id, sdk_key)
30
+ url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::PUSH
31
+ tag = { 'u' => {} }
32
+ tag['u'][tag_key] = tag_value
33
+
34
+ params = get_common_properties(user_id, settings_file)
35
+ params.merge!('url' => url, 'tags' => JSON.generate(tag), 'env' => sdk_key)
36
+
37
+ VWO::Logger.get_instance.log(
38
+ LogLevelEnum::DEBUG,
39
+ format(
40
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
41
+ file: FileNameEnum::CustomDimensionsUtil,
42
+ properties: JSON.generate(params)
43
+ )
44
+ )
45
+ params
46
+ end
47
+
48
+ def get_batch_event_url_params(settings_file, tag_key, tag_value, user_id)
49
+ tag = { 'u' => {} }
50
+ tag['u'][tag_key] = tag_value
51
+
52
+ account_id = settings_file['accountId']
53
+ params = {
54
+ 'eT' => 3,
55
+ 't' => JSON.generate(tag),
56
+ 'u' => generator_for(user_id, account_id),
57
+ 'sId' => get_current_unix_timestamp
58
+ }
59
+
60
+ VWO::Logger.get_instance.log(
61
+ LogLevelEnum::DEBUG,
62
+ format(
63
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
64
+ file: FileNameEnum::CustomDimensionsUtil,
65
+ properties: JSON.generate(params)
66
+ )
67
+ )
68
+ params
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../logger'
16
+ require_relative '../enums'
17
+ require_relative '../constants'
18
+
19
+ # Utility module for helper math and random functions
20
+ class VWO
21
+ module Utils
22
+ module Feature
23
+ include VWO::CONSTANTS
24
+ include VWO::Enums
25
+
26
+ # Returns type casted value to given value type if possible.
27
+ # @param[Number|String|Boolean] :value Value to type cast
28
+ # @param[Type] :variable_type Type to which value needs to be casted
29
+ # @return[any] Type casted value if value can be type-casted
30
+ def get_type_casted_feature_value(value, variable_type)
31
+ # Check if type(value) is already equal to required variable_type
32
+ return value if RUBY_VARIABLE_TYPES[variable_type].include?(value.class)
33
+
34
+ return value.to_s if variable_type == VariableTypes::STRING
35
+
36
+ return value.to_i if variable_type == VariableTypes::INTEGER
37
+
38
+ return value.to_f if variable_type == VariableTypes::DOUBLE
39
+
40
+ return !value || value == 0 ? false : true if variable_type == VariableTypes.BOOLEAN
41
+ rescue StandardError => _e
42
+ VWO::Logger.get_instance.log(
43
+ LogLevelEnum::ERROR,
44
+ format(
45
+ LogMessageEnum::ErrorMessages::UNABLE_TO_TYPE_CAST,
46
+ file: FileNameEnum::FeatureUtil,
47
+ value: value,
48
+ variable_type: variable_type,
49
+ of_type: value.class.name
50
+ )
51
+ )
52
+ nil
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../logger'
18
16
  require_relative '../enums'
19
17
  require_relative '../constants'
@@ -34,6 +32,11 @@ class VWO
34
32
  def get_current_unix_timestamp
35
33
  Time.now.to_i
36
34
  end
35
+
36
+ # @return[any, any]
37
+ def get_key_value(obj)
38
+ [obj.keys[0], obj.values[0]]
39
+ end
37
40
  end
38
41
  end
39
42
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'json'
18
16
  require 'cgi'
19
17
  require_relative '../logger'
@@ -33,16 +31,17 @@ class VWO
33
31
 
34
32
  # Creates the impression from the arguments passed
35
33
  #
36
- # @param[Hash] :settings_file Settings file object
34
+ # @param[Hash] :settings_file Settings file object
37
35
  # @param[String] :campaign_id Campaign identifier
38
36
  # @param[String] :variation_id Variation identifier
39
37
  # @param[String] :user_id User identifier
38
+ # @param[String] :sdk_key SDK Key
40
39
  # @param[String] :goal_id Goal identifier, if building track impression
41
40
  # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
42
41
  #
43
42
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
44
43
  # Else Properties(dict)
45
- def create_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
44
+ def create_impression(settings_file, campaign_id, variation_id, user_id, sdk_key, goal_id = nil, revenue = nil, usage_stats = {})
46
45
  return unless valid_number?(campaign_id) && valid_string?(user_id)
47
46
 
48
47
  is_track_user_api = true
@@ -53,17 +52,19 @@ class VWO
53
52
  account_id: account_id,
54
53
  experiment_id: campaign_id,
55
54
  ap: PLATFORM,
56
- uId: CGI.escape(user_id.encode('utf-8')),
57
55
  combination: variation_id,
58
56
  random: get_random_number,
59
57
  sId: get_current_unix_timestamp,
60
- u: generator_for(user_id, account_id)
58
+ u: generator_for(user_id, account_id),
59
+ env: sdk_key
61
60
  }
62
61
  # Version and SDK constants
63
62
  sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
64
63
  impression['sdk'] = 'ruby'
65
64
  impression['sdk-v'] = sdk_version
66
65
 
66
+ impression = usage_stats.merge(impression)
67
+
67
68
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
68
69
  logger = VWO::Logger.get_instance
69
70
 
@@ -93,6 +94,74 @@ class VWO
93
94
  end
94
95
  impression
95
96
  end
97
+
98
+ # Returns commonly used params for making requests to our servers.
99
+ #
100
+ # @param[String] :user_id Unique identification of user
101
+ # @param[String] :settings_file Settings file containing campaign data for extracting account_id
102
+ # @return[Hash] Commonly used params for making call to our servers
103
+ #
104
+ def get_common_properties(user_id, settings_file)
105
+ account_id = settings_file['accountId']
106
+ {
107
+ 'random' => get_random_number,
108
+ 'sdk' => SDK_NAME,
109
+ 'sdk-v' => SDK_VERSION,
110
+ 'ap' => PLATFORM,
111
+ 'sId' => get_current_unix_timestamp,
112
+ 'u' => generator_for(user_id, account_id),
113
+ 'account_id' => account_id
114
+ }
115
+ end
116
+
117
+ # Creates properties for the bulk impression event
118
+ #
119
+ # @param[Hash] :settings_file Settings file object
120
+ # @param[String] :campaign_id Campaign identifier
121
+ # @param[String] :variation_id Variation identifier
122
+ # @param[String] :user_id User identifier
123
+ # @param[String] :sdk_key SDK Key
124
+ # @param[String] :goal_id Goal identifier, if building track impression
125
+ # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
126
+ #
127
+ # @return[nil|Hash] None if campaign ID or variation ID is invalid,
128
+ # Else Properties(dict)
129
+ def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
130
+ return unless valid_number?(campaign_id) && valid_string?(user_id)
131
+ is_track_user_api = true
132
+ is_track_user_api = false unless goal_id.nil?
133
+ account_id = settings_file['accountId']
134
+ impression = {
135
+ eT: is_track_user_api ? 1 : 2,
136
+ e: campaign_id,
137
+ c: variation_id,
138
+ u: generator_for(user_id, account_id),
139
+ sId: get_current_unix_timestamp
140
+ }
141
+ logger = VWO::Logger.get_instance
142
+ if is_track_user_api
143
+ logger.log(
144
+ LogLevelEnum::DEBUG,
145
+ format(
146
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_USER,
147
+ file: FileNameEnum::ImpressionUtil,
148
+ properties: JSON.generate(impression)
149
+ )
150
+ )
151
+ else
152
+ impression['g'] = goal_id
153
+ impression['r'] = revenue if revenue
154
+ logger.log(
155
+ LogLevelEnum::DEBUG,
156
+ format(
157
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_GOAL,
158
+ file: FileNameEnum::ImpressionUtil,
159
+ properties: JSON.generate(impression)
160
+ )
161
+ )
162
+ end
163
+ impression
164
+ end
96
165
  end
97
166
  end
98
167
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'net/http'
18
16
 
19
17
  class VWO
@@ -26,6 +24,20 @@ class VWO
26
24
  uri.query = URI.encode_www_form(params)
27
25
  Net::HTTP.get_response(uri)
28
26
  end
27
+
28
+ def self.post(url, params, post_data)
29
+ uri = URI.parse(url)
30
+ http = Net::HTTP.new(uri.host, uri.port)
31
+ http.use_ssl = true
32
+ uri.query = URI.encode_www_form(params)
33
+ headers = {
34
+ 'Authorization'=>params[:env],
35
+ 'Content-Type' =>'application/json',
36
+ 'Accept'=>'application/json'
37
+ }
38
+ response = http.post(uri, post_data.to_json, headers)
39
+ response
40
+ end
29
41
  end
30
42
  end
31
43
  end
@@ -0,0 +1,116 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../enums'
16
+
17
+ # Utility module for helper math and random functions
18
+ class VWO
19
+ module Utils
20
+ module Segment
21
+ GROUPING_PATTERN = /^(.+?)\((.*)\)/
22
+ WILDCARD_PATTERN = /(^\*|^)(.+?)(\*$|$)/
23
+ include VWO::Enums
24
+
25
+ # Extracts true values represented in the args, and returns stringified value of it
26
+ #
27
+ # @param [String] :operator_value operand/dsl leaf value
28
+ # @param [String|Number] :custom_variables_value custom_variables value
29
+ # @return [[String, String]] tuple of str value of operator_value, custom_variables_value converted
30
+ # into their true types
31
+ def convert_to_true_types(operator_value, custom_variables_value)
32
+ # This is atomic, either both values will be processed or none
33
+ begin
34
+ true_type_operator_value = Kernel::Float(operator_value)
35
+ true_type_custom_variables_value = Kernel::Float(custom_variables_value)
36
+ rescue StandardError => _e
37
+ return operator_value, custom_variables_value
38
+ end
39
+ # Now both are float, So, convert them independently to int type if they are int rather than floats
40
+ true_type_operator_value = true_type_operator_value.to_i if true_type_operator_value == true_type_operator_value.floor
41
+
42
+ true_type_custom_variables_value = true_type_custom_variables_value.to_i if true_type_custom_variables_value == true_type_custom_variables_value.floor
43
+
44
+ # Convert them back to string and return
45
+ [true_type_operator_value.to_s, true_type_custom_variables_value.to_s]
46
+ end
47
+
48
+ # Extract the operand_type, ie. lower, wildcard, regex or equals
49
+ #
50
+ # @param[String] :operand string value from leaf_node of dsl
51
+ # @return [[String, String]] tuple of operand value and operand type
52
+ #
53
+ def separate_operand(operand)
54
+ groups = GROUPING_PATTERN.match(operand)
55
+ return groups[1..2] if groups
56
+
57
+ [OperandValueTypesName::EQUALS, operand]
58
+ end
59
+
60
+ # Processes the value from the custom_variables_variables
61
+ # @param[String|Number|Boolean|nil] :custom_variables_value the custom_variables_value provided inside custom_variables
62
+ #
63
+ # @return [String] stringified value of processed custom_variables_value
64
+ #
65
+ def process_custom_variables_value(custom_variables_value)
66
+ return '' if custom_variables_value.nil?
67
+
68
+ if custom_variables_value.is_a?(TrueClass) || custom_variables_value.is_a?(FalseClass)
69
+ custom_variables_value = custom_variables_value ? OperandValuesBooleanTypes::TRUE : OperandValuesBooleanTypes::FALSE
70
+ end
71
+ custom_variables_value.to_s
72
+ end
73
+
74
+ # Extracts operand_type and operand_value from the leaf_node/operand
75
+ # @param[String] :operand String value from the leaf_node
76
+ # @return[[String, String]] Tuple of defined operand_types and operand_value
77
+ #
78
+ def process_operand_value(operand)
79
+ # Separate the operand type and value inside the bracket
80
+
81
+ operand_type_name, operand_value = separate_operand(operand)
82
+
83
+ # Enum the operand type, here lower, regex, and equals will be identified
84
+ operand_type =
85
+ begin
86
+ VWO::Enums::OperandValueTypesName.const_get(operand_type_name.upcase)
87
+ rescue StandardError => _e
88
+ nil
89
+ end
90
+
91
+ # In case of wildcard, the operand type is further divided into contains, startswith and endswith
92
+ if operand_type_name == OperandValueTypesName::WILDCARD
93
+ starting_star, operand_value, ending_star = WILDCARD_PATTERN.match(operand_value)[1..3]
94
+ operand_type =
95
+ if starting_star.to_s.length > 0 && ending_star.to_s.length > 0
96
+ OperandValueTypes::CONTAINS
97
+ elsif starting_star.to_s.length > 0
98
+ OperandValueTypes::STARTS_WITH
99
+ elsif ending_star.to_s.length > 0
100
+ OperandValueTypes::ENDS_WITH
101
+ else
102
+ OperandValueTypes::EQUALS
103
+ end
104
+ end
105
+
106
+ # In case there is an abnormal patter, it would have passed all the above if cases, which means it
107
+ # should be equals, so set the whole operand as operand value and operand type as equals
108
+ if operand_type.nil?
109
+ operand_type = OperandValueTypes::EQUALS
110
+ operand_value = operand
111
+ end
112
+ [operand_type, operand_value]
113
+ end
114
+ end
115
+ end
116
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'digest'
18
16
  require_relative '../logger'
19
17
  require_relative '../enums'
@@ -44,9 +42,9 @@ class VWO
44
42
  ary = hash.digest.unpack('NnnnnN')
45
43
  ary[2] = (ary[2] & 0x0FFF) | (version << 12)
46
44
  ary[3] = (ary[3] & 0x3FFF) | 0x8000
47
- # rubocop:disable Lint/FormatString
45
+ # rubocop:disable Lint/FormatStringToken,Style/FormatString
48
46
  '%08x-%04x-%04x-%04x-%04x%08x' % ary
49
- # rubocop:enable Lint/FormatString
47
+ # rubocop:enable Lint/FormatStringToken,Style/FormatString
50
48
  end
51
49
 
52
50
  VWO_NAMESPACE = uuid_v5(URL_NAMESPACE, 'https://vwo.com')