lazylead 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|