card-mod-email 0.11.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/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: []
|