card-mod-email 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,12 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ class Card
4
+ class Format
5
+ # Format text for use in plain text email messages
6
+ class EmailTextFormat < Card::Format::TextFormat
7
+ def chunk_list
8
+ :references
9
+ end
10
+ end
11
+ end
12
+ 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
@@ -0,0 +1,9 @@
1
+ format :email_html do
2
+ view :unknown do
3
+ ""
4
+ end
5
+
6
+ view :compact_missing do
7
+ ""
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+
2
+ format :email_text do
3
+ view :unknown do
4
+ ""
5
+ end
6
+
7
+ view :compact_missing do
8
+ ""
9
+ end
10
+
11
+ view :last_action, perms: :none, cache: :never do
12
+ _render_last_action_verb
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ include_set Abstract::EmailField
@@ -0,0 +1 @@
1
+ include_set Abstract::EmailField
@@ -0,0 +1 @@
1
+ include_set Abstract::EmailField
@@ -0,0 +1,13 @@
1
+ include_set Abstract::TestContext
2
+
3
+ def clean_html?
4
+ false
5
+ end
6
+
7
+ format :email_html do
8
+ def email_content context
9
+ content = contextual_content context
10
+ return unless content.present?
11
+ Card::Mailer.layout content
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ include_set Abstract::TestContext
@@ -0,0 +1 @@
1
+ include_set Abstract::TestContext
@@ -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: []