bodyparts 0.1.1 → 0.1.2
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/README.rdoc +1 -1
- data/VERSION +1 -1
- data/bodyparts.gemspec +2 -2
- data/lib/bodyparts.rb +36 -23
- data/spec/bodyparts_spec.rb +12 -3
- data/spec/spec_helper.rb +15 -4
- metadata +3 -3
data/README.rdoc
CHANGED
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.2
|
data/bodyparts.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{bodyparts}
|
|
8
|
-
s.version = "0.1.
|
|
8
|
+
s.version = "0.1.2"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Max Ogden"]
|
|
12
|
-
s.date = %q{2010-06-
|
|
12
|
+
s.date = %q{2010-06-10}
|
|
13
13
|
s.description = %q{Separates new messages from included reply chains in the body of forwarded emails}
|
|
14
14
|
s.email = %q{max@maxogden.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/bodyparts.rb
CHANGED
|
@@ -1,32 +1,45 @@
|
|
|
1
1
|
require 'mail'
|
|
2
|
+
require 'tmail'
|
|
2
3
|
|
|
3
4
|
class BodyParts
|
|
4
|
-
def self.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
def self.rules
|
|
6
|
+
[{ :server => 'Gmail', :reply_delimiter => /^On.*?wrote:.$/m },
|
|
7
|
+
{ :server => 'Yahoo! Mail', :reply_delimiter => /^_+\r\nFrom:/ },
|
|
8
|
+
{ :server => 'Microsoft Live Mail/Hotmail', :reply_delimiter => /\r\n\r\n(Date|Subject):/ },
|
|
9
|
+
{ :server => 'Outlook Express/AOL Webmail', :reply_delimiter => /^-+.*Original Message.*-+/ }]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.extract_tmail_attributes(tmail_object)
|
|
13
|
+
message_id = tmail_object.message_id
|
|
14
|
+
x_mailer = tmail_object['x-mailer'].to_s
|
|
15
|
+
body = if tmail_object.multipart?
|
|
16
|
+
tmail_object.parts.first.body
|
|
17
|
+
else
|
|
18
|
+
tmail_object.body
|
|
19
|
+
end
|
|
20
|
+
{:message_id => message_id, :x_mailer => x_mailer, :body => body}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.extract_mail_attributes(mail_object)
|
|
24
|
+
message_id = mail_object['message_id']
|
|
25
|
+
x_mailer = mail_object['x-mailer']
|
|
23
26
|
|
|
24
|
-
if
|
|
25
|
-
body =
|
|
27
|
+
if mail_object.multipart?
|
|
28
|
+
body = mail_object.parts.first.body.raw_source
|
|
26
29
|
else
|
|
27
|
-
body =
|
|
30
|
+
body = mail_object.body.raw_source
|
|
31
|
+
end
|
|
32
|
+
{:message_id => message_id, :x_mailer => x_mailer, :body => body}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.find_reply_in(email)
|
|
36
|
+
email = Mail::Message.new(email) if email.is_a? String
|
|
37
|
+
mail_attributes = case email.class.to_s
|
|
38
|
+
when "TMail::Mail" then extract_tmail_attributes(email)
|
|
39
|
+
when "Mail::Message" then extract_mail_attributes(email)
|
|
40
|
+
else raise "You must pass in either a TMail or Mail object or raw email source text"
|
|
28
41
|
end
|
|
29
|
-
|
|
42
|
+
body = mail_attributes[:body]
|
|
30
43
|
matches = rules.map {|rule| body.match(rule[:reply_delimiter])}.compact!
|
|
31
44
|
unless matches.empty?
|
|
32
45
|
match = matches.sort_by {|m| m.begin(0)}.first
|
data/spec/bodyparts_spec.rb
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
|
3
3
|
describe "BodyParts" do
|
|
4
|
+
|
|
5
|
+
[TMail::Mail, Mail].each do |mail_object|
|
|
6
|
+
it "should accept and parse #{mail_object} objects as input" do
|
|
7
|
+
generic = FakeMessage.fake_emails[:generic]
|
|
8
|
+
message = FakeMessage.new_mail(mail_object, generic[:headers])
|
|
9
|
+
BodyParts.find_reply_in(message)[:new_message].should == generic[:reply_text]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
4
13
|
%w(gmail yahoo hotmail aol_webmail generic).each do |mail_server|
|
|
5
14
|
it "should strip out the replies from a #{mail_server} message containing forwarded junk" do
|
|
6
15
|
mail_server = FakeMessage.fake_emails[mail_server.to_sym]
|
|
7
|
-
message = FakeMessage.new_mail(mail_server[:headers])
|
|
16
|
+
message = FakeMessage.new_mail(Mail, mail_server[:headers])
|
|
8
17
|
BodyParts.find_reply_in(message.to_s)[:new_message].should == mail_server[:reply_text]
|
|
9
18
|
end
|
|
10
19
|
end
|
|
11
20
|
|
|
12
21
|
it "should always use the first reply delimiter in a message containing multiple replies" do
|
|
13
22
|
multiple_replies = FakeMessage.fake_emails[:multiple_replies]
|
|
14
|
-
message = FakeMessage.new_mail(multiple_replies[:headers])
|
|
23
|
+
message = FakeMessage.new_mail(Mail, multiple_replies[:headers])
|
|
15
24
|
BodyParts.find_reply_in(message.to_s)[:new_message].should == multiple_replies[:reply_text]
|
|
16
25
|
end
|
|
17
26
|
|
|
18
27
|
it "should return the rest of the thread" do
|
|
19
28
|
generic = FakeMessage.fake_emails[:generic]
|
|
20
|
-
message = FakeMessage.new_mail(generic[:headers])
|
|
29
|
+
message = FakeMessage.new_mail(Mail, generic[:headers])
|
|
21
30
|
BodyParts.find_reply_in(message.to_s).should == {:new_message => generic[:reply_text], :rest_of_thread => generic[:rest_of_thread].gsub("\n", "\r\n").strip}
|
|
22
31
|
end
|
|
23
32
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -16,13 +16,24 @@ class FakeMessage
|
|
|
16
16
|
}
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def self.new_mail(custom_headers={})
|
|
19
|
+
def self.new_mail(mail_class, custom_headers={})
|
|
20
20
|
headers = default_mail_headers.merge(custom_headers)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
|
|
22
|
+
mail = mail_class.new do
|
|
23
|
+
if mail_class == Mail
|
|
24
|
+
text_part do
|
|
25
|
+
body headers.delete("body")
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
29
|
+
|
|
30
|
+
if mail_class == TMail::Mail
|
|
31
|
+
%w(body from to).each do |attr|
|
|
32
|
+
mail.send "#{attr}=", headers[attr]
|
|
33
|
+
headers.delete attr
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
26
37
|
headers.each {|header, content| mail[header] = content }
|
|
27
38
|
mail
|
|
28
39
|
end
|
metadata
CHANGED
|
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
7
|
- 1
|
|
8
|
-
-
|
|
9
|
-
version: 0.1.
|
|
8
|
+
- 2
|
|
9
|
+
version: 0.1.2
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Max Ogden
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2010-06-
|
|
17
|
+
date: 2010-06-10 00:00:00 -07:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|