bento-sdk 0.5.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.
@@ -0,0 +1,91 @@
1
+ require "securerandom"
2
+
3
+ module Bento
4
+ class Analytics
5
+ module Utils
6
+ extend self
7
+
8
+ # public: Return a new hash with keys converted from strings to symbols
9
+ #
10
+ def symbolize_keys(hash)
11
+ hash.each_with_object({}) do |(k, v), memo|
12
+ memo[k.to_sym] = v
13
+ end
14
+ end
15
+
16
+ # public: Convert hash keys from strings to symbols in place
17
+ #
18
+ def symbolize_keys!(hash)
19
+ hash.replace symbolize_keys hash
20
+ end
21
+
22
+ # public: Return a new hash with keys as strings
23
+ #
24
+ def stringify_keys(hash)
25
+ hash.each_with_object({}) do |(k, v), memo|
26
+ memo[k.to_s] = v
27
+ end
28
+ end
29
+
30
+ # public: Returns a new hash with all the date values in the into iso8601
31
+ # strings
32
+ #
33
+ def isoify_dates(hash)
34
+ hash.each_with_object({}) do |(k, v), memo|
35
+ memo[k] = datetime_in_iso8601(v)
36
+ end
37
+ end
38
+
39
+ # public: Converts all the date values in the into iso8601 strings in place
40
+ #
41
+ def isoify_dates!(hash)
42
+ hash.replace isoify_dates hash
43
+ end
44
+
45
+ # public: Returns a uid string
46
+ #
47
+ def uid
48
+ arr = SecureRandom.random_bytes(16).unpack("NnnnnN")
49
+ arr[2] = (arr[2] & 0x0fff) | 0x4000
50
+ arr[3] = (arr[3] & 0x3fff) | 0x8000
51
+ "%08x-%04x-%04x-%04x-%04x%08x" % arr
52
+ end
53
+
54
+ def datetime_in_iso8601(datetime)
55
+ case datetime
56
+ when Time
57
+ time_in_iso8601 datetime
58
+ when DateTime
59
+ time_in_iso8601 datetime.to_time
60
+ when Date
61
+ date_in_iso8601 datetime
62
+ else
63
+ datetime
64
+ end
65
+ end
66
+
67
+ def time_in_iso8601(time, fraction_digits = 3)
68
+ fraction = if fraction_digits > 0
69
+ (".%06i" % time.usec)[0, fraction_digits + 1]
70
+ end
71
+
72
+ "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(time, true, "Z")}"
73
+ end
74
+
75
+ def date_in_iso8601(date)
76
+ date.strftime("%F")
77
+ end
78
+
79
+ def formatted_offset(time, colon = true, alternate_utc_string = nil)
80
+ time.utc? && alternate_utc_string || seconds_to_utc_offset(time.utc_offset, colon)
81
+ end
82
+
83
+ def seconds_to_utc_offset(seconds, colon = true)
84
+ (colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON) % [(seconds < 0 ? "-" : "+"), (seconds.abs / 3600), ((seconds.abs % 3600) / 60)]
85
+ end
86
+
87
+ UTC_OFFSET_WITH_COLON = "%s%02d:%02d"
88
+ UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(":", "")
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,5 @@
1
+ module Bento
2
+ class Analytics
3
+ VERSION = "0.1"
4
+ end
5
+ end
@@ -0,0 +1,69 @@
1
+ require "bento/sdk/defaults"
2
+ require "bento/sdk/message_batch"
3
+ require "bento/sdk/transport"
4
+ require "bento/sdk/utils"
5
+
6
+ module Bento
7
+ class Analytics
8
+ class Worker
9
+ include Bento::Analytics::Utils
10
+ include Bento::Analytics::Defaults
11
+ include Bento::Analytics::Logging
12
+
13
+ # public: Creates a new worker
14
+ #
15
+ # The worker continuously takes messages off the queue
16
+ # and makes requests to the app.bentonow.com API
17
+ #
18
+ # queue - Queue synchronized between client and worker
19
+ # write_key - String of the project's Write key
20
+ # options - Hash of worker options
21
+ # batch_size - Fixnum of how many items to send in a batch
22
+ # on_error - Proc of what to do on an error
23
+ #
24
+ def initialize(queue, write_key, options = {})
25
+ symbolize_keys! options
26
+ @queue = queue
27
+ @write_key = write_key
28
+ @on_error = options[:on_error] || proc { |status, error| }
29
+ batch_size = options[:batch_size] || Bento::Analytics::Defaults::MessageBatch::MAX_SIZE
30
+ @batch = Bento::Analytics::MessageBatch.new(batch_size)
31
+ @lock = Mutex.new
32
+ @transport = Bento::Analytics::Transport.new
33
+ end
34
+
35
+ # public: Continuously runs the loop to check for new events
36
+ #
37
+ def run
38
+ until Thread.current[:should_exit]
39
+ return if @queue.empty?
40
+
41
+ @lock.synchronize do
42
+ consume_message_from_queue! until @batch.full? || @queue.empty?
43
+ end
44
+
45
+ res = @transport.send @write_key, @batch
46
+ @on_error.call(res.status, res.error) unless res.status == 200
47
+
48
+ @lock.synchronize { @batch.clear }
49
+ end
50
+ ensure
51
+ @transport.shutdown
52
+ end
53
+
54
+ # public: Check whether we have outstanding requests.
55
+ #
56
+ def is_requesting?
57
+ @lock.synchronize { !@batch.empty? }
58
+ end
59
+
60
+ private
61
+
62
+ def consume_message_from_queue!
63
+ @batch << @queue.pop
64
+ rescue Bento::Analytics::MessageBatch::JSONGenerationError => e
65
+ @on_error.call(-1, e.to_s)
66
+ end
67
+ end
68
+ end
69
+ end
data/lib/bento-sdk.rb ADDED
@@ -0,0 +1,68 @@
1
+ require "bento/analytics"
2
+ require "bento/core/client"
3
+ require "bento/core/error"
4
+ require "bento/core/response"
5
+ require "bento/core/version"
6
+ require "bento/core/validators/base"
7
+ require "bento/core/validators/event_validators"
8
+ require "bento/core/validators/email_validators"
9
+ require "bento/resources/subscribers"
10
+ require "bento/resources/events"
11
+ require "bento/resources/emails"
12
+ require "bento/resources/spam"
13
+
14
+ require "bento/sdk/configuration"
15
+
16
+ require 'forwardable'
17
+ require 'faraday'
18
+
19
+ module Bento
20
+ class Error < StandardError; end
21
+
22
+ class ArgumentError < Error; end
23
+
24
+ class ConfigurationError < Error
25
+ attr_reader :key
26
+
27
+ def initialize(key)
28
+ @key = key.to_sym
29
+
30
+ super <<~CONFIG_ERROR_MESSAGE
31
+ Missing config value for `#{key}`
32
+
33
+ Please set a value for `#{key}` using an environment variable:
34
+
35
+ BENTO_#{key.to_s.upcase}=your-value
36
+
37
+ or via the `Bento.configure` method:
38
+
39
+ Bento.configure do |config|
40
+ config.#{key} = 'your-value'
41
+ end
42
+ CONFIG_ERROR_MESSAGE
43
+ end
44
+ end
45
+
46
+ class << self
47
+ extend Forwardable
48
+
49
+ # User configurable options
50
+ def_delegators :@config, :site_uuid, :site_uuid=
51
+ def_delegators :@config, :publishable_key, :publishable_key=
52
+ def_delegators :@config, :secret_key, :secret_key=
53
+ def_delegators :@config, :log_level, :log_level=
54
+ def_delegators :@config, :dev_mode, :dev_mode=
55
+
56
+ def config
57
+ @config ||= Bento::Configuration.new
58
+ end
59
+
60
+ def configure
61
+ yield config
62
+ end
63
+
64
+ def reset!
65
+ @config = nil
66
+ end
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bento-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - bentonow.com
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-02-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.15'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.15'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tzinfo
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: oj
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.6.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.6.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: standard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: The easiest way to track users and send emails in your Ruby on Rails
126
+ app
127
+ email: support@Bentonow.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - lib/bento-sdk.rb
133
+ - lib/bento/analytics.rb
134
+ - lib/bento/core/client.rb
135
+ - lib/bento/core/error.rb
136
+ - lib/bento/core/response.rb
137
+ - lib/bento/core/validators/base.rb
138
+ - lib/bento/core/validators/email_validators.rb
139
+ - lib/bento/core/validators/event_validators.rb
140
+ - lib/bento/core/version.rb
141
+ - lib/bento/resources/emails.rb
142
+ - lib/bento/resources/events.rb
143
+ - lib/bento/resources/spam.rb
144
+ - lib/bento/resources/subscribers.rb
145
+ - lib/bento/sdk/backoff_policy.rb
146
+ - lib/bento/sdk/client.rb
147
+ - lib/bento/sdk/configuration.rb
148
+ - lib/bento/sdk/defaults.rb
149
+ - lib/bento/sdk/field_parser.rb
150
+ - lib/bento/sdk/logging.rb
151
+ - lib/bento/sdk/message_batch.rb
152
+ - lib/bento/sdk/response.rb
153
+ - lib/bento/sdk/transport.rb
154
+ - lib/bento/sdk/utils.rb
155
+ - lib/bento/sdk/version.rb
156
+ - lib/bento/sdk/worker.rb
157
+ homepage: https://github.com/bentonow/bento-ruby-sdk
158
+ licenses:
159
+ - MIT
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '2.6'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubygems_version: 3.2.22
177
+ signing_key:
178
+ specification_version: 4
179
+ summary: Bento Ruby on Rails SDK
180
+ test_files: []