ecoportal-api 0.9.7 → 0.10.1

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.
@@ -1,11 +1,12 @@
1
+ # rubocop:disable Naming/PredicateName
1
2
  module Ecoportal
2
3
  module API
3
4
  module Common
4
5
  class BaseModel
5
- class UnlinkedModel < Exception
6
- def initialize (msg = "Something went wrong when linking the document.", from: nil, key: nil)
7
- msg += " From: #{from}." if from
8
- msg += " key: #{key}." if key
6
+ class UnlinkedModel < StandardError
7
+ def initialize(msg = "Something went wrong when linking the document.", from: nil, key: nil)
8
+ msg << " From: #{from}." if from
9
+ msg << " key: #{key}." if key
9
10
  super(msg)
10
11
  end
11
12
  end
@@ -25,10 +26,11 @@ module Ecoportal
25
26
  end
26
27
  end
27
28
 
28
- def embeds_one(method, key: method, nullable: false, klass:)
29
+ def embeds_one(method, klass:, key: method, nullable: false)
29
30
  method = method.to_s.freeze
30
31
  var = "@#{method}".freeze
31
32
  key = key.to_s.freeze
33
+
32
34
  define_method(method) do
33
35
  if instance_variable_defined?(var)
34
36
  value = instance_variable_get(var)
@@ -36,7 +38,9 @@ module Ecoportal
36
38
  return value if (value && doc[key]) || (!value && !doc[key])
37
39
  remove_instance_variable(var)
38
40
  end
41
+
39
42
  doc[key] ||= {} unless nullable
43
+
40
44
  return instance_variable_set(var, nil) unless doc[key]
41
45
 
42
46
  self.class.resolve_class(klass).new(
@@ -44,7 +48,6 @@ module Ecoportal
44
48
  ).tap {|obj| instance_variable_set(var, obj)}
45
49
  end
46
50
  end
47
-
48
51
  end
49
52
 
50
53
  attr_reader :_parent, :_key
@@ -52,28 +55,32 @@ module Ecoportal
52
55
  def initialize(doc = {}, parent: self, key: nil)
53
56
  @_parent = parent
54
57
  @_key = key
55
- if !_parent || !_key
56
- @doc = JSON.parse(doc.to_json)
57
- @original_doc = JSON.parse(@doc.to_json)
58
- @initial_doc = JSON.parse(@doc.to_json)
59
- end
58
+
59
+ return unless !_parent || !_key
60
+
61
+ @doc = JSON.parse(doc.to_json)
62
+ @original_doc = JSON.parse(@doc.to_json)
63
+ @initial_doc = JSON.parse(@doc.to_json)
60
64
  end
61
65
 
62
66
  def doc
63
- raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
67
+ raise UnlinkedModel.new(from: "#{self.class}#doc", key: _key) unless linked?
64
68
  return @doc if is_root?
69
+
65
70
  _parent.doc.dig(*[_key].flatten)
66
71
  end
67
72
 
68
73
  def original_doc
69
- raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked?
74
+ raise UnlinkedModel.new(from: "#{self.class}#original_doc", key: _key) unless linked?
70
75
  return @original_doc if is_root?
76
+
71
77
  _parent.original_doc&.dig(*[_key].flatten)
72
78
  end
73
79
 
74
80
  def initial_doc
75
- raise UnlinkedModel.new(from: "#{self.class}#initial_doc", key: _key) unless linked?
81
+ raise UnlinkedModel.new(from: "#{self.class}#initial_doc", key: _key) unless linked?
76
82
  return @initial_doc if is_root?
83
+
77
84
  _parent.initial_doc&.dig(*[_key].flatten)
78
85
  end
79
86
 
@@ -81,6 +88,7 @@ module Ecoportal
81
88
  # @return [Hash] `doc` before change
82
89
  def replace_doc!(new_doc)
83
90
  raise UnlinkedModel.new(from: "#{self.class}#replace_doc", key: _key) unless linked?
