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.
@@ -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.3.0'
17
- s.date = '2011-08-23'
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
 
@@ -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.3.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,4 @@
1
+ this is an email with a correct -- signature.
2
+
3
+ --
4
+ rick
@@ -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
+ > ![](https://img.skitch.com/20111216-m9munqjsy112yqap5cjee5wr6c.jpg)
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
- prerelease: false
5
- segments:
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
- has_rdoc: true
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
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 0
56
- version: "0"
57
- required_rubygems_version: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- segments:
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.3.6
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