eco-rake 0.2.4 → 0.2.6
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 +4 -4
- data/CHANGELOG.md +13 -1
- data/eco-rake.gemspec +1 -0
- data/lib/eco-rake/lib/files/decrypt.rb +9 -2
- data/lib/eco-rake/lib/people/sync_launch.rb +26 -8
- data/lib/eco-rake/lib/people/sync_options.rb +1 -0
- data/lib/eco-rake/lib/people/sync_process.rb +3 -0
- data/lib/eco-rake/lib/people/sync_rely.rb +5 -1
- data/lib/eco-rake/option/mirror.rb +2 -0
- data/lib/eco-rake/patches/exception.rb +46 -0
- data/lib/eco-rake/patches.rb +6 -0
- data/lib/eco-rake/shell/files.rb +6 -0
- data/lib/eco-rake/utils/mailer/aws_provider.rb +71 -0
- data/lib/eco-rake/utils/mailer/provider_base.rb +48 -0
- data/lib/eco-rake/utils/mailer/sendgrid_provider.rb +110 -0
- data/lib/eco-rake/utils/mailer.rb +54 -40
- data/lib/eco-rake/version.rb +1 -1
- data/lib/eco-rake.rb +1 -0
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6f834edf2918e4ff4e45cfcf538da2e59b632fad4222a3b996f5ab00c60fb25
|
4
|
+
data.tar.gz: 1f0a90c3242171b560b6adb848e50fc58cd569e61e915e7e9363e6c50c4c6266
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b619ed8b4ebdf32cb30fdef61f5821d821c1338464e3cfe5d2331df930f00582c0c008c1fe3dac53744b328e4d126a8609f87c71d647889028215f9b709e0895
|
7
|
+
data.tar.gz: c90b0316f090eec3f5ed131a0bfd808e75ca190f38c8f5f447524161de88c43f39aafe0d9db91a6882c4d7bd70a62ece823a3fde56cdfdc71062eee178d934a6
|
data/CHANGELOG.md
CHANGED
@@ -2,14 +2,26 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [0.2.
|
5
|
+
## [0.2.6] - 2024-12-09
|
6
6
|
|
7
7
|
### Added
|
8
8
|
|
9
|
+
- `EcoRake::Lib::People::SyncLaunch` new constant `join_files`
|
10
|
+
- To specify the integration to use the target folder in raw
|
11
|
+
- Which will use all the files with matching pattern within.
|
12
|
+
|
9
13
|
### Fixed
|
10
14
|
|
11
15
|
### Changed
|
12
16
|
|
17
|
+
## [0.2.5] - 2024-10-01
|
18
|
+
|
19
|
+
### Added
|
20
|
+
|
21
|
+
- `--no-email` option to the people sync process.
|
22
|
+
- Helper to summarize an error Exception
|
23
|
+
- `SendGrid` mailer
|
24
|
+
|
13
25
|
## [0.2.4] - 2024-09-05
|
14
26
|
|
15
27
|
### Added
|
data/eco-rake.gemspec
CHANGED
@@ -12,13 +12,20 @@ class EcoRake
|
|
12
12
|
def task(*_args)
|
13
13
|
return display_target_files if options[:list]
|
14
14
|
return warn_missing_file if target_files.empty?
|
15
|
+
|
15
16
|
status = 0
|
16
17
|
target_files.each do |file|
|
17
18
|
delete_file(gpg_to_csv_filename(file))
|
18
|
-
|
19
|
+
|
20
|
+
stat = sh_continue(
|
21
|
+
decrypt_command(file, ignore_mdc_error: ignore_mdc_error)
|
22
|
+
)
|
23
|
+
|
19
24
|
status = stat unless stat.zero?
|
20
25
|
end
|
21
|
-
|
26
|
+
|
27
|
+
msg = "Deleting files from '#{source_folder}'"
|
28
|
+
delete_file(*target_files, message: msg) unless options[:simulate]
|
22
29
|
exit status unless status.zero?
|
23
30
|
end
|
24
31
|
|
@@ -5,12 +5,13 @@ class EcoRake
|
|
5
5
|
# @todo ping some back-end that it was run
|
6
6
|
# - Should be able to log at debug level.
|
7
7
|
class SyncLaunch < EcoRake::Lib::People::BaseTask
|
8
|
-
ADDITIONAL_OPTIONS = %i[only_stats no_policy simulate].freeze
|
8
|
+
ADDITIONAL_OPTIONS = %i[only_stats no_policy simulate no_email].freeze
|
9
9
|
FORWARD_RULES = {
|
10
10
|
schema: ->(schema) { "-schema-id \"#{schema}\"" },
|
11
11
|
only_stats: '-feed-only-stats',
|
12
12
|
no_policy: '-skip-batch-policy',
|
13
|
-
simulate: '-simulate'
|
13
|
+
simulate: '-simulate',
|
14
|
+
no_email: '-no-email'
|
14
15
|
}.freeze
|
15
16
|
|
16
17
|
attr_const :target_enviro, required: true
|
@@ -20,6 +21,7 @@ class EcoRake
|
|
20
21
|
attr_const :snapshot_mode, default: :full
|
21
22
|
attr_const :local_folder, default: '.'
|
22
23
|
attr_const :mail_to
|
24
|
+
attr_const :join_files, default: false
|
23
25
|
|
24
26
|
option_reopen :schema, default_lookup: :default_schema, required: true
|
25
27
|
option_reopen :folder, default_lookup: :local_folder
|
@@ -29,7 +31,7 @@ class EcoRake
|
|
29
31
|
def task(*_args)
|
30
32
|
return missing_files_notify unless latest_file
|
31
33
|
return process_deltas if delta?
|
32
|
-
|
34
|
+
process_full_file if full? || delta_last?
|
33
35
|
end
|
34
36
|
|
35
37
|
private
|
@@ -51,9 +53,12 @@ class EcoRake
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def missing_files_notify
|
54
|
-
|
56
|
+
msg = "Missing files to be processed"
|
57
|
+
puts msg
|
55
58
|
exit 1 if options[:simulate]
|
56
|
-
exit 1
|
59
|
+
exit 1 if options[:no_email]
|
60
|
+
exit 1 unless (inbox = mail_to)
|
61
|
+
|
57
62
|
email_missing_files(enviro: target_enviro, to: inbox)
|
58
63
|
exit 1
|
59
64
|
end
|
@@ -83,12 +88,14 @@ class EcoRake
|
|
83
88
|
# @note it ensures basic information is not missing or inconsistent.
|
84
89
|
def base_command(file_or_folder)
|
85
90
|
raise "Missing target file or folder in #{self.class}" if file_or_folder.to_s.strip.empty?
|
91
|
+
|
86
92
|
usecase = base_usecase.to_sym
|
87
93
|
case usecase
|
88
94
|
when :hris
|
89
95
|
msg = "Inconsistent configuration in #{self.class}. BASE_USECASE is '#{usecase}', "
|
90
96
|
msg << "but file SNAPSHOT_MODE is '#{snapshot_mode}'"
|
91
97
|
raise msg if delta? || delta_last?
|
98
|
+
|
92
99
|
"-hris-from #{double_quote(file_or_folder)}"
|
93
100
|
when :upsert
|
94
101
|
"-upsert-from #{double_quote(file_or_folder)}"
|
@@ -106,28 +113,39 @@ class EcoRake
|
|
106
113
|
%i[partial delta].any? {|m| m == mode}
|
107
114
|
end
|
108
115
|
|
116
|
+
# only last delta (i.e. customer builds deltas based on eP full snapshot)
|
109
117
|
def delta_last?
|
110
|
-
snapshot_mode.to_s.downcase.to_sym
|
118
|
+
snapshot_mode.to_s.downcase.to_sym == :delta_last
|
111
119
|
end
|
112
120
|
|
113
121
|
# Amont the `target_files` the last in alphabetic order.
|
114
122
|
def latest_file
|
115
|
-
@latest_file ||=
|
123
|
+
@latest_file ||= ''.then do
|
124
|
+
next options[:folder] if join_files
|
125
|
+
|
126
|
+
target_files.last
|
127
|
+
end
|
116
128
|
end
|
117
129
|
|
118
130
|
# @note if there is a file_pattern method or FILE_PATTERN const, it's used as a pattern.
|
119
131
|
# @return [Array<String>] the `csv` files of the target folder
|
120
132
|
def target_files
|
121
|
-
@target_files ||=
|
133
|
+
@target_files ||= [].then do
|
134
|
+
next options[:folder] if join_files
|
135
|
+
|
136
|
+
csv_files(options[:folder], regexp: file_pattern)
|
137
|
+
end
|
122
138
|
end
|
123
139
|
|
124
140
|
# Deletes the files identified as target.
|
125
141
|
def clear_files
|
126
142
|
deleted_files = target_files.each_with_object([]) do |file, deleted|
|
127
143
|
next unless File.exist?(file)
|
144
|
+
|
128
145
|
File.delete(file)
|
129
146
|
deleted << file
|
130
147
|
end
|
148
|
+
|
131
149
|
puts "Deleted these files:\n • #{deleted_files.join("\n • ")}" unless deleted_files.empty?
|
132
150
|
end
|
133
151
|
end
|
@@ -9,6 +9,7 @@ class EcoRake
|
|
9
9
|
option '-o', '--only-stats', TrueClass, desc: 'To display only stats in the feedback'
|
10
10
|
option '-b', '--no-policy', FalseClass, desc: 'To skip the batch policy'
|
11
11
|
option '-n', '--no-get', FalseClass, desc: 'Skip get people step'
|
12
|
+
option '-m', '--no-email', FalseClass, desc: 'Do not notify'
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -22,6 +22,7 @@ class EcoRake
|
|
22
22
|
|
23
23
|
sh_continue rake_sync_command
|
24
24
|
return if options[:simulate]
|
25
|
+
|
25
26
|
sh_continue rake_sftp_archive if pull_driver == 'sftp'
|
26
27
|
sh_continue rake_files_purge('cache')
|
27
28
|
sh_continue rake_files_purge('requests')
|
@@ -62,7 +63,9 @@ class EcoRake
|
|
62
63
|
msg = 'File decryption failed'
|
63
64
|
puts msg
|
64
65
|
exit 1 if options[:simulate]
|
66
|
+
exit 1 if options[:no_email]
|
65
67
|
exit 1 unless inbox = mail_to
|
68
|
+
|
66
69
|
email(enviro: target_enviro, to: inbox, subject: msg, body: msg)
|
67
70
|
exit 1
|
68
71
|
end
|
@@ -10,6 +10,7 @@ class EcoRake
|
|
10
10
|
only_stats: :mirror,
|
11
11
|
no_policy: :mirror,
|
12
12
|
no_get: :mirror,
|
13
|
+
no_email: :mirror,
|
13
14
|
simulate: :mirror
|
14
15
|
}.freeze
|
15
16
|
|
@@ -24,7 +25,10 @@ class EcoRake
|
|
24
25
|
private
|
25
26
|
|
26
27
|
def rake_sync_command
|
27
|
-
rake_command(
|
28
|
+
rake_command(
|
29
|
+
namespaced_task,
|
30
|
+
*forward_options(*FORWARD_RULES.keys - [:enviro])
|
31
|
+
)
|
28
32
|
end
|
29
33
|
|
30
34
|
def rake_command(task_name, *options)
|
@@ -25,8 +25,10 @@ class EcoRake
|
|
25
25
|
# puts "boolean_mirror (#{value}): #{opt}" if name == :no_get
|
26
26
|
|
27
27
|
return nil unless [TrueClass, NilClass, FalseClass].any? {|klass| type_coercion == klass}
|
28
|
+
|
28
29
|
enabled_value = !boolean_name? || [TrueClass, NilClass].any? {|klass| type_coercion == klass}
|
29
30
|
return opt if value == enabled_value
|
31
|
+
|
30
32
|
name_false_hypen if boolean_name? && value == !enabled_value
|
31
33
|
end
|
32
34
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class ::Exception
|
2
|
+
def patch_full_message(trace_count: -1)
|
3
|
+
tracing = backtrace || []
|
4
|
+
first_ln = tracing[0]
|
5
|
+
tracing = tracing[1..trace_count]
|
6
|
+
tracing = tracing[1..30] if instance_of?(SystemStackError)
|
7
|
+
tracing ||= []
|
8
|
+
|
9
|
+
msg = []
|
10
|
+
msg << "\n#{first_ln} \n#{message} (#{self.class})"
|
11
|
+
tracing.each_with_index do |bt, i|
|
12
|
+
msg << "#{" " * 8}#{i + 1}: from #{bt}"
|
13
|
+
end
|
14
|
+
|
15
|
+
unless cause.nil?
|
16
|
+
msg << "\nCAUSE:"
|
17
|
+
msg << cause.patch_full_message(trace_count: trace_count)
|
18
|
+
end
|
19
|
+
|
20
|
+
msg.join("\n")
|
21
|
+
rescue StandardError => e
|
22
|
+
puts "Something is wrong with 'patch_full_message': #{e}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# To extend an exception message preserving same exception object
|
27
|
+
# @see https://stackoverflow.com/a/30133010/4352306
|
28
|
+
Exception.class_eval do
|
29
|
+
def prepend_message(message)
|
30
|
+
mod = Module.new do
|
31
|
+
define_method :to_s do
|
32
|
+
String(message) + super()
|
33
|
+
end
|
34
|
+
end
|
35
|
+
extend mod
|
36
|
+
end
|
37
|
+
|
38
|
+
def append_message(message)
|
39
|
+
mod = Module.new do
|
40
|
+
define_method :to_s do
|
41
|
+
super() + String(message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
extend mod
|
45
|
+
end
|
46
|
+
end
|
data/lib/eco-rake/shell/files.rb
CHANGED
@@ -9,6 +9,7 @@ class EcoRake
|
|
9
9
|
def upsert_local_dir(path)
|
10
10
|
return if path.to_s.strip.empty?
|
11
11
|
return if File.directory?(path)
|
12
|
+
|
12
13
|
require 'fileutils'
|
13
14
|
puts "Creating directory '#{path}'"
|
14
15
|
FileUtils.mkdir_p(path)
|
@@ -18,7 +19,9 @@ class EcoRake
|
|
18
19
|
def delete_file(*files, message: 'Deleting files:')
|
19
20
|
files = files.select {|file| File.exist?(file)}
|
20
21
|
return if files.empty?
|
22
|
+
|
21
23
|
puts message if message
|
24
|
+
|
22
25
|
files.each do |file|
|
23
26
|
File.delete(file)
|
24
27
|
puts " • #{file}" if message
|
@@ -27,6 +30,7 @@ class EcoRake
|
|
27
30
|
|
28
31
|
def move_file(*files, folder:, message: 'Moving files:')
|
29
32
|
puts message if message
|
33
|
+
|
30
34
|
files.each do |file|
|
31
35
|
new_name = File.join(folder, File.basename(file))
|
32
36
|
File.name(file, new_name)
|
@@ -62,6 +66,7 @@ class EcoRake
|
|
62
66
|
# @return [String]
|
63
67
|
def gpg_to_csv_filename(gpg_file)
|
64
68
|
return nil unless gpg_file
|
69
|
+
|
65
70
|
ext = gpg_file.split('.')[1..-1].join('.')
|
66
71
|
base = File.basename(gpg_file, ".#{ext}")
|
67
72
|
folder = File.dirname(gpg_file)
|
@@ -76,6 +81,7 @@ class EcoRake
|
|
76
81
|
|
77
82
|
def days_to_seconds(days)
|
78
83
|
return nil unless days
|
84
|
+
|
79
85
|
days * DAY_SECONDS
|
80
86
|
end
|
81
87
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# rubocop:disable Naming/MethodParameterName
|
2
|
+
class EcoRake
|
3
|
+
module Utils
|
4
|
+
class Mailer
|
5
|
+
class AwsProvider < ProviderBase
|
6
|
+
def send_mail(subject:, body:, to: nil, cc: nil, bcc: nil)
|
7
|
+
ses.send_email(
|
8
|
+
destination: fetch_destination(to: to, cc: cc, bcc: bcc),
|
9
|
+
source: fetch_from,
|
10
|
+
message: {
|
11
|
+
subject: {
|
12
|
+
charset: "UTF-8",
|
13
|
+
data: subject
|
14
|
+
},
|
15
|
+
body: {
|
16
|
+
# NOTE: (html) will let you send html instead
|
17
|
+
# you can use both at once if you like
|
18
|
+
text: {
|
19
|
+
charset: "UTF-8",
|
20
|
+
data: body
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Boolean] whether or not the mailer is configured for usage.
|
28
|
+
def configured?
|
29
|
+
fetch_access_key_id && fetch_secret_access_key && fetch_region
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def credentials
|
35
|
+
@credentials ||= {
|
36
|
+
id: 'MAILER_KEY_ID',
|
37
|
+
key: 'MAILER_ACCESS_KEY'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def ses
|
42
|
+
require 'aws-sdk-ses'
|
43
|
+
@ses ||= Aws::SES::Client.new(
|
44
|
+
access_key_id: fetch_access_key_id,
|
45
|
+
secret_access_key: fetch_secret_access_key,
|
46
|
+
region: fetch_region
|
47
|
+
)
|
48
|
+
rescue StandardError => err
|
49
|
+
puts "Trying to send an email with wrong email configuration: #{err}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_destination(to: nil, cc: nil, bcc: nil)
|
53
|
+
{
|
54
|
+
to_addresses: [fetch_to(to)].flatten.compact.uniq
|
55
|
+
}.tap do |dest|
|
56
|
+
cc = [cc].flatten.compact.uniq
|
57
|
+
bcc = [bcc].flatten.compact.uniq
|
58
|
+
dest.merge!(cc_addresses: cc) unless cc.empty?
|
59
|
+
dest.merge!(bcc_addresses: bcc) unless bcc.empty?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def fetch_region
|
64
|
+
ENV['MAILER_REGION']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# rubocop:enable Naming/MethodParameterName
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Utils
|
3
|
+
class Mailer
|
4
|
+
class ProviderBase
|
5
|
+
class << self
|
6
|
+
def to_desc(to: nil, cc: nil, bcc: nil)
|
7
|
+
cc_to = [cc].flatten.compact.uniq
|
8
|
+
bcc_to = [bcc].flatten.compact.uniq
|
9
|
+
{ to_addresses: [to].flatten.compact.uniq }.tap do |dest|
|
10
|
+
dest.merge!(cc_addresses: cc_to) unless cc_to.empty?
|
11
|
+
dest.merge!(bcc_addresses: bcc_to) unless bcc_to.empty?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def send_mail(subject:, body:, to: nil, cc: nil, bcc: nil) # rubocop:disable Lint/UnusedMethodArgument
|
17
|
+
raise "You must implement this method"
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch_to(value = nil)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def credentials
|
27
|
+
raise "You must implement this method"
|
28
|
+
end
|
29
|
+
|
30
|
+
def fetch_from(value = nil)
|
31
|
+
value || ENV['MAILER_FROM']
|
32
|
+
end
|
33
|
+
|
34
|
+
def fetch_access_key_id
|
35
|
+
env_mail(:id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch_secret_access_key
|
39
|
+
env_mail(:key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def env_mail(prop)
|
43
|
+
ENV[credentials[prop]]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# rubocop:disable Naming/MethodParameterName
|
2
|
+
class EcoRake
|
3
|
+
module Utils
|
4
|
+
class Mailer
|
5
|
+
class SendgridProvider < ProviderBase
|
6
|
+
def send_mail(subject:, body:, to: nil, cc: nil, bcc: nil)
|
7
|
+
return false unless sendgrid
|
8
|
+
|
9
|
+
data = to_data(
|
10
|
+
subject: subject,
|
11
|
+
body: body,
|
12
|
+
to: to,
|
13
|
+
cc: cc,
|
14
|
+
bcc: bcc
|
15
|
+
)
|
16
|
+
|
17
|
+
mailer._("send").post(request_body: data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch_to(value = nil)
|
21
|
+
emails = [super].flatten.compact
|
22
|
+
to_email_model(emails)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean] whether or not the mailer is configured for usage.
|
26
|
+
def configured?
|
27
|
+
fetch_secret_access_key
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def credentials
|
33
|
+
@credentials ||= {
|
34
|
+
id: 'SENDGRID_ACCESS_ID',
|
35
|
+
key: 'SENDGRID_ACCESS_KEY'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_data(subject:, body:, to: nil, cc: nil, bcc: nil)
|
40
|
+
{
|
41
|
+
"personalizations" => [
|
42
|
+
{
|
43
|
+
"to" => fetch_to(to).flatten,
|
44
|
+
"subject" => subject
|
45
|
+
}.tap do |pers|
|
46
|
+
merge_if('cc', cc, target: pers)
|
47
|
+
merge_if('bcc', bcc, target: pers)
|
48
|
+
end
|
49
|
+
],
|
50
|
+
"from" => fetch_from,
|
51
|
+
"content" => [
|
52
|
+
{
|
53
|
+
"type" => "text/plain",
|
54
|
+
"value" => body
|
55
|
+
}
|
56
|
+
]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def mailer
|
61
|
+
@mailer ||= sendgrid&.client&.mail
|
62
|
+
end
|
63
|
+
|
64
|
+
def sendgrid
|
65
|
+
require 'sendgrid-ruby'
|
66
|
+
extend(::SendGrid) unless is_a?(SendGrid)
|
67
|
+
|
68
|
+
@sendgrid ||= SendGrid::API.new(
|
69
|
+
api_key: fetch_secret_access_key
|
70
|
+
)
|
71
|
+
rescue StandardError => err
|
72
|
+
puts "Trying to send an email with wrong email configuration: #{err}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_email_model(value)
|
76
|
+
case value
|
77
|
+
when Array
|
78
|
+
value.map do |val|
|
79
|
+
to_email_model(val)
|
80
|
+
end.compact
|
81
|
+
else
|
82
|
+
return if value.to_s.strip.empty?
|
83
|
+
|
84
|
+
{
|
85
|
+
"email" => value
|
86
|
+
}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def merge_if(key, data, target: {})
|
91
|
+
return if data.to_s.strip.empty?
|
92
|
+
|
93
|
+
key_data = to_email_model(data)
|
94
|
+
|
95
|
+
return if key_data.nil?
|
96
|
+
return if key_data.empty?
|
97
|
+
|
98
|
+
target.merge!({key.to_s => key_data})
|
99
|
+
end
|
100
|
+
|
101
|
+
def fetch_from(value = nil)
|
102
|
+
email = [super].flatten.compact.first
|
103
|
+
to_email_model(email)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# rubocop:enable Naming/MethodParameterName
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require_relative 'mailer/provider_base'
|
2
|
+
require_relative 'mailer/aws_provider'
|
3
|
+
require_relative 'mailer/sendgrid_provider'
|
4
|
+
|
1
5
|
class EcoRake
|
2
6
|
module Utils
|
3
7
|
# Mailer helper that uses `aws-sdk-ses` **gem** (`Aws::SES::Client`)
|
@@ -7,6 +11,13 @@ class EcoRake
|
|
7
11
|
# 3. `MAILER_ACCESS_KEY`
|
8
12
|
# 4. `MAILER_FROM`
|
9
13
|
class Mailer
|
14
|
+
DEFAULT_PROVIDER = :sendgrid
|
15
|
+
|
16
|
+
attr_reader :provider
|
17
|
+
def initialize(provider: DEFAULT_PROVIDER)
|
18
|
+
@provider = provider || DEFAULT_PROVIDER
|
19
|
+
end
|
20
|
+
|
10
21
|
# Sends an email
|
11
22
|
# @param to [String] destination email address
|
12
23
|
# @param subject [String] subject of the email
|
@@ -17,6 +28,7 @@ class EcoRake
|
|
17
28
|
puts "Mailer: You are missing configuration parameters. Review your .env file"
|
18
29
|
return false
|
19
30
|
end
|
31
|
+
|
20
32
|
ses.send_email(
|
21
33
|
destination: fetch_to(to: to, cc: cc, bcc: bcc),
|
22
34
|
source: fetch_from(from),
|
@@ -37,54 +49,56 @@ class EcoRake
|
|
37
49
|
).tap do |response|
|
38
50
|
puts "Sent email to #{to} (MessageId: #{response.message_id})"
|
39
51
|
end
|
52
|
+
rescue StandardError => err
|
53
|
+
msg = "The mailer generated an exception:\n"
|
54
|
+
msg << err.patch_full_message(trace_count: 15)
|
55
|
+
puts msg
|
40
56
|
end
|
57
|
+
# Sends an email
|
58
|
+
# @param to [String] destination email address
|
59
|
+
# @param subject [String] subject of the email
|
60
|
+
# @param body [String] `html` or plain text message
|
61
|
+
def mail(subject:, body:, to: nil, cc: nil, bcc: nil)
|
62
|
+
return false unless (serv = service)
|
41
63
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def ses
|
50
|
-
require 'aws-sdk-ses'
|
51
|
-
begin
|
52
|
-
@ses ||= Aws::SES::Client.new(
|
53
|
-
access_key_id: fetch_access_key_id,
|
54
|
-
secret_access_key: fetch_secret_access_key,
|
55
|
-
region: fetch_region
|
56
|
-
)
|
57
|
-
rescue StandardError => e
|
58
|
-
puts "Trying to send an email with wrong email configuration: #{e}"
|
59
|
-
end
|
60
|
-
@ses
|
61
|
-
end
|
62
|
-
|
63
|
-
def fetch_to(to: nil, cc: nil, bcc: nil)
|
64
|
-
{
|
65
|
-
to_addresses: [to].flatten.compact.uniq
|
66
|
-
}.tap do |dest|
|
67
|
-
cc = [cc].flatten.compact.uniq
|
68
|
-
bcc = [bcc].flatten.compact.uniq
|
69
|
-
dest.merge!(cc_addresses: cc) unless cc.empty?
|
70
|
-
dest.merge!(bcc_addresses: bcc) unless bcc.empty?
|
64
|
+
unless serv.configured?
|
65
|
+
msg = "Mailer: You are missing configuration parameters "
|
66
|
+
msg << "for '#{provider}'. Review your .env file"
|
67
|
+
puts msg
|
68
|
+
return false
|
71
69
|
end
|
72
|
-
end
|
73
70
|
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
serv.send_mail(
|
72
|
+
subject: subject,
|
73
|
+
body: body,
|
74
|
+
to: to,
|
75
|
+
cc: cc,
|
76
|
+
bcc: bcc
|
77
|
+
).tap do |response|
|
78
|
+
next unless response
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
+
to_addr = serv.fetch_to(to)
|
81
|
+
msg = "Sent email #{ProviderBase.to_desc(to: to_addr, cc: cc, bcc: bcc)}"
|
82
|
+
puts msg
|
83
|
+
end
|
84
|
+
rescue StandardError => err
|
85
|
+
msg = "The mailer generated an exception:\n"
|
86
|
+
msg << err.patch_full_message(trace_count: 15)
|
87
|
+
puts msg
|
80
88
|
end
|
81
89
|
|
82
|
-
|
83
|
-
ENV['MAILER_ACCESS_KEY']
|
84
|
-
end
|
90
|
+
private
|
85
91
|
|
86
|
-
def
|
87
|
-
|
92
|
+
def service
|
93
|
+
case provider
|
94
|
+
when :aws
|
95
|
+
AwsProvider.new
|
96
|
+
when :sendgrid
|
97
|
+
SendgridProvider.new
|
98
|
+
else
|
99
|
+
puts "Unknown mail provider '#{provider}'"
|
100
|
+
nil
|
101
|
+
end
|
88
102
|
end
|
89
103
|
end
|
90
104
|
end
|
data/lib/eco-rake/version.rb
CHANGED
data/lib/eco-rake.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eco-rake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura Samper
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09
|
11
|
+
date: 2024-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -158,6 +158,20 @@ dependencies:
|
|
158
158
|
- - "~>"
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '0.4'
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
name: sendgrid-ruby
|
163
|
+
requirement: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: 6.7.0
|
168
|
+
type: :runtime
|
169
|
+
prerelease: false
|
170
|
+
version_requirements: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 6.7.0
|
161
175
|
description:
|
162
176
|
email:
|
163
177
|
- oscar@ecoportal.co.nz
|
@@ -223,6 +237,8 @@ files:
|
|
223
237
|
- lib/eco-rake/options/library.rb
|
224
238
|
- lib/eco-rake/options/parental.rb
|
225
239
|
- lib/eco-rake/options/set.rb
|
240
|
+
- lib/eco-rake/patches.rb
|
241
|
+
- lib/eco-rake/patches/exception.rb
|
226
242
|
- lib/eco-rake/rake_task.rb
|
227
243
|
- lib/eco-rake/shell.rb
|
228
244
|
- lib/eco-rake/shell/command.rb
|
@@ -232,6 +248,9 @@ files:
|
|
232
248
|
- lib/eco-rake/tasks.rb
|
233
249
|
- lib/eco-rake/utils.rb
|
234
250
|
- lib/eco-rake/utils/mailer.rb
|
251
|
+
- lib/eco-rake/utils/mailer/aws_provider.rb
|
252
|
+
- lib/eco-rake/utils/mailer/provider_base.rb
|
253
|
+
- lib/eco-rake/utils/mailer/sendgrid_provider.rb
|
235
254
|
- lib/eco-rake/utils/mailing.rb
|
236
255
|
- lib/eco-rake/utils/timing.rb
|
237
256
|
- lib/eco-rake/version.rb
|
@@ -255,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
274
|
- !ruby/object:Gem::Version
|
256
275
|
version: '0'
|
257
276
|
requirements: []
|
258
|
-
rubygems_version: 3.5.
|
277
|
+
rubygems_version: 3.5.23
|
259
278
|
signing_key:
|
260
279
|
specification_version: 4
|
261
280
|
summary: A set of helpers to build re-usable `rake` integration helpers.
|