91
+
84
92
  @doc.tap do
85
93
  @doc = new_doc
86
94
  end
@@ -90,6 +98,7 @@ module Ecoportal
90
98
  # @return [Hash] `original_doc` before change
91
99
  def replace_original_doc!(new_doc)
92
100
  raise UnlinkedModel.new(from: "#{self.class}#replace_original_doc", key: _key) unless linked?
101
+
93
102
  @original_doc.tap do
94
103
  @original_doc = new_doc
95
104
  end
@@ -115,7 +124,8 @@ module Ecoportal
115
124
 
116
125
  # It consolidates all the changes carried by `doc` by setting it as `original_doc`.
117
126
  def consolidate!
118
- raise UnlinkedModel.new(from: "#{self.class}#consolidate!", key: _key) unless linked?
127
+ raise UnlinkedModel.new(from: "#{self.class}#consolidate!", key: _key) unless linked?
128
+
119
129
  new_doc = JSON.parse(doc.to_json)
120
130
  if is_root?
121
131
  @original_doc = new_doc
@@ -130,18 +140,19 @@ module Ecoportal
130
140
  # i.e. `parent.reset!("child")` # when parent.child is `nil`
131
141
  # 2. In such a case, only immediate childs are allowed to be reset
132
142
  # @param key [String, Array<String>, nil] if given, it only resets the specified property
133
- def reset!(key = nil)
134
- raise "'key' should be a String. Given #{key}" unless !key || key.is_a?(String)
135
- raise UnlinkedModel.new(from: "#{self.class}#reset!", key: _key) unless linked?
143
+ def reset!(key = nil) # rubocop:disable Metrics/AbcSize>
144
+ msg = "'key' should be a String. Given #{key}"
145
+ raise ArgumentError, msg unless !key || key.is_a?(String)
146
+ raise UnlinkedModel.new(from: "#{self.class}#reset!", key: _key) unless linked?
136
147
 
137
148
  if key
138
- if self.respond_to?(key) && child = self.send(key) && child.is_a?(Ecoportal::API::Common::BaseModel)
149
+ if respond_to?(key) && (child = send(key)) && child.is_a?(Ecoportal::API::Common::BaseModel)
139
150
  child.reset!
140
151
  else
141
152
  new_doc = original_doc && original_doc[key]
142
153
  dig_set(doc, [key], new_doc && JSON.parse(new_doc.to_json))
143
154
  # regenerate object if new_doc is null
144
- self.send(key) if !new_doc && self.respond_to?(key)
155
+ send(key) if !new_doc && respond_to?(key)
145
156
  end
146
157
  else
147
158
  new_doc = JSON.parse(original_doc.to_json)
@@ -179,17 +190,17 @@ module Ecoportal
179
190
  end
180
191
 
181
192
  def set_uniq_array_keep_order(key, value)
182
- unless value.is_a?(Array)
183
- raise "#{key}= needs to be passed an Array, got #{value.class}"
184
- end
185
- ini_vals = (original_doc && original_doc[key]) || []
193
+ msg = "#{key}= needs to be passed an Array, got #{value.class}"
194
+ raise ArgumentError, msg unless value.is_a?(Array)
186
195
 
196
+ ini_vals = (original_doc && original_doc[key]) || []
187
197
  value = value.uniq
188
198
  # preserve original order to avoid false updates
189
199
  doc[key] = ((ini_vals & value) + (value - ini_vals)).compact
190
200
  end
191
-
192
201
  end
193
202
  end
194
203
  end
195
204
  end
205
+
206
+ # rubocop:enable Naming/PredicateName
@@ -28,19 +28,21 @@ module Ecoportal
28
28
  log(:info) { "Processing batch responses" }
29
29
 
30
30
  body_data(response.body).each.with_index do |subresponse, idx|
31
- callback = @operations[idx][:callback]
32
31
  status = subresponse["status"]
33
- body = subresponse["response"]
34
32
  method = @operations[idx][:method]
