worker_tools 0.1.1 → 0.2.2
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 +5 -5
- data/.travis.yml +2 -1
- data/README.md +49 -3
- data/lib/worker_tools/basics.rb +5 -1
- data/lib/worker_tools/benchmark.rb +15 -0
- data/lib/worker_tools/counters.rb +41 -0
- data/lib/worker_tools/csv_input.rb +7 -1
- data/lib/worker_tools/recorder.rb +3 -0
- data/lib/worker_tools/slack_error_notifier.rb +105 -0
- data/lib/worker_tools/version.rb +1 -1
- data/lib/worker_tools/xlsx_input.rb +5 -0
- data/lib/worker_tools/xlsx_output.rb +127 -0
- data/worker_tools.gemspec +5 -3
- metadata +31 -15
- data/lib/worker_tools/rocketchat_error_notifier.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a53ae86156768dd1b1f80601a50f8c6926918d3f625be933173f7d4513c0f2d8
|
4
|
+
data.tar.gz: 48dfc8c5430311e2b6dae3d5bfbb55d6d2ce0444d3c5e5dd5a9cf044e42afdf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95ac0fe0d5255b995a5c7a0193edf6a56eb5d376234e1f6088f6c97ad03ea6e760d499c62c2c711f5ad2b453f5c9f7b5309f9bea2acfb50b9c60621b83ed3800
|
7
|
+
data.tar.gz: e2a09d6b64d813a0296f81d5ef995ed49178957bfdbf67349e5b2d811ec84e98b08850e9565f875f02a6b105f9ae9769cfd177d660b2a4d98bf0b2ae03ecf77c
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -59,6 +59,7 @@ In this case the migration would be something like this:
|
|
59
59
|
t.integer :state, default: 0, null: false
|
60
60
|
t.text :information
|
61
61
|
t.json :options, default: {}
|
62
|
+
t.json :meta, default: {}
|
62
63
|
|
63
64
|
t.string :attachment_file_name
|
64
65
|
t.integer :attachment_file_size
|
@@ -124,9 +125,9 @@ If you only want the logger functions, without worrying about persisting a model
|
|
124
125
|
end
|
125
126
|
```
|
126
127
|
|
127
|
-
## Module
|
128
|
+
## Module SlackErrorNotifier
|
128
129
|
|
129
|
-
[
|
130
|
+
[slack_error_notifier](/lib/worker_tools/slack_error_notifier.rb)
|
130
131
|
|
131
132
|
## Module CSV Input
|
132
133
|
|
@@ -199,6 +200,52 @@ def perform(model_id)
|
|
199
200
|
end
|
200
201
|
```
|
201
202
|
|
203
|
+
## Counters
|
204
|
+
|
205
|
+
There is a counter wrapper that you can use to add custom counters to the meta attribute. To do this, you need to complete the following tasks:
|
206
|
+
- include WorkerTools::Counters to your class
|
207
|
+
- add :counters to the wrappers method props
|
208
|
+
- call counters method with your custom counters
|
209
|
+
You can see an example below. After that, you can access your custom counters via the meta attribute.
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
class MyImporter
|
213
|
+
include WorkerTools::Counters
|
214
|
+
wrappers :counters
|
215
|
+
counters :foo, :bar
|
216
|
+
|
217
|
+
def run
|
218
|
+
example_foo_counter_methods
|
219
|
+
end
|
220
|
+
|
221
|
+
def example_foo_counter_methods
|
222
|
+
self.foo = 0
|
223
|
+
|
224
|
+
10.times { increment_foo }
|
225
|
+
|
226
|
+
puts foo # foo == 10
|
227
|
+
end
|
228
|
+
|
229
|
+
# ..
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
## Benchmark
|
234
|
+
|
235
|
+
There is a benchmark wrapper that you can use to record the benchmark. The only thing you need to do is to include the benchmark module and append the name to the wrapper array. Below you can see an example of the integration.
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
class MyImporter
|
239
|
+
include WorkerTools::CustomBenchmark
|
240
|
+
wrappers :benchmark
|
241
|
+
|
242
|
+
def run
|
243
|
+
# do stuff
|
244
|
+
end
|
245
|
+
|
246
|
+
# ..
|
247
|
+
end
|
248
|
+
```
|
202
249
|
|
203
250
|
## Contributing
|
204
251
|
|
@@ -208,4 +255,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/i22-di
|
|
208
255
|
## License
|
209
256
|
|
210
257
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
211
|
-
|
data/lib/worker_tools/basics.rb
CHANGED
@@ -33,6 +33,7 @@ module WorkerTools
|
|
33
33
|
|
34
34
|
def perform(model_id = nil)
|
35
35
|
@model_id = model_id
|
36
|
+
|
36
37
|
with_wrappers(wrapper_methods) do
|
37
38
|
run
|
38
39
|
end
|
@@ -42,6 +43,7 @@ module WorkerTools
|
|
42
43
|
self.class.read_wrappers.map do |wrapper|
|
43
44
|
symbolized_method = "with_wrapper_#{wrapper}".to_sym
|
44
45
|
raise "Missing wrapper #{wrapper}" unless respond_to?(symbolized_method)
|
46
|
+
|
45
47
|
symbolized_method
|
46
48
|
end
|
47
49
|
end
|
@@ -60,7 +62,7 @@ module WorkerTools
|
|
60
62
|
end
|
61
63
|
|
62
64
|
def finalize
|
63
|
-
model.
|
65
|
+
model.update!(
|
64
66
|
state: 'complete',
|
65
67
|
information: information
|
66
68
|
)
|
@@ -76,6 +78,7 @@ module WorkerTools
|
|
76
78
|
|
77
79
|
def with_wrappers(wrapper_symbols, &block)
|
78
80
|
return yield if wrapper_symbols.blank?
|
81
|
+
|
79
82
|
current_wrapper_symbol = wrapper_symbols.shift
|
80
83
|
send(current_wrapper_symbol) { with_wrappers(wrapper_symbols, &block) }
|
81
84
|
end
|
@@ -87,6 +90,7 @@ module WorkerTools
|
|
87
90
|
return @model_id if @model_id.is_a?(model_class)
|
88
91
|
return model_class.find(@model_id) if @model_id
|
89
92
|
raise 'Model not available' unless create_model_if_not_available
|
93
|
+
|
90
94
|
t = model_class.new
|
91
95
|
t.kind = model_kind if t.respond_to?(:kind=)
|
92
96
|
t.save!(validate: false)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WorkerTools
|
2
|
+
module CustomBenchmark
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
attr_accessor :benchmark
|
7
|
+
|
8
|
+
def with_wrapper_benchmark(&block)
|
9
|
+
@benchmark = Benchmark.measure(&block)
|
10
|
+
|
11
|
+
model.meta['duration'] = @benchmark.real.round if model.respond_to?(:meta)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module WorkerTools
|
2
|
+
module Counters
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
def self.counters(*args)
|
7
|
+
@counters ||= args.flatten
|
8
|
+
add_counter_methods
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.read_counters
|
12
|
+
@counters || []
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.add_counter_methods
|
16
|
+
@counters.each do |name|
|
17
|
+
define_method name do
|
18
|
+
model.meta[name]
|
19
|
+
end
|
20
|
+
define_method "#{name}=" do |value|
|
21
|
+
model.meta[name] = value
|
22
|
+
end
|
23
|
+
define_method "increment_#{name}" do
|
24
|
+
model.meta[name] += 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_wrapper_counters(&block)
|
30
|
+
reset_counters
|
31
|
+
block.call
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset_counters
|
35
|
+
self.class.read_counters.each do |name|
|
36
|
+
model.meta[name] = 0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -54,6 +54,7 @@ module WorkerTools
|
|
54
54
|
def csv_input_columns_check(csv_rows_enum)
|
55
55
|
# override and return true if you do not want this check to be performed
|
56
56
|
return csv_input_columns_array_check(csv_rows_enum) if csv_input_columns.is_a?(Array)
|
57
|
+
|
57
58
|
csv_input_columns_hash_check(csv_rows_enum)
|
58
59
|
end
|
59
60
|
|
@@ -61,6 +62,7 @@ module WorkerTools
|
|
61
62
|
expected_columns_length = csv_input_columns.length
|
62
63
|
actual_columns_length = csv_rows_enum.first.length
|
63
64
|
return if expected_columns_length == actual_columns_length
|
65
|
+
|
64
66
|
raise "The number of columns (#{actual_columns_length}) is not the expected (#{expected_columns_length})"
|
65
67
|
end
|
66
68
|
|
@@ -105,6 +107,7 @@ module WorkerTools
|
|
105
107
|
# => { tenant: 1, area: 0}
|
106
108
|
def csv_input_mapping_order(header_names)
|
107
109
|
return csv_input_columns.map.with_index { |n, i| [n, i] }.to_h if csv_input_columns.is_a?(Array)
|
110
|
+
|
108
111
|
csv_input_mapping_order_for_hash(header_names)
|
109
112
|
end
|
110
113
|
|
@@ -115,6 +118,7 @@ module WorkerTools
|
|
115
118
|
h[k] = filtered_column_names.index { |n| case n when matchable then true end }
|
116
119
|
end
|
117
120
|
return mapping unless csv_input_include_other_columns
|
121
|
+
|
118
122
|
csv_input_mapping_order_with_other_columns(mapping, filtered_column_names)
|
119
123
|
end
|
120
124
|
|
@@ -131,7 +135,7 @@ module WorkerTools
|
|
131
135
|
end
|
132
136
|
|
133
137
|
def csv_rows_enum
|
134
|
-
@csv_rows_enum ||= CSV.foreach(csv_input_file_path, csv_input_csv_options)
|
138
|
+
@csv_rows_enum ||= CSV.foreach(csv_input_file_path, **csv_input_csv_options)
|
135
139
|
end
|
136
140
|
|
137
141
|
def csv_input_headers_present
|
@@ -168,12 +172,14 @@ module WorkerTools
|
|
168
172
|
|
169
173
|
@rows_enum.with_index.each do |values, index|
|
170
174
|
next if index.zero? && @headers_present
|
175
|
+
|
171
176
|
yield values_to_row(values)
|
172
177
|
end
|
173
178
|
end
|
174
179
|
|
175
180
|
def values_to_row(values)
|
176
181
|
return values_to_row_according_to_mapping(values) if @mapping_order
|
182
|
+
|
177
183
|
values_to_row_according_to_position(values)
|
178
184
|
end
|
179
185
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module WorkerTools
|
2
2
|
module Recorder
|
3
|
+
|
3
4
|
def with_wrapper_recorder(&block)
|
4
5
|
block.yield
|
5
6
|
# this time we do want to catch Exception to attempt to handle some of the
|
@@ -45,11 +46,13 @@ module WorkerTools
|
|
45
46
|
|
46
47
|
def format_log_message(message)
|
47
48
|
return error_to_text(message, log_error_trace_lines) if message.is_a?(Exception)
|
49
|
+
|
48
50
|
message
|
49
51
|
end
|
50
52
|
|
51
53
|
def format_info_message(message)
|
52
54
|
return error_to_text(message, info_error_trace_lines) if message.is_a?(Exception)
|
55
|
+
|
53
56
|
message
|
54
57
|
end
|
55
58
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'slack-notifier'
|
2
|
+
|
3
|
+
module WorkerTools
|
4
|
+
module SlackErrorNotifier
|
5
|
+
def with_wrapper_slack_error_notifier(&block)
|
6
|
+
block.yield
|
7
|
+
rescue StandardError => e
|
8
|
+
slack_error_notify(e) if slack_error_notifier_enabled
|
9
|
+
raise
|
10
|
+
end
|
11
|
+
|
12
|
+
def slack_error_notifier_enabled
|
13
|
+
Rails.env.production?
|
14
|
+
end
|
15
|
+
|
16
|
+
def slack_error_notifier_emoji
|
17
|
+
':red_circle:'
|
18
|
+
end
|
19
|
+
|
20
|
+
def slack_error_notifier_channel
|
21
|
+
return SLACK_NOTIFIER_CHANNEL if defined?(SLACK_NOTIFIER_CHANNEL)
|
22
|
+
|
23
|
+
raise 'Define slack_error_notifier_channel or set SLACK_NOTIFIER_CHANNEL in an initializer'
|
24
|
+
end
|
25
|
+
|
26
|
+
def slack_error_notifier_webhook
|
27
|
+
return SLACK_NOTIFIER_WEBHOOK if defined?(SLACK_NOTIFIER_WEBHOOK)
|
28
|
+
|
29
|
+
raise 'Define slack_error_notifier_webhook or set SLACK_NOTIFIER_WEBHOOK in an initializer'
|
30
|
+
end
|
31
|
+
|
32
|
+
def slack_error_notifier_username
|
33
|
+
'Notifier'
|
34
|
+
end
|
35
|
+
|
36
|
+
def slack_error_notifier_receivers
|
37
|
+
# Ex: '@all'
|
38
|
+
end
|
39
|
+
|
40
|
+
def slack_error_notifier_attachments_color
|
41
|
+
# good, warning, danger, hex color
|
42
|
+
'danger'
|
43
|
+
end
|
44
|
+
|
45
|
+
def slack_error_notifier_title
|
46
|
+
# Example with a link:
|
47
|
+
#
|
48
|
+
# For urls a default_url_options[:host] might be necessary.
|
49
|
+
# In this example I just copy it from existing action_mailer defaults.
|
50
|
+
#
|
51
|
+
# import = slack_error_notifier_model
|
52
|
+
# host = Rails.application.config.action_mailer.default_url_options[:host]
|
53
|
+
# url = Rails.application.routes.url_helpers.import_url(import, host: host, protocol: :https)
|
54
|
+
# kind = I18n.t(import.kind, scope: 'import.kinds')
|
55
|
+
# text = "##{import.id} *#{kind}*"
|
56
|
+
# "[#{text}](#{url})"
|
57
|
+
klass = model.class.model_name.human
|
58
|
+
kind = I18n.t("activerecord.attributes.#{model.class.name.underscore}.kinds.#{model.kind}")
|
59
|
+
"#{klass} #{kind} ##{model.id}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def slack_error_notifier_error_details(error)
|
63
|
+
error.backtrace[0..2].join("\n")
|
64
|
+
end
|
65
|
+
|
66
|
+
def slack_error_notifier_message
|
67
|
+
message = []
|
68
|
+
message << slack_error_notifier_receivers
|
69
|
+
message << slack_error_notifier_title
|
70
|
+
message.compact.join(' - ')
|
71
|
+
end
|
72
|
+
|
73
|
+
def slack_error_notifier_attachments(error)
|
74
|
+
[
|
75
|
+
{ color: slack_error_notifier_attachments_color, fields: slack_error_notifier_attachments_fields },
|
76
|
+
{
|
77
|
+
title: [error.class, error.message].join(' : '),
|
78
|
+
color: slack_error_notifier_attachments_color,
|
79
|
+
text: slack_error_notifier_error_details(error)
|
80
|
+
}
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def slack_error_notifier_attachments_fields
|
85
|
+
[
|
86
|
+
{ title: 'Application', value: Rails.application.class.module_parent_name, short: true },
|
87
|
+
{ title: 'Environment', value: Rails.env, short: true }
|
88
|
+
]
|
89
|
+
end
|
90
|
+
|
91
|
+
def slack_error_notifier
|
92
|
+
Slack::Notifier.new(slack_error_notifier_webhook)
|
93
|
+
end
|
94
|
+
|
95
|
+
def slack_error_notify(error)
|
96
|
+
slack_error_notifier.post(
|
97
|
+
username: slack_error_notifier_username,
|
98
|
+
channel: slack_error_notifier_channel,
|
99
|
+
icon_emoji: slack_error_notifier_emoji,
|
100
|
+
text: "*#{slack_error_notifier_message}*",
|
101
|
+
attachments: slack_error_notifier_attachments(error)
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/worker_tools/version.rb
CHANGED
@@ -59,6 +59,7 @@ module WorkerTools
|
|
59
59
|
def xlsx_input_columns_check(xlsx_rows_enum)
|
60
60
|
# override and return true if you do not want this check to be performed
|
61
61
|
return xlsx_input_columns_array_check(xlsx_rows_enum) if xlsx_input_columns.is_a?(Array)
|
62
|
+
|
62
63
|
xlsx_input_columns_hash_check(xlsx_rows_enum)
|
63
64
|
end
|
64
65
|
|
@@ -66,6 +67,7 @@ module WorkerTools
|
|
66
67
|
expected_columns_length = xlsx_input_columns.length
|
67
68
|
actual_columns_length = xlsx_rows_enum.first.length
|
68
69
|
return if expected_columns_length == actual_columns_length
|
70
|
+
|
69
71
|
raise "The number of columns (#{actual_columns_length}) is not the expected (#{expected_columns_length})"
|
70
72
|
end
|
71
73
|
|
@@ -97,6 +99,7 @@ module WorkerTools
|
|
97
99
|
# => { tenant: 1, area: 0}
|
98
100
|
def xlsx_input_mapping_order(header_names)
|
99
101
|
return xlsx_input_columns.map.with_index { |n, i| [n, i] }.to_h if xlsx_input_columns.is_a?(Array)
|
102
|
+
|
100
103
|
xlsx_input_mapping_order_for_hash(header_names)
|
101
104
|
end
|
102
105
|
|
@@ -107,6 +110,7 @@ module WorkerTools
|
|
107
110
|
h[k] = filtered_column_names.index { |n| case n when matchable then true end }
|
108
111
|
end
|
109
112
|
return mapping unless xlsx_input_include_other_columns
|
113
|
+
|
110
114
|
xlsx_input_mapping_order_with_other_columns(mapping, filtered_column_names)
|
111
115
|
end
|
112
116
|
|
@@ -155,6 +159,7 @@ module WorkerTools
|
|
155
159
|
|
156
160
|
@rows_enum.with_index.each do |values, index|
|
157
161
|
next if index.zero? # headers
|
162
|
+
|
158
163
|
yield values_to_row(values)
|
159
164
|
end
|
160
165
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'rubyXL'
|
2
|
+
module WorkerTools
|
3
|
+
module XlsxOutput
|
4
|
+
# if defined, this file will be written to this destination (regardless
|
5
|
+
# of whether the model saves the file as well)
|
6
|
+
def xlsx_output_target
|
7
|
+
# Ex: Rails.root.join('shared', 'foo', 'bar.xlsx')
|
8
|
+
raise "xlsx_output_target has to be defined in #{self}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def xlsx_output_content
|
12
|
+
{
|
13
|
+
sheet1: {
|
14
|
+
label: 'Sheet 1',
|
15
|
+
headers: xlsx_output_column_headers,
|
16
|
+
rows: xlsx_output_values,
|
17
|
+
column_style: xlsx_output_column_format
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def xlsx_output_values
|
23
|
+
raise "xlsx_output_values has to be defined in #{self}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def xlsx_output_column_headers
|
27
|
+
# These columns are used to set the headers, also
|
28
|
+
# to set the row values depending on your implementation.
|
29
|
+
#
|
30
|
+
# To ignore them set it to _false_
|
31
|
+
#
|
32
|
+
# Ex:
|
33
|
+
# @xlsx_output_column_headers ||= {
|
34
|
+
# foo: 'Foo Header',
|
35
|
+
# bar: 'Bar Header'
|
36
|
+
# }
|
37
|
+
raise "xlsx_output_column_headers has to be defined in #{self}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def xlsx_output_column_format
|
41
|
+
# These columns are used to set the headers, also
|
42
|
+
# to set the row values depending on your implementation.
|
43
|
+
#
|
44
|
+
# To ignore them set it to _false_
|
45
|
+
#
|
46
|
+
# Ex:
|
47
|
+
# @xlsx_output_column_format ||= {
|
48
|
+
# foo: { width: 10, text_wrap: true },
|
49
|
+
# bar: { width: 20, text_wrap: false }
|
50
|
+
# }
|
51
|
+
{}
|
52
|
+
end
|
53
|
+
|
54
|
+
def xlsx_output_target_folder
|
55
|
+
@xlsx_output_target_folder ||= File.dirname(xlsx_output_target)
|
56
|
+
end
|
57
|
+
|
58
|
+
def xlsx_ensure_output_target_folder
|
59
|
+
FileUtils.mkdir_p(xlsx_output_target_folder) unless File.directory?(xlsx_output_target_folder)
|
60
|
+
end
|
61
|
+
|
62
|
+
def xlsx_insert_headers(spreadsheet, headers)
|
63
|
+
return unless headers
|
64
|
+
|
65
|
+
iterator =
|
66
|
+
if headers.is_a? Hash
|
67
|
+
headers.values
|
68
|
+
else
|
69
|
+
headers
|
70
|
+
end
|
71
|
+
iterator.each_with_index do |header, index|
|
72
|
+
spreadsheet.add_cell(0, index, header.to_s)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def xlsx_insert_rows(spreadsheet, rows, headers)
|
77
|
+
rows.each_with_index do |row, row_index|
|
78
|
+
xlsx_iterators(row, headers).each_with_index do |value, col_index|
|
79
|
+
spreadsheet.add_cell(row_index + 1, col_index, value.to_s)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def xlsx_iterators(iterable, compare_hash = nil)
|
85
|
+
if iterable.is_a? Hash
|
86
|
+
raise 'parameter compare_hash should be a hash, too.' if compare_hash.nil? || !compare_hash.is_a?(Hash)
|
87
|
+
|
88
|
+
iterable.values_at(*compare_hash.keys)
|
89
|
+
else
|
90
|
+
iterable
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def xlsx_style_columns(spreadsheet, styles, headers)
|
95
|
+
return false unless headers
|
96
|
+
|
97
|
+
xlsx_iterators(styles, headers).each_with_index do |format, index|
|
98
|
+
next unless format
|
99
|
+
|
100
|
+
spreadsheet.change_column_width(index, format[:width])
|
101
|
+
spreadsheet.change_text_wrap(index, format[:text_wrap])
|
102
|
+
end
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
def xlsx_write_sheet(workbook, sheet_content, index)
|
107
|
+
sheet = workbook.worksheets[index]
|
108
|
+
sheet = workbook.add_worksheet(sheet_content[:label]) if sheet.nil?
|
109
|
+
|
110
|
+
sheet.sheet_name = sheet_content[:label]
|
111
|
+
xlsx_style_columns(sheet, sheet_content[:column_style], sheet_content[:headers])
|
112
|
+
xlsx_insert_headers(sheet, sheet_content[:headers])
|
113
|
+
xlsx_insert_rows(sheet, sheet_content[:rows], sheet_content[:headers])
|
114
|
+
end
|
115
|
+
|
116
|
+
def xlsx_write_output_target
|
117
|
+
xlsx_ensure_output_target_folder
|
118
|
+
|
119
|
+
book = RubyXL::Workbook.new
|
120
|
+
xlsx_output_content.each_with_index do |(_, object), index|
|
121
|
+
xlsx_write_sheet(book, object, index)
|
122
|
+
end
|
123
|
+
|
124
|
+
book.write xlsx_output_target
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/worker_tools.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path('
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require 'worker_tools/version'
|
4
4
|
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the "allowed_push_host"
|
17
17
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
18
|
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless spec.respond_to?(:metadata)
|
19
|
+
|
19
20
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
20
21
|
|
21
22
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
@@ -26,8 +27,9 @@ Gem::Specification.new do |spec|
|
|
26
27
|
spec.require_paths = ['lib']
|
27
28
|
|
28
29
|
spec.add_dependency 'activesupport'
|
29
|
-
spec.add_dependency 'rocketchat-notifier', '>= 0.1.2'
|
30
30
|
spec.add_dependency 'roo'
|
31
|
+
spec.add_dependency 'rubyXL'
|
32
|
+
spec.add_dependency 'slack-notifier'
|
31
33
|
|
32
34
|
spec.add_development_dependency 'activerecord'
|
33
35
|
spec.add_development_dependency 'bundler'
|
@@ -37,7 +39,7 @@ Gem::Specification.new do |spec|
|
|
37
39
|
spec.add_development_dependency 'mocha'
|
38
40
|
spec.add_development_dependency 'pry'
|
39
41
|
spec.add_development_dependency 'rake'
|
40
|
-
spec.add_development_dependency 'rubocop', '0.
|
42
|
+
spec.add_development_dependency 'rubocop', '0.71.0'
|
41
43
|
spec.add_development_dependency 'simplecov'
|
42
44
|
spec.add_development_dependency 'sqlite3'
|
43
45
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: worker_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fsainz
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -25,21 +25,35 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: roo
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0
|
33
|
+
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubyXL
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: slack-notifier
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
@@ -170,14 +184,14 @@ dependencies:
|
|
170
184
|
requirements:
|
171
185
|
- - '='
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: 0.
|
187
|
+
version: 0.71.0
|
174
188
|
type: :development
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
192
|
- - '='
|
179
193
|
- !ruby/object:Gem::Version
|
180
|
-
version: 0.
|
194
|
+
version: 0.71.0
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: simplecov
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,7 +220,7 @@ dependencies:
|
|
206
220
|
- - ">="
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0'
|
209
|
-
description:
|
223
|
+
description:
|
210
224
|
email:
|
211
225
|
- fernando.sainz@i22.de
|
212
226
|
executables: []
|
@@ -224,19 +238,22 @@ files:
|
|
224
238
|
- bin/setup
|
225
239
|
- lib/worker_tools.rb
|
226
240
|
- lib/worker_tools/basics.rb
|
241
|
+
- lib/worker_tools/benchmark.rb
|
242
|
+
- lib/worker_tools/counters.rb
|
227
243
|
- lib/worker_tools/csv_input.rb
|
228
244
|
- lib/worker_tools/csv_output.rb
|
229
245
|
- lib/worker_tools/recorder.rb
|
230
|
-
- lib/worker_tools/
|
246
|
+
- lib/worker_tools/slack_error_notifier.rb
|
231
247
|
- lib/worker_tools/version.rb
|
232
248
|
- lib/worker_tools/xlsx_input.rb
|
249
|
+
- lib/worker_tools/xlsx_output.rb
|
233
250
|
- worker_tools.gemspec
|
234
251
|
homepage: https://github.com/i22-digitalagentur/worker-tools
|
235
252
|
licenses:
|
236
253
|
- MIT
|
237
254
|
metadata:
|
238
255
|
allowed_push_host: https://rubygems.org
|
239
|
-
post_install_message:
|
256
|
+
post_install_message:
|
240
257
|
rdoc_options: []
|
241
258
|
require_paths:
|
242
259
|
- lib
|
@@ -251,9 +268,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
251
268
|
- !ruby/object:Gem::Version
|
252
269
|
version: '0'
|
253
270
|
requirements: []
|
254
|
-
|
255
|
-
|
256
|
-
signing_key:
|
271
|
+
rubygems_version: 3.1.4
|
272
|
+
signing_key:
|
257
273
|
specification_version: 4
|
258
274
|
summary: A collection of modules to help writing common worker tasks)
|
259
275
|
test_files: []
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module WorkerTools
|
2
|
-
module RocketchatErrorNotifier
|
3
|
-
def with_wrapper_rocketchat_error_notifier(&block)
|
4
|
-
block.yield
|
5
|
-
rescue StandardError => e
|
6
|
-
rocketchat_error_notify(e) if rocketchat_error_notifier_enabled
|
7
|
-
raise
|
8
|
-
end
|
9
|
-
|
10
|
-
def rocketchat_error_notifier_enabled
|
11
|
-
Rails.env.production?
|
12
|
-
end
|
13
|
-
|
14
|
-
def rocketchat_error_notifier_emoji
|
15
|
-
':red_circle:'
|
16
|
-
end
|
17
|
-
|
18
|
-
def rocketchat_error_notifier_receivers
|
19
|
-
# Ex: '@all'
|
20
|
-
end
|
21
|
-
|
22
|
-
def rocketchat_error_notifier_event
|
23
|
-
'Worker Error Notifier'
|
24
|
-
end
|
25
|
-
|
26
|
-
def rocketchat_error_notifier_title
|
27
|
-
# Example with a link:
|
28
|
-
#
|
29
|
-
# For urls a default_url_options[:host] might be necessary.
|
30
|
-
# In this example I just copy it from existing action_mailer defaults.
|
31
|
-
#
|
32
|
-
# import = rocketchat_error_notifier_model
|
33
|
-
# host = Rails.application.config.action_mailer.default_url_options[:host]
|
34
|
-
# url = Rails.application.routes.url_helpers.import_url(import, host: host, protocol: :https)
|
35
|
-
# kind = I18n.t(import.kind, scope: 'import.kinds')
|
36
|
-
# text = "##{import.id} *#{kind}*"
|
37
|
-
# "[#{text}](#{url})"
|
38
|
-
klass = model.class.model_name.human
|
39
|
-
kind = I18n.t("activerecord.attributes.#{model.class.name.underscore}.kinds.#{model.kind}")
|
40
|
-
"#{klass} #{kind} ##{model.id}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def rocketchat_error_notifier_error_details(error)
|
44
|
-
details = "#{error.class}: #{error.message}\n"
|
45
|
-
details << error.backtrace[0..10].join("\n")
|
46
|
-
end
|
47
|
-
|
48
|
-
def rocketchat_error_notifier_message
|
49
|
-
message = []
|
50
|
-
message << rocketchat_error_notifier_receivers
|
51
|
-
message << rocketchat_error_notifier_title
|
52
|
-
message.compact.join(' - ')
|
53
|
-
end
|
54
|
-
|
55
|
-
def rocketchat_error_notifier_attachment(error)
|
56
|
-
{ collapsed: true, title: 'Error', text: rocketchat_error_notifier_error_details(error) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def rocketchat_error_notify(error)
|
60
|
-
RocketChatNotifier.notify(
|
61
|
-
rocketchat_error_notifier_message,
|
62
|
-
emoji: rocketchat_error_notifier_emoji,
|
63
|
-
event: "#{rocketchat_error_notifier_event} (#{Rails.env})",
|
64
|
-
attachment: rocketchat_error_notifier_attachment(error)
|
65
|
-
)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|