card-mod-email 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/card/format/email_html_format.rb +14 -0
- data/lib/card/format/email_text_format.rb +12 -0
- data/set/abstract/email_field.rb +41 -0
- data/set/abstract/test_context.rb +26 -0
- data/set/all/email_html.rb +9 -0
- data/set/all/email_text.rb +14 -0
- data/set/right/bcc.rb +1 -0
- data/set/right/cc.rb +1 -0
- data/set/right/from.rb +1 -0
- data/set/right/html_message.rb +13 -0
- data/set/right/subject.rb +1 -0
- data/set/right/text_message.rb +1 -0
- data/set/right/to.rb +1 -0
- data/set/type/email_template.rb +91 -0
- data/set/type/email_template/email_config.rb +81 -0
- metadata +75 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3719c8ba807c0372733ecd09c9eb2e1a635f4ad07f3558392f78525e8e91f86e
|
4
|
+
data.tar.gz: c56306768a9067cae84f5448c729dbb5e061024611eccadef71422c4ad2a6dbc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a0637a78d1c7a46886847a66e4e38f72d92871377aa5196eabd0c77eed76575e9016ffe9f4bd4b77e32c29744a8ff64d3655a96caad5f820568a325ef918d64d
|
7
|
+
data.tar.gz: 14a8fec3f37d261f4e591de75e24988c9c894880c5f4e08362b0a386e95428730ed35c4bead808e2baa17f25f0d692c94418a2f789251a7fd6a2c154796a161b
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class Card
|
4
|
+
class Format
|
5
|
+
# Format text for use in html email messages
|
6
|
+
class EmailHtmlFormat < Card::Format::HtmlFormat
|
7
|
+
@@aliases["email"] = "email_html"
|
8
|
+
|
9
|
+
def self.view_caching?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
format do
|
3
|
+
# turn off autodetection of uri's
|
4
|
+
def chunk_list
|
5
|
+
:references
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# format :html do
|
10
|
+
# def pointer_items args
|
11
|
+
# card.item_names(context: :raw).map do |iname|
|
12
|
+
# wrap_item iname, args
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# end#
|
16
|
+
|
17
|
+
format :email_text do
|
18
|
+
def email_addresses context
|
19
|
+
context ||= self
|
20
|
+
card.item_names(context: context.name).map do |name|
|
21
|
+
# FIXME: context is processed twice here because pointers absolutize
|
22
|
+
# item_names by default while other types can return relative names.
|
23
|
+
# That's poor default behavior and should be fixed!
|
24
|
+
name = name.to_name.absolute context
|
25
|
+
email_address?(name) ? name : email_address_from_card(name, context)
|
26
|
+
end.flatten.compact.join(", ")
|
27
|
+
end
|
28
|
+
|
29
|
+
def email_address? string
|
30
|
+
string =~ /.+\@.+\..+/
|
31
|
+
end
|
32
|
+
|
33
|
+
def email_address_from_card name, context
|
34
|
+
card = Card.fetch name
|
35
|
+
card.account&.email || email_addresses_from_card_content(card, context)
|
36
|
+
end
|
37
|
+
|
38
|
+
def email_addresses_from_card_content card, context
|
39
|
+
subformat(card).contextual_content(context).split(/[,\n]/)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
format :html do
|
2
|
+
view :core do
|
3
|
+
return super() if voo.hide? :test_context
|
4
|
+
card.with_context test_context_card do
|
5
|
+
super()
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_context_card
|
10
|
+
card.left.fetch(:test_context)&.item_card
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
format :email_html do
|
15
|
+
view :core do
|
16
|
+
voo.hide! :test_context
|
17
|
+
super()
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
format :email_text do
|
22
|
+
view :core do
|
23
|
+
voo.hide! :test_context
|
24
|
+
super()
|
25
|
+
end
|
26
|
+
end
|
data/set/right/bcc.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::EmailField
|
data/set/right/cc.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::EmailField
|
data/set/right/from.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::EmailField
|
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::TestContext
|
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::TestContext
|
data/set/right/to.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include_set Abstract::EmailField
|
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
def clean_html?
|
3
|
+
false
|
4
|
+
end
|
5
|
+
|
6
|
+
def deliver context=nil, fields={}, opts={}
|
7
|
+
mail = format.mail context, fields, opts
|
8
|
+
mail.deliver
|
9
|
+
rescue Net::SMTPError => exception
|
10
|
+
errors.add :exception, exception.message
|
11
|
+
end
|
12
|
+
|
13
|
+
format do
|
14
|
+
def mail context=nil, fields={}, opts={}
|
15
|
+
config = card.email_config context, fields, opts
|
16
|
+
fmt = self # self is <Mail::Message> within the new_mail block
|
17
|
+
Card::Mailer.new_mail config do
|
18
|
+
fmt.message_body self, config
|
19
|
+
fmt.add_attachments self, config.delete(:attach)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def message_body mail, config
|
24
|
+
config[:html_message] &&= config[:html_message].call mail
|
25
|
+
method, args = body_method_and_args config[:html_message].present?,
|
26
|
+
config[:text_message].present?
|
27
|
+
args = Array.wrap(args).map { |arg| config[arg] }
|
28
|
+
send method, mail, *args
|
29
|
+
end
|
30
|
+
|
31
|
+
def body_method_and_args html, text
|
32
|
+
if html && text
|
33
|
+
[:text_and_html_message, %i[text_message html_message attach]]
|
34
|
+
elsif html
|
35
|
+
%i[html_body html_message]
|
36
|
+
else
|
37
|
+
%i[text_body text_message]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def text_and_html_message mail, text_message, html_message, attachment_list=nil
|
42
|
+
fmt = self
|
43
|
+
if attachment_list&.any?
|
44
|
+
mail.multipart_mixed text_message, html_message
|
45
|
+
else
|
46
|
+
mail.text_part { body text_message }
|
47
|
+
mail.html_part { fmt.html_body self, html_message }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def multipart_mixed mail, text_message, html_message
|
52
|
+
mail.content_type "multipart/mixed"
|
53
|
+
mail.part content_type: "multipart/alternative" do |copy|
|
54
|
+
copy.part content_type: "text/plain" do |plain|
|
55
|
+
plain.body = text_message
|
56
|
+
end
|
57
|
+
copy.part content_type: "text/html" do |html|
|
58
|
+
html.body = html_message
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def html_body mail, message
|
64
|
+
mail.content_type "text/html; charset=UTF-8"
|
65
|
+
mail.body message
|
66
|
+
end
|
67
|
+
|
68
|
+
def text_body mail, message
|
69
|
+
mail.content_type "text/plain; charset=UTF-8"
|
70
|
+
mail.text_part { body message }
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_attachments mail, list
|
74
|
+
return unless list.present?
|
75
|
+
each_valid_attachment list do |file, index|
|
76
|
+
mail.add_file filename: attachment_name(file, index),
|
77
|
+
content: File.read(file.path)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def each_valid_attachment list
|
82
|
+
list.each_with_index do |cardname, index|
|
83
|
+
next unless (file = Card[cardname]&.try(:attachment))
|
84
|
+
yield file, index
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def attachment_name file, number
|
89
|
+
"attachment-#{number + 1}.#{file.extension}"
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
EMAIL_FIELDS =
|
2
|
+
%i[to from cc bcc attach subject text_message html_message].freeze
|
3
|
+
|
4
|
+
EMAIL_FIELD_METHODS =
|
5
|
+
{ subject: :contextual_content,
|
6
|
+
text_message: :contextual_content,
|
7
|
+
attach: :extended_item_contents }.freeze
|
8
|
+
|
9
|
+
# @param [Card] context the card in whose context all email fields will be interpreted
|
10
|
+
# @param [Hash] fields override any templated field configurations with hash values
|
11
|
+
# @param [Hash] opts options for rendering. unknown options become format options
|
12
|
+
# @option opts [Card, String, Integer] :auth user identifier. render as this user
|
13
|
+
def email_config context, fields={}, opts={}
|
14
|
+
@active_email_context = context || self
|
15
|
+
auth = opts.delete :auth
|
16
|
+
config = EMAIL_FIELDS.each_with_object({}) do |field, conf|
|
17
|
+
conf[field] = fields[field] || email_field_from_card(field, auth, opts)
|
18
|
+
end
|
19
|
+
safe_from_and_reply_to! config
|
20
|
+
config.select { |_k, v| v.present? }
|
21
|
+
end
|
22
|
+
|
23
|
+
def email_field_from_card field, auth, format_opts
|
24
|
+
return unless (field_card = fetch(field))
|
25
|
+
auth ||= field_card.updater
|
26
|
+
special_email_field_method(field, field_card, auth, format_opts) ||
|
27
|
+
standard_email_field(field, field_card, auth, format_opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def special_email_field_method field, field_card, auth, format_opts
|
31
|
+
method = "email_#{field}_field"
|
32
|
+
return unless respond_to? method
|
33
|
+
send method, field_card, auth, format_opts
|
34
|
+
end
|
35
|
+
|
36
|
+
def standard_email_field field, field_card, auth, format_opts
|
37
|
+
method = EMAIL_FIELD_METHODS[field] || :email_addresses
|
38
|
+
format_opts = format_opts.merge format: :email_text
|
39
|
+
Auth.as auth do
|
40
|
+
field_card.format(format_opts).send method, @active_email_context
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# html messages return procs because image attachments can't be properly rendered
|
45
|
+
# without a mail object. (which isn't available at initial config time)
|
46
|
+
def email_html_message_field message_card, auth, format_opts
|
47
|
+
proc do |mail|
|
48
|
+
Auth.as auth do
|
49
|
+
format_opts = format_opts.merge format: :email_html, active_mail: mail
|
50
|
+
message_card.format(format_opts).email_content @active_email_context
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# whenever a default "from" field is configured in Card::Mailer, emails are always
|
56
|
+
# actually "from" that address
|
57
|
+
def safe_from_and_reply_to! config
|
58
|
+
conf_name, conf_email = configured_from_name_and_email config[:from]
|
59
|
+
actual_email = Card::Mailer.default[:from] || conf_email
|
60
|
+
config[:from] = email_from_field_value conf_name, conf_email, actual_email
|
61
|
+
config[:reply_to] ||= actual_email
|
62
|
+
end
|
63
|
+
|
64
|
+
def email_from_field_value conf_name, conf_email, actual_email
|
65
|
+
conf_text = conf_name || conf_email
|
66
|
+
if conf_text != actual_email
|
67
|
+
%("#{conf_text}" <#{actual_email}>)
|
68
|
+
elsif actual_email.present?
|
69
|
+
actual_email
|
70
|
+
else
|
71
|
+
Card[WagnBotID].account.email
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def configured_from_name_and_email raw_string
|
76
|
+
if raw_string =~ /(.*)\<(.*)>/
|
77
|
+
[Regexp.last_match(1).strip, Regexp.last_match(2)]
|
78
|
+
else
|
79
|
+
[nil, raw_string]
|
80
|
+
end
|
81
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: card-mod-email
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.11.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ethan McCutchen
|
8
|
+
- Philipp Kühl
|
9
|
+
- Gerry Gleason
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2020-12-24 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: card
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.101.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - '='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 1.101.0
|
29
|
+
description: ''
|
30
|
+
email:
|
31
|
+
- info@decko.org
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- lib/card/format/email_html_format.rb
|
37
|
+
- lib/card/format/email_text_format.rb
|
38
|
+
- set/abstract/email_field.rb
|
39
|
+
- set/abstract/test_context.rb
|
40
|
+
- set/all/email_html.rb
|
41
|
+
- set/all/email_text.rb
|
42
|
+
- set/right/bcc.rb
|
43
|
+
- set/right/cc.rb
|
44
|
+
- set/right/from.rb
|
45
|
+
- set/right/html_message.rb
|
46
|
+
- set/right/subject.rb
|
47
|
+
- set/right/text_message.rb
|
48
|
+
- set/right/to.rb
|
49
|
+
- set/type/email_template.rb
|
50
|
+
- set/type/email_template/email_config.rb
|
51
|
+
homepage: http://decko.org
|
52
|
+
licenses:
|
53
|
+
- GPL-3.0
|
54
|
+
metadata:
|
55
|
+
card-mod: email
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '2.5'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubygems_version: 3.0.3
|
72
|
+
signing_key:
|
73
|
+
specification_version: 4
|
74
|
+
summary: Email handling
|
75
|
+
test_files: []
|