33
+ body = subresponse["response"]
34
+ callback = @operations[idx][:callback]
35
35
 
36
36
  if status == 200 && method == "GET"
37
37
  batch_response = BatchResponse.new(status, body, @wrapper.new(body))
38
38
  log_batch_response(@operations[idx], batch_response)
39
- callback && callback.call(batch_response, batch_response.result)
39
+
40
+ callback&.call(batch_response, batch_response.result)
40
41
  else
41
42
  batch_response = BatchResponse.new(status, body)
42
43
  log_batch_response(@operations[idx], batch_response)
43
- callback && callback.call(batch_response)
44
+
45
+ callback&.call(batch_response)
44
46
  end
45
47
  end
46
48
  end
@@ -48,9 +50,9 @@ module Ecoportal
48
50
  def get(doc, &block)
49
51
  id = get_id(doc)
50
52
  @operations << {
51
- path: @base_path + "/" + CGI::escape(id),
53
+ path: "#{@base_path}/#{CGI.escape(id)}",
52
54
  method: "GET",
53
- callback: block_given? && block
55
+ callback: block
54
56
  }
55
57
  end
56
58
 
@@ -58,10 +60,10 @@ module Ecoportal
58
60
  id = get_id(doc)
59
61
  body = get_body(doc)
60
62
  @operations << {
61
- path: @base_path + "/" + CGI::escape(id),
63
+ path: "#{@base_path}/#{CGI.escape(id)}",
62
64
  method: "PATCH",
63
65
  body: body,
64
- callback: block_given? && block
66
+ callback: block
65
67
  }
66
68
  end
67
69
 
@@ -69,19 +71,19 @@ module Ecoportal
69
71
  id = get_id(doc)
70
72
  body = get_body(doc)
71
73
  @operations << {
72
- path: @base_path + "/" + CGI::escape(id),
74
+ path: "#{@base_path}/#{CGI.escape(id)}",
73
75
  method: "POST",
74
76
  body: body,
75
- callback: block_given? && block
77
+ callback: block
76
78
  }
77
79
  end
78
80
 
79
81
  def delete(doc, &block)
80
82
  id = get_id(doc)
81
83
  @operations << {
82
- path: @base_path + "/" + CGI::escape(id),
84
+ path: "#{@base_path}/#{CGI.escape(id)}",
83
85
  method: "DELETE",
84
- callback: block_given? && block
86
+ callback: block
85
87
  }
86
88
  end
87
89
 
@@ -91,7 +93,7 @@ module Ecoportal
91
93
  path: @base_path,
92
94
  method: "POST",
93
95
  body: body,
94
- callback: block_given? && block
96
+ callback: block
95
97
  }
96
98
  end
97
99
 
@@ -104,14 +106,15 @@ module Ecoportal
104
106
  end
105
107
 
106
108
  def log_batch_response(operation, response)
107
- level = response.success?? :debug : :warn
108
109
  log(:info) { "BATCH #{operation[:method]} #{operation[:path]}" }
109
110
  log(:info) { "Status #{response.status}" }
111
+
112
+ level = response.success?? :debug : :warn
110
113
  log(level) { "Response: #{JSON.pretty_generate(response.body)}" }
111
114
  end
112
115
 
113
116
  def log(level, &block)
114
- @logger.send(level, &block) if @logger
117
+ @logger&.send(level, &block)
115
118
  end
116
119
  end
117
120
  end
@@ -2,7 +2,6 @@ module Ecoportal
2
2
  module API
3
3
  module Common
4
4
  class BatchResponse
5
-
6
5
  attr_reader :status, :body, :result
7
6
 
8
7
  def initialize(status, body, result = nil)
@@ -15,10 +14,8 @@ module Ecoportal
15
14
  status.success?
16
15
  end
17
16
 
18
- def each
19
- [*@result].each do |doc|
20
- yield doc
21
- end
17
+ def each(&block)
18
+ [*@result].each(&block)
22
19
  end
23
20
 
