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.
- checksums.yaml +7 -0
- data/lib/bento/analytics.rb +47 -0
- data/lib/bento/core/client.rb +47 -0
- data/lib/bento/core/error.rb +26 -0
- data/lib/bento/core/response.rb +23 -0
- data/lib/bento/core/validators/base.rb +18 -0
- data/lib/bento/core/validators/email_validators.rb +10 -0
- data/lib/bento/core/validators/event_validators.rb +46 -0
- data/lib/bento/core/version.rb +3 -0
- data/lib/bento/resources/emails.rb +59 -0
- data/lib/bento/resources/events.rb +77 -0
- data/lib/bento/resources/spam.rb +26 -0
- data/lib/bento/resources/subscribers.rb +137 -0
- data/lib/bento/sdk/backoff_policy.rb +49 -0
- data/lib/bento/sdk/client.rb +123 -0
- data/lib/bento/sdk/configuration.rb +85 -0
- data/lib/bento/sdk/defaults.rb +37 -0
- data/lib/bento/sdk/field_parser.rb +104 -0
- data/lib/bento/sdk/logging.rb +60 -0
- data/lib/bento/sdk/message_batch.rb +72 -0
- data/lib/bento/sdk/response.rb +15 -0
- data/lib/bento/sdk/transport.rb +144 -0
- data/lib/bento/sdk/utils.rb +91 -0
- data/lib/bento/sdk/version.rb +5 -0
- data/lib/bento/sdk/worker.rb +69 -0
- data/lib/bento-sdk.rb +68 -0
- metadata +180 -0
@@ -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,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: []
|