lazylead 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ .dockerignore +12 -0
- data/.0pdd.yml +5 -0
- data/.circleci/config.yml +50 -0
- data/.circleci/release_image.sh +13 -0
- data/.circleci/validate.sh +10 -0
- data/.docker/Dockerfile +31 -0
- data/.docker/build.sh +6 -0
- data/.docker/docker-compose.yml +23 -0
- data/.docker/readme.md +21 -0
- data/.gitattributes +9 -0
- data/.github/CODE_OF_CONDUCT.md +76 -0
- data/.github/CONTRIBUTING.md +9 -0
- data/.github/ISSUE_TEMPLATE.md +14 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
- data/.github/tasks.yml +24 -0
- data/.github/trello.md +18 -0
- data/.gitignore +12 -0
- data/.pdd +5 -0
- data/.rubocop.yml +87 -0
- data/.ruby-version +1 -0
- data/.rultor.yml +31 -0
- data/.simplecov +16 -0
- data/.travis.yml +16 -0
- data/Gemfile +27 -0
- data/Guardfile +33 -0
- data/Rakefile +93 -0
- data/appveyor.yml +50 -0
- data/bin/.ruby-version +1 -0
- data/bin/lazylead +99 -0
- data/build.sh +6 -0
- data/deploy.sh +16 -0
- data/lazylead.gemspec +106 -0
- data/lib/lazylead.rb +52 -0
- data/lib/lazylead/allocated.rb +56 -0
- data/lib/lazylead/cli/app.rb +87 -0
- data/lib/lazylead/confluence.rb +157 -0
- data/lib/lazylead/email.rb +74 -0
- data/lib/lazylead/exchange.rb +83 -0
- data/lib/lazylead/log.rb +71 -0
- data/lib/lazylead/model.rb +140 -0
- data/lib/lazylead/postman.rb +78 -0
- data/lib/lazylead/salt.rb +91 -0
- data/lib/lazylead/schedule.rb +88 -0
- data/lib/lazylead/smtp.rb +82 -0
- data/lib/lazylead/system/empty.rb +36 -0
- data/lib/lazylead/system/fake.rb +41 -0
- data/lib/lazylead/system/jira.rb +249 -0
- data/lib/lazylead/system/synced.rb +41 -0
- data/lib/lazylead/task/alert.rb +105 -0
- data/lib/lazylead/task/confluence_ref.rb +59 -0
- data/lib/lazylead/task/echo.rb +38 -0
- data/lib/lazylead/task/fix_version.rb +79 -0
- data/lib/lazylead/task/missing_comment.rb +53 -0
- data/lib/lazylead/version.rb +27 -0
- data/lib/messages/due_date_expired.erb +96 -0
- data/lib/messages/illegal_fixversion_change.erb +120 -0
- data/lib/messages/missing_comment.erb +128 -0
- data/license.txt +21 -0
- data/readme.md +160 -0
- data/test/lazylead/allocated_test.rb +51 -0
- data/test/lazylead/cli/app_test.rb +74 -0
- data/test/lazylead/confluence_test.rb +55 -0
- data/test/lazylead/exchange_test.rb +68 -0
- data/test/lazylead/model_test.rb +65 -0
- data/test/lazylead/salt_test.rb +42 -0
- data/test/lazylead/smoke_test.rb +38 -0
- data/test/lazylead/smtp_test.rb +65 -0
- data/test/lazylead/system/jira_test.rb +110 -0
- data/test/lazylead/task/confluence_ref_test.rb +66 -0
- data/test/lazylead/task/duedate_test.rb +126 -0
- data/test/lazylead/task/echo_test.rb +34 -0
- data/test/lazylead/task/fix_version_test.rb +52 -0
- data/test/lazylead/task/missing_comment_test.rb +56 -0
- data/test/lazylead/version_test.rb +36 -0
- data/test/sqlite_test.rb +80 -0
- data/test/test.rb +103 -0
- data/todo.yml +16 -0
- data/upgrades/sqlite/001-install-main-lazylead-tables.sql +63 -0
- data/upgrades/sqlite/999.testdata.sql +39 -0
- metadata +815 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019-2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"),
|
9
|
+
# to deal in the Software without restriction, including without limitation
|
10
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
11
|
+
# and/or sell copies of the Software, and to permit persons to whom
|
12
|
+
# the Software is furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
15
|
+
# in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
22
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
23
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
require "tilt"
|
26
|
+
|
27
|
+
module Lazylead
|
28
|
+
# Email notifications utilities.
|
29
|
+
module Emailing
|
30
|
+
# Construct html document from template and binds.
|
31
|
+
def make_body(opts)
|
32
|
+
Email.new(
|
33
|
+
opts["template"],
|
34
|
+
opts.merge(version: Lazylead::VERSION)
|
35
|
+
).render
|
36
|
+
end
|
37
|
+
|
38
|
+
# Split text with email addresses by ',' and trim all elements if needed.
|
39
|
+
def split(type, opts)
|
40
|
+
if opts[type].include? ","
|
41
|
+
opts[type].split(",").map(&:strip).reject(&:empty?)
|
42
|
+
else
|
43
|
+
[opts[type]]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# An email regarding tickets based on file with markup.
|
49
|
+
#
|
50
|
+
# The 'tilt' gem was used as a template engine.
|
51
|
+
# Read more about 'tilt':
|
52
|
+
# - https://github.com/rtomayko/tilt
|
53
|
+
# - https://github.com/rtomayko/tilt/blob/master/docs/TEMPLATES.md
|
54
|
+
# - https://www.rubyguides.com/2018/11/ruby-erb-haml-slim/
|
55
|
+
#
|
56
|
+
# Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
|
57
|
+
# Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
|
58
|
+
# License:: MIT
|
59
|
+
class Email
|
60
|
+
# :file :: the file with html template
|
61
|
+
# :binds :: the template variables for substitution.
|
62
|
+
def initialize(file, binds)
|
63
|
+
@file = file
|
64
|
+
@binds = binds
|
65
|
+
end
|
66
|
+
|
67
|
+
# Construct the email body from html template based on variables (binds).
|
68
|
+
def render
|
69
|
+
Tilt.new(@file)
|
70
|
+
.render(OpenStruct.new(@binds))
|
71
|
+
.delete!("\n")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019-2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"),
|
9
|
+
# to deal in the Software without restriction, including without limitation
|
10
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
11
|
+
# and/or sell copies of the Software, and to permit persons to whom
|
12
|
+
# the Software is furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
15
|
+
# in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
22
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
23
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
require "viewpoint"
|
26
|
+
require_relative "log"
|
27
|
+
require_relative "salt"
|
28
|
+
require_relative "email"
|
29
|
+
require_relative "version"
|
30
|
+
|
31
|
+
module Lazylead
|
32
|
+
#
|
33
|
+
# A postman to send emails to the Microsoft Exchange server.
|
34
|
+
#
|
35
|
+
# @todo #/DEV Add support of symbols for options in order to use both
|
36
|
+
# notations like opts[:endpoint] or opts["endpoint"].
|
37
|
+
#
|
38
|
+
# Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
|
39
|
+
# Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
|
40
|
+
# License:: MIT
|
41
|
+
class Exchange
|
42
|
+
include Emailing
|
43
|
+
|
44
|
+
def initialize(
|
45
|
+
log = Log::NOTHING, salt = Salt.new("exchange_salt"), opts = ENV.to_h
|
46
|
+
)
|
47
|
+
@log = log
|
48
|
+
@salt = salt
|
49
|
+
@opts = opts
|
50
|
+
end
|
51
|
+
|
52
|
+
# Send an email.
|
53
|
+
# :opts :: the mail configuration like from, cc, subject, template.
|
54
|
+
def send(opts)
|
55
|
+
to = opts["to"] || opts[:to]
|
56
|
+
to = [to] unless to.is_a? Array
|
57
|
+
html = make_body(opts)
|
58
|
+
msg = {
|
59
|
+
subject: opts["subject"],
|
60
|
+
body: html,
|
61
|
+
body_type: "HTML",
|
62
|
+
to_recipients: to
|
63
|
+
}
|
64
|
+
msg.update(cc_recipients: split("cc", opts)) if opts.key? "cc"
|
65
|
+
cli.send_message msg
|
66
|
+
@log.debug "Email was generated from #{opts} and send by #{__FILE__}. " \
|
67
|
+
"Here is the body: #{html}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def cli
|
73
|
+
return @cli if defined? @cli
|
74
|
+
url = @opts["exchange_url"]
|
75
|
+
usr = @opts["exchange_user"]
|
76
|
+
psw = @opts["exchange_password"]
|
77
|
+
usr = @salt.decrypt(usr) if @salt.specified?
|
78
|
+
psw = @salt.decrypt(psw) if @salt.specified?
|
79
|
+
@log.debug "Connect to MS Exchange server #{url} as '#{usr}'"
|
80
|
+
@cli = Viewpoint::EWSClient.new url, usr, psw
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/lazylead/log.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019-2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"),
|
9
|
+
# to deal in the Software without restriction, including without limitation
|
10
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
11
|
+
# and/or sell copies of the Software, and to permit persons to whom
|
12
|
+
# the Software is furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
15
|
+
# in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
22
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
23
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
require "logging"
|
26
|
+
|
27
|
+
module Lazylead
|
28
|
+
# Loggers.
|
29
|
+
#
|
30
|
+
# There are 3 colored loggers so far:
|
31
|
+
# NOTHING - for cases when logging isn't required
|
32
|
+
# VERBOSE - all logging levels including debug
|
33
|
+
# ERRORS - for errors only which are critical for app.
|
34
|
+
#
|
35
|
+
module Log
|
36
|
+
# Coloring configuration for appender(s).
|
37
|
+
Logging.color_scheme("bright",
|
38
|
+
levels: {
|
39
|
+
info: :green,
|
40
|
+
warn: :yellow,
|
41
|
+
error: :red,
|
42
|
+
fatal: %i[white on_red]
|
43
|
+
},
|
44
|
+
date: :blue,
|
45
|
+
logger: :cyan)
|
46
|
+
Logging.appenders.stdout(
|
47
|
+
"stdout",
|
48
|
+
layout: Logging.layouts.pattern(
|
49
|
+
pattern: "[%d] %-5l %m\n",
|
50
|
+
color_scheme: "bright"
|
51
|
+
)
|
52
|
+
)
|
53
|
+
|
54
|
+
# Nothing to log
|
55
|
+
NOTHING = Logging.logger["nothing"]
|
56
|
+
NOTHING.level = :off
|
57
|
+
NOTHING.freeze
|
58
|
+
|
59
|
+
# All levels including debug
|
60
|
+
VERBOSE = Logging.logger["verbose"]
|
61
|
+
VERBOSE.level = :debug
|
62
|
+
VERBOSE.add_appenders "stdout"
|
63
|
+
VERBOSE.freeze
|
64
|
+
|
65
|
+
# Alerts
|
66
|
+
ERRORS = Logging.logger["errors"]
|
67
|
+
ERRORS.level = :error
|
68
|
+
ERRORS.add_appenders "stdout"
|
69
|
+
ERRORS.freeze
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019-2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"),
|
9
|
+
# to deal in the Software without restriction, including without limitation
|
10
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
11
|
+
# and/or sell copies of the Software, and to permit persons to whom
|
12
|
+
# the Software is furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
15
|
+
# in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
22
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
23
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
require "active_record"
|
26
|
+
require "require_all"
|
27
|
+
require_rel "task"
|
28
|
+
require_rel "system"
|
29
|
+
require_relative "log"
|
30
|
+
require_relative "postman"
|
31
|
+
require_relative "exchange"
|
32
|
+
|
33
|
+
#
|
34
|
+
# ORM domain model entities.
|
35
|
+
#
|
36
|
+
# Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
|
37
|
+
# Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
|
38
|
+
# License:: MIT
|
39
|
+
module Lazylead
|
40
|
+
# ORM-related methods
|
41
|
+
module ORM
|
42
|
+
# Tables from database may have configuration in json column.
|
43
|
+
# Some of those properties might be configured/overridden by environment
|
44
|
+
# variable using macros "${...}"
|
45
|
+
# {
|
46
|
+
# ...
|
47
|
+
# "user" = "${my_user}",
|
48
|
+
# "pass" = "${my_pass}"
|
49
|
+
# "url" = "https://url.com"
|
50
|
+
# ...
|
51
|
+
# }
|
52
|
+
# next, we need to configure following environment variables(ENV)
|
53
|
+
# my_user=XXXXX
|
54
|
+
# my_pass=YYYYY
|
55
|
+
# thus, the result of this method is
|
56
|
+
# {
|
57
|
+
# ...
|
58
|
+
# "user" = "XXXXXX",
|
59
|
+
# "pass" = "YYYYYY"
|
60
|
+
# "url" = "https://url.com"
|
61
|
+
# ...
|
62
|
+
# }
|
63
|
+
def env(opts)
|
64
|
+
opts.each_with_object({}) do |e, o|
|
65
|
+
k = e[0]
|
66
|
+
v = e[1]
|
67
|
+
v = ENV[v.slice(2, v.length - 3)] if v.start_with? "${"
|
68
|
+
o[k] = v
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Convert json-based database column 'properties' to hash.
|
73
|
+
def to_hash
|
74
|
+
JSON.parse(properties).to_h
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
attributes.map { |k, v| "#{k}='#{v}'" }.join(", ")
|
79
|
+
end
|
80
|
+
|
81
|
+
def inspect
|
82
|
+
to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
# General lazylead task.
|
86
|
+
class Task < ActiveRecord::Base
|
87
|
+
include ORM
|
88
|
+
belongs_to :team, foreign_key: "team_id"
|
89
|
+
belongs_to :system, foreign_key: "system"
|
90
|
+
|
91
|
+
def exec(log = Log::NOTHING)
|
92
|
+
log.debug("Task ##{id} '#{name}' is started")
|
93
|
+
action.constantize
|
94
|
+
.new(log)
|
95
|
+
.run(system.connect(log), postman(log), props)
|
96
|
+
log.debug("Task ##{id} '#{name}' is completed")
|
97
|
+
end
|
98
|
+
|
99
|
+
def props
|
100
|
+
return @prop if defined? @prop
|
101
|
+
@prop = team.to_hash.merge(to_hash)
|
102
|
+
end
|
103
|
+
|
104
|
+
def postman(log = Log::NOTHING)
|
105
|
+
if props.key? "postman"
|
106
|
+
props["postman"].constantize.new(log)
|
107
|
+
else
|
108
|
+
log.warn "No postman details provided, an local stub is used."
|
109
|
+
Postman.new
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Ticketing systems to monitor.
|
115
|
+
class System < ActiveRecord::Base
|
116
|
+
include ORM
|
117
|
+
|
118
|
+
# Make an instance of ticketing system for future interaction.
|
119
|
+
def connect(log = Log::NOTHING)
|
120
|
+
opts = to_hash
|
121
|
+
if opts["type"].empty?
|
122
|
+
log.warn "No task system details provided, an empty stub is used."
|
123
|
+
Empty.new
|
124
|
+
else
|
125
|
+
opts["type"].constantize.new(
|
126
|
+
env(opts.except("type", "salt")),
|
127
|
+
opts["salt"].blank? ? NoSalt.new : Salt.new(opts["salt"]),
|
128
|
+
log
|
129
|
+
)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# A team for lazylead task.
|
135
|
+
# Each team may have several tasks.
|
136
|
+
class Team < ActiveRecord::Base
|
137
|
+
include ORM
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019-2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"),
|
9
|
+
# to deal in the Software without restriction, including without limitation
|
10
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
11
|
+
# and/or sell copies of the Software, and to permit persons to whom
|
12
|
+
# the Software is furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
15
|
+
# in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
22
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
23
|
+
# OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
require_relative "log"
|
26
|
+
require_relative "email"
|
27
|
+
require_relative "version"
|
28
|
+
|
29
|
+
module Lazylead
|
30
|
+
#
|
31
|
+
# A postman to send emails.
|
32
|
+
#
|
33
|
+
# @todo #/DEV Merge Smtp and Postman objects. There might be different
|
34
|
+
# postman's based on different mail servers, thus its better to keep together
|
35
|
+
# the instantiation and sending. For each type of mail servers we should have
|
36
|
+
# separate object.
|
37
|
+
#
|
38
|
+
# @todo #/DEV TestMail.deliveries -> store all emails to the files in
|
39
|
+
# /test/resources/testmailer/*.html. Right now after each test with email
|
40
|
+
# sending we taking the body and test it content. Quite ofter we need to
|
41
|
+
# check visual style in mails, etc, thus its better to store them on disk.
|
42
|
+
#
|
43
|
+
# Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
|
44
|
+
# Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
|
45
|
+
# License:: MIT
|
46
|
+
class Postman
|
47
|
+
include Emailing
|
48
|
+
|
49
|
+
def initialize(log = Log::NOTHING)
|
50
|
+
@log = log
|
51
|
+
end
|
52
|
+
|
53
|
+
# Send an email.
|
54
|
+
# :opts :: the mail configuration like to, from, cc, subject, template.
|
55
|
+
def send(opts)
|
56
|
+
html = make_body(opts)
|
57
|
+
cc = detect_cc(opts)
|
58
|
+
Mail.deliver do
|
59
|
+
to opts[:to] || opts["to"]
|
60
|
+
from opts["from"]
|
61
|
+
cc cc if opts.key? "cc"
|
62
|
+
subject opts["subject"]
|
63
|
+
html_part do
|
64
|
+
content_type "text/html; charset=UTF-8"
|
65
|
+
body html
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@log.debug "Email was generated from #{opts} and send by #{__FILE__}. " \
|
69
|
+
"Here is the body: #{html}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def detect_cc(opts)
|
73
|
+
cc = opts["cc"]
|
74
|
+
cc = split("cc", opts) if !cc.nil? && cc.include?(",")
|
75
|
+
cc
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|