24
21
  def print_pretty
@@ -3,16 +3,22 @@ module Ecoportal
3
3
  module API
4
4
  module Common
5
5
  # @note
6
- # - You can see the documentation of the `HTTP` module in [the repository](https://github.com/httprb/http)
7
- # - it does `extend` the module `Chainable` ([chainable.rb](https://github.com/httprb/http/blob/master/lib/http/chainable.rb)),
8
- # - where all the http requests are dev by using `HTTP::Client#request` ([client.rb](https://github.com/httprb/http/blob/master/lib/http/client.rb))
9
- # - which calls `build_request` (new `HTTP::Request`) and `perform` (new `HTTP::Connection`)
10
- # - to return `HTTP::Response` ([response.rb](https://github.com/httprb/http/blob/master/lib/http/response.rb))
6
+ # - You can see the documentation of the `HTTP` module in
7
+ # [the repository](https://github.com/httprb/http)
8
+ # - it does `extend` the module `Chainable`
9
+ # ([chainable.rb](https://github.com/httprb/http/blob/master/lib/http/chainable.rb)),
10
+ # - where all the http requests are dev by using `HTTP::Client#request`
11
+ # ([client.rb](https://github.com/httprb/http/blob/master/lib/http/client.rb))
12
+ # - which calls `build_request` (new `HTTP::Request`) and `perform`
13
+ # (new `HTTP::Connection`)
14
+ # - to return `HTTP::Response`
15
+ # ([response.rb](https://github.com/httprb/http/blob/master/lib/http/response.rb))
11
16
  # @attr_reader logger [Logger] the logger.
12
17
  # @attr_reader host [String] the remote target server.
13
18
  class Client
14
19
  include Common::ElasticApmIntegration
15
20
  DELAY_REQUEST_RETRY = 5
21
+ RETRY_ATTEMPTS = 5
16
22
 
17
23
  attr_accessor :logger
18
24
  attr_reader :host
@@ -30,15 +36,17 @@ module Ecoportal
30
36
  @logger = logger
31
37
  @host = host
32
38
  @response_logging_enabled = response_logging
39
+
33
40
  if host.match(/^localhost|^127\.0\.0\.1/)
34
41
  @base_uri = "http://#{host}/api/"
35
42
  else
36
43
  @base_uri = "https://#{host}/api/"
37
44
  end
38
45
  log(:info) { "#{version} client initialized pointing at #{host}" }
39
- if @api_key.nil? || @api_key.match(/\A\W*\z/)
40
- log(:error) { "Api-key missing!" }
41
- end
46
+
47
+ return unless @api_key.nil? || @api_key.match(/\A\W*\z/)
48
+
49
+ log(:error) { "Api-key missing!" }
42
50
  end
43
51
 
44
52
  # Logger interface.
@@ -51,7 +59,7 @@ module Ecoportal
51
59
  # @yield [] generates the message.
52
60
  # @yieldreturn [String] the generated message.
53
61
  def log(level, &block)
54
- logger.send(level, &block) if logger
62
+ logger&.send(level, &block)
55
63
  end
56
64
 
57
65
  # Sends an http `GET` request against the api version using `path` to complete the base url,
@@ -126,18 +134,18 @@ module Ecoportal
126
134
  Ecoportal::API::Common::Response.new(response)
127
135
  end
128
136
 
129
- # Creates a HTTP object adding the `X-ApiKey` or `X-ECOPORTAL-API-KEY` param to the header, depending on the API version.
137
+ # Creates a HTTP object adding the `X-ApiKey` or `X-ECOPORTAL-API-KEY` param
138
+ # to the header, depending on the API version.
130
139
  # @note It configures HTTP so it only allows body data in json format.
131
140
  # @return [HTTP] HTTP object.
132
141
  def base_request
133
- @base_request ||= begin
142
+ @base_request ||=
134
143
  case @version
135
144
  when "v2"
136
145
  HTTP.headers("X-ECOPORTAL-API-KEY" => @api_key).accept(:json)
