email_reply_parser 0.3.0 → 0.4.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.
- data/email_reply_parser.gemspec +5 -2
- data/lib/email_reply_parser.rb +16 -8
- data/test/email_reply_parser_test.rb +30 -0
- data/test/emails/correct_sig.txt +4 -0
- data/test/emails/email_1_5.txt +15 -0
- data/test/emails/email_1_6.txt +15 -0
- metadata +27 -38
data/email_reply_parser.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'email_reply_parser'
|
16
|
-
s.version = '0.
|
17
|
-
s.date = '
|
16
|
+
s.version = '0.4.0'
|
17
|
+
s.date = '2012-03-01'
|
18
18
|
s.rubyforge_project = 'email_reply_parser'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -65,10 +65,13 @@ Gem::Specification.new do |s|
|
|
65
65
|
email_reply_parser.gemspec
|
66
66
|
lib/email_reply_parser.rb
|
67
67
|
test/email_reply_parser_test.rb
|
68
|
+
test/emails/correct_sig.txt
|
68
69
|
test/emails/email_1_1.txt
|
69
70
|
test/emails/email_1_2.txt
|
70
71
|
test/emails/email_1_3.txt
|
71
72
|
test/emails/email_1_4.txt
|
73
|
+
test/emails/email_1_5.txt
|
74
|
+
test/emails/email_1_6.txt
|
72
75
|
]
|
73
76
|
# = MANIFEST =
|
74
77
|
|
data/lib/email_reply_parser.rb
CHANGED
@@ -19,7 +19,7 @@ require 'strscan'
|
|
19
19
|
#
|
20
20
|
# this is some text
|
21
21
|
#
|
22
|
-
# --
|
22
|
+
# --
|
23
23
|
# Bob
|
24
24
|
# http://homepage.com/~bob
|
25
25
|
#
|
@@ -30,7 +30,7 @@ require 'strscan'
|
|
30
30
|
#
|
31
31
|
# [mail]: https://github.com/mikel/mail
|
32
32
|
class EmailReplyParser
|
33
|
-
VERSION = "0.
|
33
|
+
VERSION = "0.4.0"
|
34
34
|
|
35
35
|
# Splits an email body into a list of Fragments.
|
36
36
|
#
|
@@ -60,9 +60,16 @@ class EmailReplyParser
|
|
60
60
|
#
|
61
61
|
# Returns this same Email instance.
|
62
62
|
def read(text)
|
63
|
+
# Check for multi-line reply headers. Some clients break up
|
64
|
+
# the "On DATE, NAME <EMAIL> wrote:" line into multiple lines.
|
65
|
+
if text =~ /^(On(.+)wrote:)$/m
|
66
|
+
# Remove all new lines from the reply header.
|
67
|
+
text.gsub! $1, $1.gsub("\n", " ")
|
68
|
+
end
|
69
|
+
|
63
70
|
# The text is reversed initially due to the way we check for hidden
|
64
71
|
# fragments.
|
65
|
-
text.reverse
|
72
|
+
text = text.reverse
|
66
73
|
|
67
74
|
# This determines if any 'visible' Fragment has been found. Once any
|
68
75
|
# visible Fragment is found, stop looking for hidden ones.
|
@@ -85,7 +92,7 @@ class EmailReplyParser
|
|
85
92
|
end
|
86
93
|
|
87
94
|
# Finish up the final fragment. Finishing a fragment will detect any
|
88
|
-
# attributes (hidden, signature, reply), and join each line into a
|
95
|
+
# attributes (hidden, signature, reply), and join each line into a
|
89
96
|
# string.
|
90
97
|
finish_fragment
|
91
98
|
|
@@ -98,6 +105,7 @@ class EmailReplyParser
|
|
98
105
|
|
99
106
|
private
|
100
107
|
EMPTY = "".freeze
|
108
|
+
SIG_REGEX = /(\s--|__|\w-)$/
|
101
109
|
|
102
110
|
### Line-by-Line Parsing
|
103
111
|
|
@@ -109,7 +117,7 @@ class EmailReplyParser
|
|
109
117
|
# Returns nothing.
|
110
118
|
def scan_line(line)
|
111
119
|
line.chomp!("\n")
|
112
|
-
line.lstrip!
|
120
|
+
line.lstrip! unless line =~ SIG_REGEX
|
113
121
|
|
114
122
|
# We're looking for leading `>`'s to see if this line is part of a
|
115
123
|
# quoted Fragment.
|
@@ -118,7 +126,7 @@ class EmailReplyParser
|
|
118
126
|
# Mark the current Fragment as a signature if the current line is empty
|
119
127
|
# and the Fragment starts with a common signature indicator.
|
120
128
|
if @fragment && line == EMPTY
|
121
|
-
if @fragment.lines.last =~
|
129
|
+
if @fragment.lines.last =~ SIG_REGEX
|
122
130
|
@fragment.signature = true
|
123
131
|
finish_fragment
|
124
132
|
end
|
@@ -165,10 +173,10 @@ class EmailReplyParser
|
|
165
173
|
#
|
166
174
|
# Go fish! (visible)
|
167
175
|
#
|
168
|
-
# > --
|
176
|
+
# > --
|
169
177
|
# > Player 1 (quoted, hidden)
|
170
178
|
#
|
171
|
-
# --
|
179
|
+
# --
|
172
180
|
# Player 2 (signature, hidden)
|
173
181
|
#
|
174
182
|
def finish_fragment
|
@@ -71,6 +71,36 @@ I am currently using the Java HTTP API.\n", reply.fragments[0].to_s
|
|
71
71
|
assert_match /Loader/, reply.fragments[1].to_s
|
72
72
|
end
|
73
73
|
|
74
|
+
def test_a_complex_body_with_only_one_fragment
|
75
|
+
reply = email :email_1_5
|
76
|
+
|
77
|
+
assert_equal 1, reply.fragments.size
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_reads_email_with_correct_signature
|
81
|
+
reply = email :correct_sig
|
82
|
+
|
83
|
+
assert_equal 2, reply.fragments.size
|
84
|
+
assert_equal [false, false], reply.fragments.map { |f| f.quoted? }
|
85
|
+
assert_equal [false, true], reply.fragments.map { |f| f.signature? }
|
86
|
+
assert_equal [false, true], reply.fragments.map { |f| f.hidden? }
|
87
|
+
assert_match /^-- \nrick/, reply.fragments[1].to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_deals_with_multiline_reply_headers
|
91
|
+
reply = email :email_1_6
|
92
|
+
|
93
|
+
assert_match /^I get/, reply.fragments[0].to_s
|
94
|
+
assert_match /^On/, reply.fragments[1].to_s
|
95
|
+
assert_match /Was this/, reply.fragments[1].to_s
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_does_not_modify_input_string
|
99
|
+
original = "The Quick Brown Fox Jumps Over The Lazy Dog"
|
100
|
+
EmailReplyParser.read original
|
101
|
+
assert_equal "The Quick Brown Fox Jumps Over The Lazy Dog", original
|
102
|
+
end
|
103
|
+
|
74
104
|
def email(name)
|
75
105
|
body = IO.read EMAIL_FIXTURE_PATH.join("#{name}.txt").to_s
|
76
106
|
EmailReplyParser.read body
|
@@ -0,0 +1,15 @@
|
|
1
|
+
One: Here's what I've got.
|
2
|
+
|
3
|
+
- This would be the first bullet point that wraps to the second line
|
4
|
+
to the next
|
5
|
+
- This is the second bullet point and it doesn't wrap
|
6
|
+
- This is the third bullet point and I'm having trouble coming up with enough
|
7
|
+
to say
|
8
|
+
- This is the fourth bullet point
|
9
|
+
|
10
|
+
Two:
|
11
|
+
- Here is another bullet point
|
12
|
+
- And another one
|
13
|
+
|
14
|
+
This is a paragraph that talks about a bunch of stuff. It goes on and on
|
15
|
+
for a while.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
I get proper rendering as well.
|
2
|
+
|
3
|
+
Sent from a magnificent torch of pixels
|
4
|
+
|
5
|
+
On Dec 16, 2011, at 12:47 PM, Corey Donohoe
|
6
|
+
<reply@reply.github.com>
|
7
|
+
wrote:
|
8
|
+
|
9
|
+
> Was this caching related or fixed already? I get proper rendering here.
|
10
|
+
>
|
11
|
+
> 
|
12
|
+
>
|
13
|
+
> ---
|
14
|
+
> Reply to this email directly or view it on GitHub:
|
15
|
+
> https://github.com/github/github/issues/2278#issuecomment-3182418
|
metadata
CHANGED
@@ -1,72 +1,61 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: email_reply_parser
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 3
|
8
|
-
- 0
|
9
|
-
version: 0.3.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Rick Olson
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2011-08-23 00:00:00 -07:00
|
18
|
-
default_executable:
|
12
|
+
date: 2012-03-01 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
14
|
description: Long description. Maybe copied from the README.
|
22
15
|
email: technoweenie@gmail.com
|
23
16
|
executables: []
|
24
|
-
|
25
17
|
extensions: []
|
26
|
-
|
27
|
-
extra_rdoc_files:
|
18
|
+
extra_rdoc_files:
|
28
19
|
- README.md
|
29
20
|
- LICENSE
|
30
|
-
files:
|
21
|
+
files:
|
31
22
|
- LICENSE
|
32
23
|
- README.md
|
33
24
|
- Rakefile
|
34
25
|
- email_reply_parser.gemspec
|
35
26
|
- lib/email_reply_parser.rb
|
36
27
|
- test/email_reply_parser_test.rb
|
28
|
+
- test/emails/correct_sig.txt
|
37
29
|
- test/emails/email_1_1.txt
|
38
30
|
- test/emails/email_1_2.txt
|
39
31
|
- test/emails/email_1_3.txt
|
40
32
|
- test/emails/email_1_4.txt
|
41
|
-
|
33
|
+
- test/emails/email_1_5.txt
|
34
|
+
- test/emails/email_1_6.txt
|
42
35
|
homepage: http://github.com/github/email_reply_parser
|
43
36
|
licenses: []
|
44
|
-
|
45
37
|
post_install_message:
|
46
|
-
rdoc_options:
|
38
|
+
rdoc_options:
|
47
39
|
- --charset=UTF-8
|
48
|
-
require_paths:
|
40
|
+
require_paths:
|
49
41
|
- lib
|
50
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
- 0
|
63
|
-
version: "0"
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
64
54
|
requirements: []
|
65
|
-
|
66
55
|
rubyforge_project: email_reply_parser
|
67
|
-
rubygems_version: 1.
|
56
|
+
rubygems_version: 1.8.11
|
68
57
|
signing_key:
|
69
58
|
specification_version: 2
|
70
59
|
summary: Short description used in Gem listings.
|
71
|
-
test_files:
|
60
|
+
test_files:
|
72
61
|
- test/email_reply_parser_test.rb
|