simple_segment 0.2.1 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 51451276d36995db980573591e7703e32e7ba5c2
4
- data.tar.gz: e34ae21510134d077de91a191bd9d29fd613ff28
2
+ SHA256:
3
+ metadata.gz: 6fb16e2b7875babb8be42dcd1bd734c150a9965be347d59ce8c977597fd07679
4
+ data.tar.gz: 291ec1529c2db59b7b047af54e2dad386c83f885422e4ecdd59f2aff448444d8
5
5
  SHA512:
6
- metadata.gz: 9060d055127519c59e9033b2a42a222321265c90f20f164e77a84a9cf7f144955a02490776fb79a57beb1cff9e7fb5d5b5f27f7f6a0c821636850c829859b7fa
7
- data.tar.gz: 156154cbb0ca38e288727142fc5d80fc9d264503259f40477b4dce8739621ef8a402467225863dff16816f0f34a4d6e50e2834cfe80dfa073f24b3dbc1a6f8d1
6
+ metadata.gz: d931d49bc337899519bf9731b0f0262b0b88eb7f36256e9255730fae574d328af1a98a27d82f947f1e03e49e4f629ffc7a1eb08ba4732a8aeda9e22e841d0d1b
7
+ data.tar.gz: 2f574ae47e801ab3d1fb2d079c288142590f8a8e8d7916ab386e53b69858d0fb9175779509301cd9bea1e790b7926cbf54bb9213820cb1aabebd0062e02bfd4f
data/.hound.yml CHANGED
@@ -1,2 +1,3 @@
1
- ruby:
1
+ rubocop:
2
2
  config_file: .rubocop.yml
3
+ version: 0.75.0
@@ -3,6 +3,8 @@ Metrics/BlockLength:
3
3
  - '**/*_spec.rb'
4
4
 
5
5
  Metrics/LineLength:
6
+ Max: 100
7
+ IgnoreCopDirectives: true
6
8
  Exclude:
7
9
  - 'simple_segment.gemspec'
8
10
 
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.8
4
- - 2.2.4
5
- - 2.3.0
6
- before_install: gem install bundler -v 1.11.2
3
+ - 2.4
4
+ - 2.5
5
+ - 2.6
6
+ - 2.7
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [1.2.0] - 2020-07-29
10
+
11
+ ### Changed
12
+ - Use an empty hash if no properties were provided to `track` https://github.com/whatthewhat/simple_segment/pull/28
13
+
14
+ ## [1.1.0] - 2020-04-11
15
+
16
+ ### Added
17
+ - Added support for http_proxy and https_proxy environment variables https://github.com/whatthewhat/simple_segment/pull/26 by @saks
18
+ - Added Ruby 2.7 to travis.yml
19
+
20
+ ## [1.0.0] - 2019-12-12
21
+
22
+ ### Added
23
+ - Allow passing custom Net::HTTP options (e.g. timeout) https://github.com/whatthewhat/simple_segment/pull/23 by @barodeur
24
+
25
+ ### Changed
26
+ - The gem is no longer tested with Ruby versions below 2.4
27
+
28
+ ## [0.3.0] - 2018-03-15
29
+
30
+ ### Changed
31
+ - Date properties are now automatically converted to ISO 8601 to be consistent with the official client https://github.com/whatthewhat/simple_segment/pull/19 by @juanramoncg
32
+
33
+ [Unreleased]: https://github.com/whatthewhat/simple_segment/compare/v1.2.0...HEAD
34
+ [1.2.0]: https://github.com/whatthewhat/simple_segment/compare/v1.1.0...v1.2.0
35
+ [1.1.0]: https://github.com/whatthewhat/simple_segment/compare/v1.0.0...v1.1.0
36
+ [1.0.0]: https://github.com/whatthewhat/simple_segment/compare/v0.3.0...v1.0.0
37
+ [0.3.0]: https://github.com/whatthewhat/simple_segment/compare/v0.2.1...v0.3.0
38
+ [0.2.1]: https://github.com/whatthewhat/simple_segment/compare/v0.2.0...v0.2.1
39
+ [0.2.0]: https://github.com/whatthewhat/simple_segment/compare/v0.1.1...v0.2.0
40
+ [0.1.1]: https://github.com/whatthewhat/simple_segment/compare/v0.1.0...v0.1.1
41
+ [0.1.0]: https://github.com/whatthewhat/simple_segment/compare/2d62f07a1df8388000b0b5a20331409132d05ad3...v0.1.0
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in simple_segment.gemspec
data/README.md CHANGED
@@ -29,34 +29,32 @@ Add this line to your application's Gemfile:
29
29
  gem 'simple_segment'