137
146
  else
138
147
  HTTP.headers("X-ApiKey" => @api_key).accept(:json)
139
148
  end
140
- end
141
149
  end
142
150
 
143
151
  # Full URl builder of the request
@@ -150,48 +158,75 @@ module Ecoportal
150
158
  private
151
159
 
152
160
  def instrument(method, path, data = nil, &block)
153
- raise "Expected block" unless block
161
+ raise "Expected block" unless block_given?
162
+
154
163
  start_time = Time.now.to_f
155
164
  log(:info) { "#{method} #{url_for(path)}" }
156
165
  log(:debug) { "Data: #{JSON.pretty_generate(data)}" }
157
166
 
158
167
  with_retry(&block).tap do |result|
159
168
  end_time = Time.now.to_f
160
- log(result.success?? :info : :warn) do
161
- "Took %.2fs, Status #{result.status}" % (end_time - start_time)
162
- end
163
- log(result.success?? :debug : :warn) do
169
+ log(result.success?? :info : :warn) {
170
+ "Took %.2fs, Status #{result.status}" % (end_time - start_time) # rubocop:disable Style/FormatString
171
+ }
172
+
173
+ next unless @response_logging_enabled
174
+
175
+ log(result.success?? :debug : :warn) {
164
176
  "Response: #{JSON.pretty_generate(result.body)}"
165
- end if @response_logging_enabled
177
+ }
166
178
  end
167
179
  end
168
180
 
169
181
  # Helper to ensure unexpected server errors do not bring client scripts immediately down
170
- def with_retry(attempts = 3, delay = DELAY_REQUEST_RETRY, error_safe: true, &block)
182
+ def with_retry(attempts = RETRY_ATTEMPTS, delay = DELAY_REQUEST_RETRY, error_safe: true, &block)
171
183
  response = nil
172
184
  attempts.times do |i|
173
185
  remaining = attempts - i - 1
186
+
174
187
  begin
175
188
  response = block.call
176
189
  rescue HTTP::ConnectionError => e
177
- raise unless error_safe && remaining > 0
190
+ raise unless error_safe && remaining.positive?
178
191
  log(:error) { "Got connection error: #{e.message}" }
179
192
  response = with_retry(remaining, error_safe: error_safe, &block)
180
193
  rescue IOError => e
181
- raise unless error_safe && remaining > 0
194
+ raise unless error_safe && remaining.positive?
182
195
  log(:error) { "Got IO error: #{e.message}" }
183
196
  response = with_retry(remaining, error_safe: error_safe, &block)
184
197
  end
185
- return response unless unexpected_server_error?(response.status)
198
+
199
+ return response unless some_unexpected_error?(response)
200
+
201
+ puts "re-attempting (remaining: #{remaining} attempts out of #{attempts})"
202
+
186
203
  log_unexpected_server_error(response)
204
+
187
205
  msg = "Got server error (#{response.status}): #{response.body}\n"
188
206
  msg += "Going to retry (#{i} out of #{attempts})"
189
207
  log(:error) { msg }
208
+
190
209
  sleep(delay) if i < attempts
191
210
  end
192
211
  response
193
212
  end
194
213
 
214
+ # Sometimes response body is wrong but status code
215
+ # doesn't reflect. Let it retry
216
+ def some_unexpected_error?(response)
217
+ unexpected_server_error?(response.status) ||
218
+ unexpected_body?(response)
219
+ end
220
+
221
+ def unexpected_body?(response)
222
+ response.body.nil?.tap do |wrong|
223
+ next unless wrong
224
+
225
+ msg = "Received non json body in response "
226
+ msg << "(#{response.src_body.class}):\n #{response.src_body}"
227
+ puts
228
+ end
229
+ end
195
230
  end
196
231
  end
197
232
  end
@@ -2,18 +2,18 @@ module Ecoportal
2
2
  module API
3
3
  module Common
4
4
  class Response
5
-
6
5
  attr_reader :status, :body
