isomorfeus-mailer 2.0.0.rc5 → 2.0.0.rc9
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 +4 -4
- data/LICENSE +4 -0
- data/lib/isomorfeus/html2text.rb +268 -0
- data/lib/isomorfeus/mailer/version.rb +1 -1
- data/lib/isomorfeus-mailer.rb +2 -1
- metadata +66 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79eb7be2e4664b0eff1edfa2ed2ca4cde0015bad971e86997f3458384bd286af
|
4
|
+
data.tar.gz: feb4afafc27f29c8067b26e0b4147be40abb95221ec4a8f7b4d3b847cd98aad1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 975f1ec2eb91a68fc3e8de50878a7aab37991a40e900b69d77a57efd1d45208ae8270a899b42b9968c47c47003b2fb867ba093b1f87dc2de76d1ff0c22969d18
|
7
|
+
data.tar.gz: 9917bc1e73ec369ee96dd9ddf8342deece4ed57485e88268375e3389dc376ae0c840d5c01f2d2a07b0103bdb85f4c59091108e2c56c216a21b7bd03b7961bf4f
|
data/LICENSE
CHANGED
@@ -19,3 +19,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
SOFTWARE.
|
22
|
+
|
23
|
+
file lib/isomorfeus/html2text.rb originally taken from https://github.com/soundasleep/html2text_ruby:
|
24
|
+
|
25
|
+
MIT License as above, Copyright 2015 Jevon Wright
|
@@ -0,0 +1,268 @@
|
|
1
|
+
class Html2Text
|
2
|
+
VERSION = "0.3.1"
|
3
|
+
|
4
|
+
attr_reader :doc
|
5
|
+
|
6
|
+
def initialize(doc)
|
7
|
+
@doc = doc
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.convert(html)
|
11
|
+
html = html.to_s
|
12
|
+
|
13
|
+
if is_office_document?(html)
|
14
|
+
# Emulate the CSS rendering of Office documents
|
15
|
+
html = html.gsub("<p class=MsoNormal>", "<br>")
|
16
|
+
.gsub("<o:p> </o:p>", "<br>")
|
17
|
+
.gsub("<o:p></o:p>", "")
|
18
|
+
end
|
19
|
+
|
20
|
+
if !html.include?("<html")
|
21
|
+
# Stop Nokogiri from inserting in <p> tags
|
22
|
+
html = "<div>#{html}</div>"
|
23
|
+
end
|
24
|
+
|
25
|
+
html = fix_newlines(replace_entities(html))
|
26
|
+
doc = Nokogiri::HTML(html)
|
27
|
+
|
28
|
+
Html2Text.new(doc).convert
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.fix_newlines(text)
|
32
|
+
text.gsub("\r\n", "\n").gsub("\r", "\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.replace_entities(text)
|
36
|
+
text.gsub(" ", " ").gsub("\u00a0", " ").gsub("‌", "")
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert
|
40
|
+
output = iterate_over(doc)
|
41
|
+
output = remove_leading_and_trailing_whitespace(output)
|
42
|
+
output = remove_unnecessary_empty_lines(output)
|
43
|
+
return output.strip
|
44
|
+
end
|
45
|
+
|
46
|
+
DO_NOT_TOUCH_WHITESPACE = "<do-not-touch-whitespace>"
|
47
|
+
|
48
|
+
def remove_leading_and_trailing_whitespace(text)
|
49
|
+
# ignore any <pre> blocks, which we don't want to interact with
|
50
|
+
pre_blocks = text.split(DO_NOT_TOUCH_WHITESPACE)
|
51
|
+
|
52
|
+
output = []
|
53
|
+
pre_blocks.each.with_index do |block, index|
|
54
|
+
if index % 2 == 0
|
55
|
+
output << block.gsub(/[ \t]*\n[ \t]*/im, "\n").gsub(/ *\t */im, "\t")
|
56
|
+
else
|
57
|
+
output << block
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
output.join("")
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def self.is_office_document?(text)
|
67
|
+
text.include?("urn:schemas-microsoft-com:office")
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_unnecessary_empty_lines(text)
|
71
|
+
text.gsub(/\n\n\n*/im, "\n\n")
|
72
|
+
end
|
73
|
+
|
74
|
+
def trimmed_whitespace(text)
|
75
|
+
# Replace whitespace characters with a space (equivalent to \s)
|
76
|
+
# and force any text encoding into UTF-8
|
77
|
+
if text.valid_encoding?
|
78
|
+
text.gsub(/[\t\n\f\r ]+/im, " ")
|
79
|
+
else
|
80
|
+
text.force_encoding("WINDOWS-1252")
|
81
|
+
return trimmed_whitespace(text.encode("UTF-16be", invalid: :replace, replace: "?").encode('UTF-8'))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def iterate_over(node)
|
86
|
+
return "\n" if node.name.downcase == "br" && next_node_is_text?(node)
|
87
|
+
|
88
|
+
return trimmed_whitespace(node.text) if node.text?
|
89
|
+
|
90
|
+
if ["style", "head", "title", "meta", "script"].include?(node.name.downcase)
|
91
|
+
return ""
|
92
|
+
end
|
93
|
+
|
94
|
+
if node.name.downcase == "pre"
|
95
|
+
return "\n#{DO_NOT_TOUCH_WHITESPACE}#{node.text}#{DO_NOT_TOUCH_WHITESPACE}"
|
96
|
+
end
|
97
|
+
|
98
|
+
output = []
|
99
|
+
|
100
|
+
output << prefix_whitespace(node)
|
101
|
+
output += node.children.map do |child|
|
102
|
+
if !child.name.nil?
|
103
|
+
iterate_over(child)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
output << suffix_whitespace(node)
|
107
|
+
|
108
|
+
output = output.compact.join("") || ""
|
109
|
+
|
110
|
+
if !node.name.nil?
|
111
|
+
if node.name.downcase == "a"
|
112
|
+
output = wrap_link(node, output)
|
113
|
+
elsif node.name.downcase == "img"
|
114
|
+
output = image_text(node)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
return output
|
119
|
+
end
|
120
|
+
|
121
|
+
def prefix_whitespace(node)
|
122
|
+
case node.name.downcase
|
123
|
+
when "hr"
|
124
|
+
"\n---------------------------------------------------------------\n"
|
125
|
+
|
126
|
+
when "h1", "h2", "h3", "h4", "h5", "h6", "ol", "ul"
|
127
|
+
"\n\n"
|
128
|
+
|
129
|
+
when "p"
|
130
|
+
"\n\n"
|
131
|
+
|
132
|
+
when "tr"
|
133
|
+
"\n"
|
134
|
+
|
135
|
+
when "div"
|
136
|
+
if node.parent.name == "div" && (node.parent.text.strip == node.text.strip)
|
137
|
+
""
|
138
|
+
else
|
139
|
+
"\n"
|
140
|
+
end
|
141
|
+
|
142
|
+
when "td", "th"
|
143
|
+
"\t"
|
144
|
+
|
145
|
+
when "li"
|
146
|
+
"- "
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def suffix_whitespace(node)
|
151
|
+
case node.name.downcase
|
152
|
+
when "h1", "h2", "h3", "h4", "h5", "h6"
|
153
|
+
# add another line
|
154
|
+
"\n\n"
|
155
|
+
|
156
|
+
when "p"
|
157
|
+
"\n\n"
|
158
|
+
|
159
|
+
when "br"
|
160
|
+
if next_node_name(node) != "div" && next_node_name(node) != nil
|
161
|
+
"\n"
|
162
|
+
end
|
163
|
+
|
164
|
+
when "li"
|
165
|
+
"\n"
|
166
|
+
|
167
|
+
when "div"
|
168
|
+
if next_node_is_text?(node)
|
169
|
+
"\n"
|
170
|
+
elsif next_node_name(node) != "div" && next_node_name(node) != nil
|
171
|
+
"\n"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# links are returned in [text](link) format
|
177
|
+
def wrap_link(node, output)
|
178
|
+
href = node.attribute("href")
|
179
|
+
name = node.attribute("name")
|
180
|
+
|
181
|
+
output = output.strip
|
182
|
+
|
183
|
+
# remove double [[ ]]s from linking images
|
184
|
+
if output[0] == "[" && output[-1] == "]"
|
185
|
+
output = output[1, output.length - 2]
|
186
|
+
|
187
|
+
# for linking images, the title of the <a> overrides the title of the <img>
|
188
|
+
if node.attribute("title")
|
189
|
+
output = node.attribute("title").to_s
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# if there is no link text, but a title attr
|
194
|
+
if output.empty? && node.attribute("title")
|
195
|
+
output = node.attribute("title").to_s
|
196
|
+
end
|
197
|
+
|
198
|
+
if href.nil?
|
199
|
+
if !name.nil?
|
200
|
+
output = "[#{output}]"
|
201
|
+
end
|
202
|
+
else
|
203
|
+
href = href.to_s
|
204
|
+
|
205
|
+
if href != output && href != "mailto:#{output}" &&
|
206
|
+
href != "http://#{output}" && href != "https://#{output}"
|
207
|
+
if output.empty?
|
208
|
+
output = href
|
209
|
+
else
|
210
|
+
output = "[#{output}](#{href})"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
case next_node_name(node)
|
216
|
+
when "h1", "h2", "h3", "h4", "h5", "h6"
|
217
|
+
output += "\n"
|
218
|
+
end
|
219
|
+
|
220
|
+
output
|
221
|
+
end
|
222
|
+
|
223
|
+
def image_text(node)
|
224
|
+
if node.attribute("title")
|
225
|
+
"[" + node.attribute("title").to_s + "]"
|
226
|
+
elsif node.attribute("alt")
|
227
|
+
"[" + node.attribute("alt").to_s + "]"
|
228
|
+
else
|
229
|
+
""
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def next_node_name(node)
|
234
|
+
next_node = node.next_sibling
|
235
|
+
while next_node != nil
|
236
|
+
break if next_node.element?
|
237
|
+
next_node = next_node.next_sibling
|
238
|
+
end
|
239
|
+
|
240
|
+
if next_node && next_node.element?
|
241
|
+
next_node.name.downcase
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def next_node_is_text?(node)
|
246
|
+
return !node.next_sibling.nil? && node.next_sibling.text? && !node.next_sibling.text.strip.empty?
|
247
|
+
end
|
248
|
+
|
249
|
+
def previous_node_name(node)
|
250
|
+
previous_node = node.previous_sibling
|
251
|
+
while previous_node != nil
|
252
|
+
break if previous_node.element?
|
253
|
+
previous_node = previous_node.previous_sibling
|
254
|
+
end
|
255
|
+
|
256
|
+
if previous_node && previous_node.element?
|
257
|
+
previous_node.name.downcase
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def previous_node_is_text?(node)
|
262
|
+
return !node.previous_sibling.nil? && node.previous_sibling.text? && !node.previous_sibling.text.strip.empty?
|
263
|
+
end
|
264
|
+
|
265
|
+
# def previous_node_is_not_text?(node)
|
266
|
+
# return node.previous_sibling.nil? || !node.previous_sibling.text? || node.previous_sibling.text.strip.empty?
|
267
|
+
# end
|
268
|
+
end
|
data/lib/isomorfeus-mailer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isomorfeus-mailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,16 +16,44 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 7.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: mailhandler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.59
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.59
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: net-imap
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: net-smtp
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - "~>"
|
@@ -39,47 +67,47 @@ dependencies:
|
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: 0.3.1
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
70
|
+
name: nokogiri
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
75
|
+
version: 1.12.5
|
48
76
|
type: :runtime
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
82
|
+
version: 1.12.5
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: oj
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - "~>"
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.13.
|
89
|
+
version: 3.13.10
|
62
90
|
type: :runtime
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.13.
|
96
|
+
version: 3.13.10
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: opal
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
103
|
+
version: 1.4.0
|
76
104
|
type: :runtime
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.
|
110
|
+
version: 1.4.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: opal-activesupport
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,70 +128,70 @@ dependencies:
|
|
100
128
|
requirements:
|
101
129
|
- - "~>"
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.14.
|
131
|
+
version: 0.14.3
|
104
132
|
type: :runtime
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
136
|
- - "~>"
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.14.
|
138
|
+
version: 0.14.3
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: isomorfeus-preact
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
143
|
- - "~>"
|
116
144
|
- !ruby/object:Gem::Version
|
117
|
-
version: 10.6.
|
145
|
+
version: 10.6.5
|
118
146
|
type: :runtime
|
119
147
|
prerelease: false
|
120
148
|
version_requirements: !ruby/object:Gem::Requirement
|
121
149
|
requirements:
|
122
150
|
- - "~>"
|
123
151
|
- !ruby/object:Gem::Version
|
124
|
-
version: 10.6.
|
152
|
+
version: 10.6.5
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
154
|
name: isomorfeus-redux
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
128
156
|
requirements:
|
129
157
|
- - "~>"
|
130
158
|
- !ruby/object:Gem::Version
|
131
|
-
version: 4.1.
|
159
|
+
version: 4.1.11
|
132
160
|
type: :runtime
|
133
161
|
prerelease: false
|
134
162
|
version_requirements: !ruby/object:Gem::Requirement
|
135
163
|
requirements:
|
136
164
|
- - "~>"
|
137
165
|
- !ruby/object:Gem::Version
|
138
|
-
version: 4.1.
|
166
|
+
version: 4.1.11
|
139
167
|
- !ruby/object:Gem::Dependency
|
140
168
|
name: isomorfeus-transport
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
142
170
|
requirements:
|
143
171
|
- - '='
|
144
172
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.0.0.
|
173
|
+
version: 2.0.0.rc9
|
146
174
|
type: :runtime
|
147
175
|
prerelease: false
|
148
176
|
version_requirements: !ruby/object:Gem::Requirement
|
149
177
|
requirements:
|
150
178
|
- - '='
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.0.0.
|
180
|
+
version: 2.0.0.rc9
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: isomorfeus
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
156
184
|
requirements:
|
157
185
|
- - '='
|
158
186
|
- !ruby/object:Gem::Version
|
159
|
-
version: 2.0.0.
|
187
|
+
version: 2.0.0.rc9
|
160
188
|
type: :development
|
161
189
|
prerelease: false
|
162
190
|
version_requirements: !ruby/object:Gem::Requirement
|
163
191
|
requirements:
|
164
192
|
- - '='
|
165
193
|
- !ruby/object:Gem::Version
|
166
|
-
version: 2.0.0.
|
194
|
+
version: 2.0.0.rc9
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
196
|
name: rake
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +220,20 @@ dependencies:
|
|
192
220
|
- - "~>"
|
193
221
|
- !ruby/object:Gem::Version
|
194
222
|
version: 3.10.0
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: rspec-collection_matchers
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 1.2.0
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 1.2.0
|
195
237
|
description: Write mail template components and send mail.
|
196
238
|
email: jan@kursator.de
|
197
239
|
executables: []
|
@@ -201,6 +243,7 @@ files:
|
|
201
243
|
- LICENSE
|
202
244
|
- README.md
|
203
245
|
- lib/isomorfeus-mailer.rb
|
246
|
+
- lib/isomorfeus/html2text.rb
|
204
247
|
- lib/isomorfeus/mailer/config.rb
|
205
248
|
- lib/isomorfeus/mailer/imports.rb
|
206
249
|
- lib/isomorfeus/mailer/version.rb
|
@@ -225,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
268
|
- !ruby/object:Gem::Version
|
226
269
|
version: 1.3.1
|
227
270
|
requirements: []
|
228
|
-
rubygems_version: 3.
|
271
|
+
rubygems_version: 3.3.3
|
229
272
|
signing_key:
|
230
273
|
specification_version: 4
|
231
274
|
summary: Write mail template components and send mail.
|