exjournal 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Trampoline Systems Ltd
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = exjournal
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to exjournal
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Trampoline Systems Ltd. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
7
+ gem.name = "exjournal"
8
+ gem.homepage = "http://github.com/trampoline/exjournal"
9
+ gem.license = "MIT"
10
+ gem.summary = %Q{extract original messages from Exchange Journal entry messages}
11
+ gem.description = %Q{Exchange journalling wraps emails as a MIME attachment of a journal message. This extracts the original message our of a journal message}
12
+ gem.email = "craig@trampolinesystems.com"
13
+ gem.authors = ["Trampoline Systems Ltd"]
14
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
15
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
16
+ gem.add_dependency "actionmailer", "~> 2.3.10"
17
+ gem.add_development_dependency "rspec", "~> 1.3.0"
18
+ gem.add_development_dependency "jeweler", "~> 1.5.2"
19
+ gem.add_development_dependency "rcov", ">= 0"
20
+ gem.add_development_dependency "rr", ">= 0.10.5"
21
+ end
22
+ Jeweler::RubygemsDotOrgTasks.new
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :default => :spec
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "exjournal #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/exjournal.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'action_mailer'
2
+ require 'tmail'
3
+
4
+ module Exjournal
5
+ module_function
6
+
7
+ # extract the first message/rfc822 attachment from the RFC822 encoded content, and return it as a TMail::Mail
8
+ # if +headers_only+ is true then message content will be discarded, and only headers processed
9
+ def extract_journalled_mail(mail, strip_content=true)
10
+ journal_mail = TMail::Mail.parse(mail) if mail.is_a?(String)
11
+
12
+ # get the attachment
13
+ attachment = journal_mail.parts.select{ |p| p.content_disposition == "attachment" || p.content_type == "message/rfc822" }.first
14
+
15
+ # complain if the email has no attachment to extract
16
+ raise "attempted to extract journalled mail, but message has no attachments: \n#{mail}\n\n" unless attachment
17
+
18
+ mail_content = strip_content ? discard_mail_body(attachment.body) : attachment.body
19
+
20
+ TMail::Mail.parse(mail_content)
21
+ end
22
+
23
+ # discard everything after the first \n\n , i.e. all message body content from an RFC822 encoded mail
24
+ def discard_mail_body(content)
25
+ content.gsub(/^(.*?)\r\n\r\n.*$/m, '\1')
26
+ end
27
+
28
+ # remove angle brackets from a header string
29
+ def strip_header(header)
30
+ header.gsub(/^<(.*)>$/, '\1')
31
+ end
32
+
33
+ def with_headers(headers)
34
+ [*(headers||[])].map{|h| yield h}
35
+ end
36
+
37
+ # remove angle brackets from one or more headers
38
+ def strip_headers(headers)
39
+ with_headers(headers){|h| strip_header(h)}
40
+ end
41
+
42
+ # parse an address to a hash
43
+ def parse_address(address)
44
+ address = TMail::Address.parse(address) if address.is_a?(String)
45
+ {:name=>address.name, :address=>address.address}
46
+ end
47
+
48
+ # parse one or more addresses to hash
49
+ def parse_addresses(addresses)
50
+ [*(addresses||[])].map{|a| parse_address(a)}
51
+ end
52
+
53
+ # turn a TMail::Mail into a has suitable for JSON representation
54
+ def mail_to_hash(mail, strip_content=true)
55
+ mail = TMail::Mail.parse(mail) if mail.is_a?(String)
56
+
57
+ message_id = strip_header(mail.message_id) if mail.message_id
58
+ sent_at = mail.date.xmlschema
59
+ in_reply_to = strip_headers(mail.in_reply_to) if mail.in_reply_to
60
+ references = strip_headers(mail.references) if mail.references
61
+ from = parse_addresses(mail.from_addrs).first
62
+ to = parse_addresses(mail.to_addrs)
63
+ cc=parse_addresses(mail.cc_addrs)
64
+ bcc=parse_addresses(mail.bcc_addrs)
65
+
66
+ h = {
67
+ :message_id=>message_id,
68
+ :sent_at=>sent_at,
69
+ :in_reply_to=>in_reply_to,
70
+ :references=>references,
71
+ :from=>from,
72
+ :to=>to,
73
+ :cc=>cc,
74
+ :bcc=>bcc
75
+ }
76
+
77
+ if !strip_content
78
+ h[:subject] = mail.subject
79
+ end
80
+
81
+ h
82
+ end
83
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Exjournal" do
4
+ describe "extract_journalled_mail" do
5
+ it "should extract the first message/rfc822 attachment without content" do
6
+ s=File.read(File.expand_path("../fixtures/email_with_email_attachment.eml", __FILE__))
7
+ jm = Exjournal.extract_journalled_mail(s)
8
+ jm.message_id.should == "<0FDFBAF6-0960-40FB-B730-B0C7C3299948@empire42.com>"
9
+ jm.body.should =~ /\s*/
10
+ end
11
+
12
+ it "should extract the first message/rfc822 attachment with content" do
13
+ s=File.read(File.expand_path("../fixtures/email_with_email_attachment.eml", __FILE__))
14
+ jm = Exjournal.extract_journalled_mail(s, false)
15
+ jm.message_id.should == "<0FDFBAF6-0960-40FB-B730-B0C7C3299948@empire42.com>"
16
+ jm.body.should !~ /\s*/
17
+ end
18
+
19
+ it "should raise if there is no message/rfc822 attachment" do
20
+ s=File.read(File.expand_path("../fixtures/email_without_attachment.eml", __FILE__))
21
+ lambda{
22
+ Exjournal.extract_journalled_mail(s)
23
+ }.should raise_error(/has no attachments/)
24
+ end
25
+ end
26
+
27
+ describe "discard_mail_body" do
28
+ it "should discard everything after \r\n\r\n" do
29
+ s=<<-EOF
30
+ From: foo@bar.com\r
31
+ To: baz@boo.com\r
32
+ Subject: i can't tell you\r
33
+ \r
34
+ because it's a secret\r
35
+ EOF
36
+ Exjournal.discard_mail_body(s).should =~ /^From: foo@bar.com.*tell you$/m
37
+ end
38
+
39
+ it "should do nothing if no \r\n\r\n" do
40
+ s=<<-EOF
41
+ From: foo@bar.com\r
42
+ To: baz@boo.com\r
43
+ Subject: i can't tell you
44
+ EOF
45
+ Exjournal.discard_mail_body(s).should == s
46
+ end
47
+ end
48
+
49
+ describe "strip_header" do
50
+ it "should strip angle brackets if present" do
51
+ Exjournal.strip_header("<foo>").should == "foo"
52
+ end
53
+
54
+ it "should do nothing if no angle brackets" do
55
+ Exjournal.strip_header("foo").should == "foo"
56
+ end
57
+ end
58
+
59
+ describe "strip_headers" do
60
+ it "should strip_header from a single header" do
61
+ Exjournal.strip_headers("<foo>").should == ["foo"]
62
+ end
63
+
64
+ it "should strip_header from more than one header" do
65
+ Exjournal.strip_headers(["<foo>", "<bar>"]).should == ["foo", "bar"]
66
+ end
67
+ end
68
+
69
+ describe "parse_address" do
70
+ it "should extract a hash from an address" do
71
+ h = Exjournal.parse_address(TMail::Address.parse('"foo mcfoo" <foo@bar.com>'))
72
+ h.should == {:name=>"foo mcfoo", :address=>"foo@bar.com"}
73
+ end
74
+ end
75
+
76
+ describe "parse_addresses" do
77
+ it "should extract a hash from a single address" do
78
+ h = Exjournal.parse_addresses(TMail::Address.parse('"foo mcfoo" <foo@bar.com>'))
79
+ h.should == [{:name=>"foo mcfoo", :address=>"foo@bar.com"}]
80
+ end
81
+
82
+ it "should extract hashes from more than one address" do
83
+ h = Exjournal.parse_addresses([TMail::Address.parse('"foo mcfoo" <foo@bar.com>'),
84
+ TMail::Address.parse('"baz mcbaz" <baz@boo.com>')])
85
+ h.should == [{:name=>"foo mcfoo", :address=>"foo@bar.com"},
86
+ {:name=>"baz mcbaz", :address=>"baz@boo.com"}]
87
+ end
88
+ end
89
+
90
+ describe "mail_to_hash" do
91
+ it "should turn a mail to json excluding subject" do
92
+ s=File.read(File.expand_path("../fixtures/email_with_references.eml", __FILE__))
93
+ h = Exjournal.mail_to_hash(s)
94
+
95
+ h[:message_id].should == "B63CAA43-F378-4033-BA8B-ED408805B5B5@empire42.com"
96
+ h[:sent_at].should == DateTime.parse('Wed, 21 Apr 2010 14:43:24 +0100').xmlschema
97
+ h[:in_reply_to].should == ["B63CAA43-F378-4033-BA8B-foo@empire42.com"]
98
+ h[:references].should == ["B63CAA43-F378-4033-BA8B-foo@empire42.com",
99
+ "B63CAA43-F378-4033-BA8B-bar@empire42.com",
100
+ "B63CAA43-F378-4033-BA8B-baz@empire42.com"]
101
+ h[:from].should == {:name=>"Peter MacRobert", :address=>"peter.macrobert@empire42.com"}
102
+ h[:to].should == [{:name=>nil, :address=>"foo@bar.com"},
103
+ {:name=>"bar mcbar", :address=>"bar.mcbar@bar.com"}]
104
+ h[:cc].should == []
105
+ h[:bcc].should == []
106
+ h[:subject].should == nil
107
+ end
108
+
109
+ it "should turn a mail to json including subject" do
110
+ s=File.read(File.expand_path("../fixtures/email_with_references.eml", __FILE__))
111
+ h = Exjournal.mail_to_hash(s, false)
112
+
113
+ h[:message_id].should == "B63CAA43-F378-4033-BA8B-ED408805B5B5@empire42.com"
114
+ h[:sent_at].should == DateTime.parse('Wed, 21 Apr 2010 14:43:24 +0100').xmlschema
115
+ h[:in_reply_to].should == ["B63CAA43-F378-4033-BA8B-foo@empire42.com"]
116
+ h[:references].should == ["B63CAA43-F378-4033-BA8B-foo@empire42.com",
117
+ "B63CAA43-F378-4033-BA8B-bar@empire42.com",
118
+ "B63CAA43-F378-4033-BA8B-baz@empire42.com"]
119
+ h[:from].should == {:name=>"Peter MacRobert", :address=>"peter.macrobert@empire42.com"}
120
+ h[:to].should == [{:name=>nil, :address=>"foo@bar.com"},
121
+ {:name=>"bar mcbar", :address=>"bar.mcbar@bar.com"}]
122
+ h[:cc].should == []
123
+ h[:bcc].should == []
124
+ h[:subject].should == "Test email"
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,52 @@
1
+ Subject: Top-level email
2
+ Mime-Version: 1.0 (Apple Message framework v1078)
3
+ Content-Type: multipart/related;
4
+ type="text/html";
5
+ boundary=Apple-Mail-1--656091021
6
+ X-Apple-Base-Url: x-msg://3/
7
+ X-Universally-Unique-Identifier: 505346e8-98bc-41b0-95a2-0f60a22e4589
8
+ X-Apple-Mail-Remote-Attachments: YES
9
+ From: Peter MacRobert <peter.macrobert@empire42.com>
10
+ X-Apple-Windows-Friendly: 1
11
+ Date: Wed, 21 Apr 2010 14:26:08 +0100
12
+ X-Apple-Mail-Signature:
13
+ Message-Id: <6612CEDB-F33D-4588-83C5-AFB2B28FD85A@empire42.com>
14
+ X-Uniform-Type-Identifier: com.apple.mail-draft
15
+ To: foo2@example.com
16
+
17
+
18
+ --Apple-Mail-1--656091021
19
+ Content-Transfer-Encoding: 7bit
20
+ Content-Type: text/html;
21
+ charset=us-ascii
22
+
23
+ <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">This is the main email content. This email has an attachment which is another email.<div><object type="application/x-apple-msg-attachment" data="cid:93E2F850-5D35-4619-87A1-469BB289F188@snowdonia.trampolinesystems.com" id="eee2d418-5b17-4488-8c96-f9d1fcad486c" height="46" width="150" apple-width="yes" apple-height="yes"></object></div></body></html>
24
+ --Apple-Mail-1--656091021
25
+ Content-Transfer-Encoding: 7bit
26
+ Content-Disposition: attachment;
27
+ filename="This is an attachment"
28
+ Content-Type: message/rfc822;
29
+ x-mac-hide-extension=yes;
30
+ x-unix-mode=0666;
31
+ name="This is an attachment"
32
+ Content-Id: <93E2F850-5D35-4619-87A1-469BB289F188@snowdonia.trampolinesystems.com>
33
+
34
+ Subject: This is an attachment
35
+ Mime-Version: 1.0 (Apple Message framework v1078)
36
+ Content-Type: text/html;
37
+ charset=us-ascii
38
+ X-Apple-Base-Url: x-msg://1/
39
+ X-Universally-Unique-Identifier: c7cc15b2-7186-4f82-9936-894288fe9450
40
+ X-Apple-Mail-Remote-Attachments: YES
41
+ From: Peter MacRobert <peter.macrobert@empire42.com>
42
+ X-Apple-Windows-Friendly: 1
43
+ Date: Wed, 21 Apr 2010 14:25:01 +0100
44
+ X-Apple-Mail-Signature:
45
+ Content-Transfer-Encoding: 7bit
46
+ Message-Id: <0FDFBAF6-0960-40FB-B730-B0C7C3299948@empire42.com>
47
+ X-Uniform-Type-Identifier: com.apple.mail-draft
48
+ To: foo@bar.com
49
+
50
+ <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Attached email.</body></html>
51
+
52
+ --Apple-Mail-1--656091021--
@@ -0,0 +1,20 @@
1
+ Subject: Test email
2
+ Mime-Version: 1.0 (Apple Message framework v1078)
3
+ Content-Type: text/html;
4
+ charset=us-ascii
5
+ X-Apple-Base-Url: x-msg://1/
6
+ X-Universally-Unique-Identifier: c7cc15b2-7186-4f82-9936-894288fe9450
7
+ X-Apple-Mail-Remote-Attachments: YES
8
+ From: Peter MacRobert <peter.macrobert@empire42.com>
9
+ X-Apple-Windows-Friendly: 1
10
+ Date: Wed, 21 Apr 2010 14:43:24 +0100
11
+ Content-Transfer-Encoding: 7bit
12
+ Message-Id: <B63CAA43-F378-4033-BA8B-ED408805B5B5@empire42.com>
13
+ In-Reply-To: <B63CAA43-F378-4033-BA8B-foo@empire42.com>
14
+ References: <B63CAA43-F378-4033-BA8B-foo@empire42.com>
15
+ <B63CAA43-F378-4033-BA8B-bar@empire42.com>
16
+ <B63CAA43-F378-4033-BA8B-baz@empire42.com>
17
+ X-Uniform-Type-Identifier: com.apple.mail-draft
18
+ To: foo@bar.com, "bar mcbar" <bar.mcbar@bar.com>
19
+
20
+ <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Plain email with no attachments.</body></html>
@@ -0,0 +1,16 @@
1
+ Subject: Test email
2
+ Mime-Version: 1.0 (Apple Message framework v1078)
3
+ Content-Type: text/html;
4
+ charset=us-ascii
5
+ X-Apple-Base-Url: x-msg://1/
6
+ X-Universally-Unique-Identifier: c7cc15b2-7186-4f82-9936-894288fe9450
7
+ X-Apple-Mail-Remote-Attachments: YES
8
+ From: Peter MacRobert <peter.macrobert@empire42.com>
9
+ X-Apple-Windows-Friendly: 1
10
+ Date: Wed, 21 Apr 2010 14:43:24 +0100
11
+ Content-Transfer-Encoding: 7bit
12
+ Message-Id: <B63CAA43-F378-4033-BA8B-ED408805B5B5@empire42.com>
13
+ X-Uniform-Type-Identifier: com.apple.mail-draft
14
+ To: foo@bar.com
15
+
16
+ <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Plain email with no attachments.</body></html>
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rubygems'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'rr'
7
+ require 'exjournal'
8
+
9
+ # Requires supporting files with custom matchers and macros, etc,
10
+ # in ./support/ and its subdirectories.
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12
+
13
+ Spec::Runner.configure do |config|
14
+ config.mock_with RR::Adapters::Rspec
15
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exjournal
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Trampoline Systems Ltd
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-23 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: actionmailer
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 10
34
+ version: 2.3.10
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 1
48
+ - 3
49
+ - 0
50
+ version: 1.3.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: jeweler
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 7
62
+ segments:
63
+ - 1
64
+ - 5
65
+ - 2
66
+ version: 1.5.2
67
+ type: :development
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: rcov
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ type: :development
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ name: rr
85
+ prerelease: false
86
+ requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 61
92
+ segments:
93
+ - 0
94
+ - 10
95
+ - 5
96
+ version: 0.10.5
97
+ type: :development
98
+ version_requirements: *id005
99
+ description: Exchange journalling wraps emails as a MIME attachment of a journal message. This extracts the original message our of a journal message
100
+ email: craig@trampolinesystems.com
101
+ executables: []
102
+
103
+ extensions: []
104
+
105
+ extra_rdoc_files:
106
+ - LICENSE.txt
107
+ - README.rdoc
108
+ files:
109
+ - .document
110
+ - .rspec
111
+ - LICENSE.txt
112
+ - README.rdoc
113
+ - Rakefile
114
+ - VERSION
115
+ - lib/exjournal.rb
116
+ - spec/exjournal_spec.rb
117
+ - spec/fixtures/email_with_email_attachment.eml
118
+ - spec/fixtures/email_with_references.eml
119
+ - spec/fixtures/email_without_attachment.eml
120
+ - spec/spec_helper.rb
121
+ has_rdoc: true
122
+ homepage: http://github.com/trampoline/exjournal
123
+ licenses:
124
+ - MIT
125
+ post_install_message:
126
+ rdoc_options: []
127
+
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ hash: 3
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ requirements: []
149
+
150
+ rubyforge_project:
151
+ rubygems_version: 1.6.2
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: extract original messages from Exchange Journal entry messages
155
+ test_files:
156
+ - spec/exjournal_spec.rb
157
+ - spec/spec_helper.rb