6
+ attr_reader :src_body
7
7
 
8
8
  def initialize(response)
9
- @status = response.status
10
- @body = [].tap do |body_data|
9
+ @status = response.status
10
+ @src_body = [].tap do |body_data|
11
11
  response.body.each do |chunk|
12
12
  body_data << chunk
13
13
  end
14
- end.join("")
15
- @body = JSON.parse(@body.to_s) rescue nil
16
- response
14
+ end.join.to_s
15
+
16
+ @body = JSON.parse(@src_body) rescue nil # rubocop:disable Style/RescueModifier
17
17
  end
18
18
 
19
19
  def success?
@@ -10,26 +10,24 @@ module Ecoportal
10
10
  @response = response
11
11
  @klass = klass
12
12
 
13
- if @response.success?
14
- @result =
15
- if @response.body.is_a?(Array)
16
- @response.body.map do |doc|
17
- @klass.new(doc)
18
- end
19
- else
20
- @klass.new(@response.body)
13
+ return unless @response.success?
14
+
15
+ @result =
16
+ if @response.body.is_a?(Array)
17
+ @response.body.map do |doc|
18
+ @klass.new(doc)
21
19
  end
22
- end
20
+ else
21
+ @klass.new(@response.body)
22
+ end
23
23
  end
24
24
 
25
25
  def body
26
26
  response.body.to_s
27
27
  end
28
28
 
29
- def each
30
- [*result].each do |doc|
31
- yield doc
32
- end
29
+ def each(&block)
30
+ [*result].each(&block)
33
31
  end
34
32
 
35
33
  def status
@@ -41,13 +39,10 @@ module Ecoportal
41
39
  end
42
40
 
43
41
  def print_pretty
44
- if success?
45
- each(&:print_pretty)
46
- else
47
- puts "Request failed."
48
- end
49
- end
42
+ return each(&:print_pretty) if success?
50
43
 
44
+ "Request failed."
45
+ end
51
46
  end
52
47
  end
53
48
  end
@@ -2,13 +2,14 @@ module Ecoportal
2
2
  module API
3
3
  class Internal
4
4
  class Account < Common::BaseModel
5
- PROPERTIES = [
6
- "user_id", "policy_group_ids", "default_tag", "prefilter",
7
- "permissions_custom", "permissions_merged", "preferences",
8
- "login_provider_ids", "starred_ids", "landing_page_id",
9
- "accept_eula", "send_invites", "force_send_invites"
10
- ]
11
- passthrough *PROPERTIES.map(&:to_sym)
5
+ PROPERTIES = %w[
6
+ user_id policy_group_ids default_tag prefilter
7
+ permissions_custom permissions_merged preferences
8
+ login_provider_ids starred_ids landing_page_id
9
+ accept_eula send_invites force_send_invites
10
+ ].freeze
11
+
12
+ passthrough(*PROPERTIES.map(&:to_sym))
12
13
 
13
14
  class_resolver :preferences_class, "Ecoportal::API::Internal::Preferences"
14
15
  class_resolver :permissions_class, "Ecoportal::API::Internal::Permissions"
@@ -23,11 +24,11 @@ module Ecoportal
23
24
  # @return [String, nil] the value set in `default_tag`
24
25
  def default_tag=(value)
25
26
  unless !value || value.is_a?(String)
26
- raise ArgumentError.new("default_tag= needs to be passed a String or nil, got #{value.class}")
27
+ raise ArgumentError, "default_tag= needs to be passed a String or nil, got #{value.class}"
27
28
  end
28
29
  if value
29
30
  unless value.match(Ecoportal::API::V1::Person::VALID_TAG_REGEX)
30
- raise ArgumentError.new("Invalid default tag #{value.inspect}")
31
+ raise ArgumentError, "Invalid default tag #{value.inspect}"
31
32
  end
32
33
  value = value.upcase
33
34
  end
@@ -89,7 +90,7 @@ module Ecoportal
89
90
  end
90
91
 