30
30
  ```
31
31
 
32
- And then execute:
33
-
34
- $ bundle
35
-
36
32
  Or install it yourself as:
37
33
 
38
- $ gem install simple_segment
34
+ ```sh
35
+ $ gem install simple_segment
36
+ ```
39
37
 
40
38
  ## Usage
41
39
 
42
40
  Create a client instance:
43
41
 
44
42
  ```ruby
45
- analytics = SimpleSegment::Client.new({
43
+ analytics = SimpleSegment::Client.new(
46
44
  write_key: 'YOUR_WRITE_KEY', # required
47
- on_error: proc { |error_code, error_body, response, exception|
45
+ on_error: proc { |error_code, error_body, exception, response|
48
46
  # defaults to an empty proc
49
47
  }
50
- })
48
+ )
51
49
  ```
52
50
 
53
51
  Use it as you would use `analytics-ruby`:
54
52
 
55
53
  ```ruby
56
- analytics.track({
54
+ analytics.track(
57
55
  user_id: user.id,
58
56
  event: 'Created Account'
59
- })
57
+ )
60
58
  ```
61
59
 
62
60
  ### Batching
@@ -86,6 +84,7 @@ analytics = SimpleSegment::Client.new(
86
84
  ```
87
85
 
88
86
  ### Configurable Logger
87
+
89
88
  When used in stubbed mode all calls are logged to STDOUT, this can be changed by providing a custom logger object:
90
89
 
91
90
  ```ruby
@@ -95,6 +94,22 @@ analytics = SimpleSegment::Client.new(
95
94
  )
96
95
  ```
97
96
 
97
+ ### Set HTTP Options
98
+
99
+ You can set [options](https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html#method-c-start) that are passed to `Net::HTTP.start`.
100
+
101
+ ```ruby
102
+ analytics = SimpleSegment::Client.new(
103
+ write_key: 'YOUR_WRITE_KEY',
104
+ http_options: {
105
+ open_timeout: 42,
106
+ read_timeout: 42,
107
+ close_on_empty_response: true,
108
+ # ...
109
+ }
110
+ )
111
+ ```
112
+
98
113
  ## Development
99
114
 
100
115
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'simple_segment'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'json'
3
5
  require 'time'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  class Batch
3
5
  include SimpleSegment::Utils
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simple_segment/utils'
2
4
  require 'simple_segment/configuration'
3
5
  require 'simple_segment/operations'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simple_segment/logging'
2
4
 
3
5
  module SimpleSegment
@@ -5,7 +7,7 @@ module SimpleSegment
5
7
  include SimpleSegment::Utils
6
8
  include SimpleSegment::Logging
7
9
 
8
- attr_reader :write_key, :on_error, :stub, :logger
10
+ attr_reader :write_key, :on_error, :stub, :logger, :http_options
9
11
 
10
12
  def initialize(settings = {})
11
13
  symbolized_settings = symbolize_keys(settings)
@@ -13,6 +15,8 @@ module SimpleSegment
13
15
  @on_error = symbolized_settings[:on_error] || proc {}
14
16
  @stub = symbolized_settings[:stub]
15
17
  @logger = default_logger(symbolized_settings[:logger])
18
+ @http_options = { use_ssl: true }
19
+ .merge(symbolized_settings[:http_options] || {})
16
20
  raise ArgumentError, 'Missing required option :write_key' \
17
21
  unless @write_key
18
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'logger'
2
4
  module SimpleSegment
3
5
  module Logging
@@ -6,11 +8,7 @@ module SimpleSegment
6
8
  end
7
9
 
8
10
  def default_logger(logger_option)
9
- if logger_option
10
- logger_option
11
- else
12
- Logger.new STDOUT
13
- end
11
+ logger_option || Logger.new(STDOUT)
14
12
  end
15
13
  end
16
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simple_segment/request'
2
4
  require 'simple_segment/operations/operation'
3
5
  require 'simple_segment/operations/identify'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Alias < Operation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Group < Operation
@@ -10,7 +12,7 @@ module SimpleSegment
10
12
  unless options[:group_id]
11
13
 
12
14
  base_payload.merge(
13
- traits: options[:traits],
15
+ traits: options[:traits] && isoify_dates!(options[:traits]),
14
16
  groupId: options[:group_id]
15
17
  )
16
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Identify < Operation
@@ -7,7 +9,7 @@ module SimpleSegment
7
9
 
8
10
  def build_payload
9
11
  base_payload.merge(
10
- traits: options[:traits]
12
+ traits: options[:traits] && isoify_dates!(options[:traits])
11
13
  )
12
14
  end
13
15
  end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Operation
6
+ include SimpleSegment::Utils
7
+
4
8
  DEFAULT_CONTEXT = {
5
9
  library: {
6
10
  name: 'simple_segment',
@@ -8,10 +12,9 @@ module SimpleSegment
8
12
  }
9
13
  }.freeze
10
14
 
11
- attr_reader :options, :request
12
-
13
15
  def initialize(client, options = {})
14
16
  @options = options
17
+ @context = DEFAULT_CONTEXT.merge(options[:context].to_h)
15
18
  @request = Request.new(client)
16
19
  end
17
20
 
@@ -21,6 +24,8 @@ module SimpleSegment
21
24
 
22
25
  private
23
26
 
27
+ attr_reader :options, :request, :context
28
+
24
29
  def base_payload
25
30
  check_identity!
26
31
  current_time = Time.now
@@ -28,7 +33,7 @@ module SimpleSegment
28
33
  {
29
34
  userId: options[:user_id],
30
35
  anonymousId: options[:anonymous_id],
31
- context: DEFAULT_CONTEXT.merge(options[:context].to_h),
36
+ context: context,
32
37
  integrations: options[:integrations],
33
38
  timestamp: timestamp(options.fetch(:timestamp, current_time)),
34
39
  sentAt: current_time.iso8601
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Page < Operation
@@ -6,9 +8,11 @@ module SimpleSegment
6
8
  end
7
9
 
8
10
  def build_payload
11
+ properties = options[:properties] && isoify_dates!(options[:properties])
12
+
9
13
  base_payload.merge(
10
14
  name: options[:name],
11
- properties: options[:properties]
15
+ properties: properties
12
16
  )
13
17
  end
14
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Operations
3
5
  class Track < Operation
@@ -6,12 +8,13 @@ module SimpleSegment
6
8
  end
7
9
 
8
10
  def build_payload
9
- raise ArgumentError, 'event name must be present' \
10
- unless options[:event]
11
+ raise ArgumentError, 'event name must be present' unless options[:event]
12
+
13
+ properties = options[:properties] || {}
11
14
 
12
15
  base_payload.merge(
13
16
  event: options[:event],
14
- properties: options[:properties]
17
+ properties: isoify_dates!(properties)
15
18
  )
16
19
  end
17
20
  end
@@ -1,21 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  class Request
3
- BASE_URL = 'https://api.segment.io'.freeze
5
+ BASE_URL = 'https://api.segment.io'
4
6
  DEFAULT_HEADERS = {
5
7
  'Content-Type' => 'application/json',
6
8
  'accept' => 'application/json'
7
9
  }.freeze
8
10
 
9
- attr_reader :write_key, :error_handler, :stub, :logger
11
+ attr_reader :write_key, :error_handler, :stub, :logger, :http_options
10
12
 
11
13
  def initialize(client)
12
14
  @write_key = client.config.write_key
13
15
  @error_handler = client.config.on_error
14
16
  @stub = client.config.stub
15
17
  @logger = client.config.logger
18
+ @http_options = client.config.http_options
16
19
  end
17
20
 
18
- def post(path, payload, headers: DEFAULT_HEADERS)
21
+ def post(path, payload, headers: DEFAULT_HEADERS) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
19
22
  response = nil
20
23
  status_code = nil
21
24
  response_body = nil
@@ -29,7 +32,7 @@ module SimpleSegment
29
32
 
30
33
  { status: 200, error: nil }
31
34
  else
32
- Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
35
+ Net::HTTP.start(uri.host, uri.port, :ENV, http_options) do |http|
33
36
  request = Net::HTTP::Post.new(path, headers)
34
37
  request.basic_auth write_key, nil
35
38
  http.request(request, payload).tap do |res|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
4
  module Utils
3
5
  def self.included(klass)
@@ -9,5 +11,33 @@ module SimpleSegment
9
11
  result[key.to_sym] = value
10
12
  end
11
13
  end
14
+
15
+ # public: Converts all the date values in the into iso8601 strings in place
16
+ #
17
+ def isoify_dates!(hash)
18
+ hash.replace isoify_dates hash
19
+ end
20
+
21
+ # public: Returns a new hash with all the date values in the into iso8601
22
+ # strings
23
+ #
24
+ def isoify_dates(hash)
25
+ hash.each_with_object({}) do |(k, v), memo|
26
+ memo[k] = maybe_datetime_in_iso8601(v)
27
+ end
28
+ end
29
+
30
+ def maybe_datetime_in_iso8601(prop)
31
+ case prop
32
+ when Time
33
+ prop.iso8601(3)
34
+ when DateTime
35
+ prop.to_time.iso8601(3)
36
+ when Date
37
+ prop.strftime('%F')
38
+ else
39
+ prop
40
+ end
41
+ end
12
42
  end
13
43
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleSegment
2
- VERSION = '0.2.1'.freeze
4
+ VERSION = '1.2.0'
3
5
  end
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'simple_segment/version'
5
6
 
@@ -19,11 +20,11 @@ Gem::Specification.new do |spec|
19
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
21
  spec.require_paths = ['lib']
21
22
 
22
- spec.add_development_dependency 'bundler', '~> 1.11'
23
- spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'bundler', '>= 1.11'
24
+ spec.add_development_dependency 'pry'
25
+ spec.add_development_dependency 'rake', '>= 10.0'
24
26
  spec.add_development_dependency 'rspec', '~> 3.0'
25
- spec.add_development_dependency 'webmock', '~> 1.24'
27
+ spec.add_development_dependency 'rubocop', '0.75.0'
26
28
  spec.add_development_dependency 'timecop', '~> 0.8.0'
27
- spec.add_development_dependency 'rubocop', '~> 0.47.0'
28
- spec.add_development_dependency 'pry'
29
+ spec.add_development_dependency 'webmock', '~> 3.7'
29
30
  end
metadata CHANGED
@@ -1,41 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_segment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikhail Topolskiy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-11 00:00:00.000000000 Z
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.11'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '10.0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '10.0'
41
55
  - !ruby/object:Gem::Dependency
@@ -53,19 +67,19 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '3.0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: webmock
70
+ name: rubocop
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - '='
60
74
  - !ruby/object:Gem::Version
61
- version: '1.24'
75
+ version: 0.75.0
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - '='
67
81
  - !ruby/object:Gem::Version
68
- version: '1.24'
82
+ version: 0.75.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: timecop
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -81,33 +95,19 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: 0.8.0
83
97
  - !ruby/object:Gem::Dependency
84
- name: rubocop
98
+ name: webmock
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.47.0
103
+ version: '3.7'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 0.47.0
97
- - !ruby/object:Gem::Dependency
98
- name: pry
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '3.7'
111
111
  description: SimpleSegment allows for manual control of when and how the events are
112
112
  sent to Segment.
113
113
  email:
@@ -121,6 +121,7 @@ files:
121
121
  - ".rspec"
122
122
  - ".rubocop.yml"
123
123
  - ".travis.yml"
124
+ - CHANGELOG.md
124
125
  - Gemfile
125
126
  - LICENSE.txt
126
127
  - README.md
@@ -162,8 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
163
  - !ruby/object:Gem::Version
163
164
  version: '0'
164
165
  requirements: []
165
- rubyforge_project:
166
- rubygems_version: 2.6.8
166
+ rubygems_version: 3.0.3
167
167
  signing_key:
168
168
  specification_version: 4
169
169
  summary: A simple synchronous API client for segment.io.