91
92
  def as_update(ref = :last, ignore: [])
92
- super(ref, ignore: ignore | ["user_id", "permissions_merged", "prefilter"])
93
+ super(ref, ignore: ignore | %w[user_id permissions_merged prefilter])
93
94
  end
94
95
  end
95
96
  end
@@ -3,12 +3,12 @@ module Ecoportal
3
3
  class Internal < V1
4
4
  include Common::Logging
5
5
 
6
- VERSION = "v0"
7
- class_resolver :people_class, "Ecoportal::API::Internal::People"
8
- class_resolver :person_schemas_class, "Ecoportal::API::Internal::PersonSchemas"
6
+ VERSION = "v0".freeze
7
+ class_resolver :people_class, "Ecoportal::API::Internal::People"
8
+ class_resolver :person_schemas_class, "Ecoportal::API::Internal::PersonSchemas"
9
9
 
10
- class_resolver :policy_groups_class, "Ecoportal::API::Internal::PolicyGroups"
11
- class_resolver :login_providers_class, "Ecoportal::API::Internal::LoginProviders"
10
+ class_resolver :policy_groups_class, "Ecoportal::API::Internal::PolicyGroups"
11
+ class_resolver :login_providers_class, "Ecoportal::API::Internal::LoginProviders"
12
12
 
13
13
  # Obtain specific object for policy groups api requests.
14
14
  # @return [PolicyGroups] an instance object ready to make policy groups api requests.
@@ -1,24 +1,26 @@
1
1
  module Ecoportal
2
2
  module API
3
3
  class Logger
4
- TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S"
5
- STDOUT_FORMAT_PROC = proc do |severity, datetime, progname, msg|
6
- prefix = "%5s > " % severity
4
+ TIMESTAMP_PATTERN = "%Y-%m-%dT%H:%M:%S".freeze
5
+
6
+ STDOUT_FORMAT_PROC = proc do |severity, _datetime, _progname, msg|
7
+ prefix = "%5s > " % severity # rubocop:disable Style/FormatString
7
8
  msg.lines.map.with_index do |line, idx|
8
9
  if idx.zero?
9
10
  prefix + line.chomp
10
11
  else
11
- " "*prefix.length + line.chomp
12
+ (" " * prefix.length) + line.chomp
12
13
  end
13
14
  end.join("\n")+"\n"
14
15
  end
15
- FILE_FORMAT_PROC = proc do |severity, datetime, progname, msg|
16
- prefix = "%5s(%s) > " % [severity, datetime.strftime(TIMESTAMP_PATTERN)]
16
+
17
+ FILE_FORMAT_PROC = proc do |severity, datetime, _progname, msg|
18
+ prefix = "%5s(%s) > " % [severity, datetime.strftime(TIMESTAMP_PATTERN)] # rubocop:disable Style/FormatString, Style/FormatStringToken
17
19
  msg.lines.map.with_index do |line, idx|
18
20
  if idx.zero?
19
21
  prefix + line.chomp
20
22
  else
21
- " "*prefix.length + line.chomp
23
+ (" " * prefix.length) + line.chomp
22
24
  end
23
25
  end.join("\n")+"\n"
24
26
  end
@@ -34,7 +36,7 @@ module Ecoportal
34
36
  @file = make_file_logger(file_level, output_file)
35
37
  end
36
38
 
37
- %w(unknown fatal error warn info debug).each do |type|
39
+ %w[unknown fatal error warn info debug].each do |type|
38
40
  define_method(type) do |&block|
39
41
  @console.send(type, &block)
40
42
  @file&.send(type, &block)
@@ -44,7 +46,7 @@ module Ecoportal
44
46
  private
45
47
 
46
48
  def make_stdout_logger(level)
47
- ::Logger.new(STDOUT).tap do |logger|
49
+ ::Logger.new($stdout).tap do |logger|
48
50
  logger.formatter = STDOUT_FORMAT_PROC
49
51
  logger.level = level
50
52
  end