email_nugget_rb 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.3.0"
10
+ gem "yard", "~> 0.6.0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.6.4"
13
+ end
14
+
15
+ gem "uuid"
16
+ gem "json"
@@ -0,0 +1,36 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ git (1.2.5)
6
+ jeweler (1.6.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ json (1.6.6)
11
+ macaddr (1.5.0)
12
+ systemu (>= 2.4.0)
13
+ rake (0.9.2.2)
14
+ rspec (2.3.0)
15
+ rspec-core (~> 2.3.0)
16
+ rspec-expectations (~> 2.3.0)
17
+ rspec-mocks (~> 2.3.0)
18
+ rspec-core (2.3.1)
19
+ rspec-expectations (2.3.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.3.0)
22
+ systemu (2.5.0)
23
+ uuid (2.3.5)
24
+ macaddr (~> 1.0)
25
+ yard (0.6.8)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ bundler (~> 1.0.0)
32
+ jeweler (~> 1.6.4)
33
+ json
34
+ rspec (~> 2.3.0)
35
+ uuid
36
+ yard (~> 0.6.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Jon Durbin
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.
@@ -0,0 +1,19 @@
1
+ = email_nugget_rb
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to email_nugget_rb
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) 2012 Jon Durbin. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "email_nugget_rb"
18
+ gem.homepage = "http://github.com/gdi/email_nugget_rb"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Save email envelope and message in single data format.}
21
+ gem.description = %Q{Save email envelope and message in a single data format.}
22
+ gem.email = "development@greenviewdata.com"
23
+ gem.authors = ["Jon Durbin"]
24
+ gem.version = "0.0.3"
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+ RSpec::Core::RakeTask.new(:spec) do |spec|
32
+ spec.pattern = FileList['spec/**/*_spec.rb']
33
+ end
34
+
35
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'yard'
43
+ YARD::Rake::YardocTask.new
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'uuid'
3
+ require 'json'
4
+
5
+ class EmailNugget
6
+ autoload "Envelope", "email_nugget/envelope"
7
+ autoload "Message", "email_nugget/message"
8
+
9
+ attr_accessor :id, :envelope, :message
10
+
11
+ # Initialize a new email nugget.
12
+ def initialize(args = {})
13
+ self.envelope = EmailNugget::Envelope.new(args[:envelope] || args['envelope'])
14
+ self.message = EmailNugget::Message.new(args[:message] || args['message'])
15
+ self.id = args[:id] || args['id'] || generate_id
16
+ end
17
+
18
+ # Generate a new UUID
19
+ def generate_id
20
+ UUID.new.generate
21
+ end
22
+
23
+ def to_hash
24
+ {
25
+ :ip => self.envelope.ip,
26
+ :helo => self.envelope.helo,
27
+ :mail_from => self.envelope.mail_from,
28
+ :rcpt_to => self.envelope.rcpt_to,
29
+ :date => self.envelope.date,
30
+ :context => self.envelope.context,
31
+ :misc => self.envelope.misc,
32
+ }
33
+ end
34
+
35
+ # Save the current nugget to the specified file.
36
+ def write_to(file_path)
37
+ # Catch any errors opening or writing to the file.
38
+ begin
39
+ nugget_file = File.open(file_path, "w")
40
+ # Get a lock on the file.
41
+ nugget_file.flock(File::LOCK_EX | File::LOCK_NB)
42
+ # Save the envelope as JSON in the first line.
43
+ nugget_file.syswrite(to_hash.to_json + "\n")
44
+ # Save the checksum in the second line.
45
+ nugget_file.syswrite(self.message.checksum + "\n")
46
+ # Save the message contents after the second line.
47
+ nugget_file.syswrite(self.message.data + "\n")
48
+ rescue => e
49
+ # Unable to save email nugget to file_path
50
+ #puts "Error saving email nugget to #{file_path}: #{e.to_s}"
51
+ return false
52
+ end
53
+ # Success
54
+ return true
55
+ end
56
+
57
+ class << self
58
+ # Create a new email nugget from the specified file path.
59
+ def new_from(file_path)
60
+ # Catch any errors opening or reading from the file.
61
+ begin
62
+ nugget_file = File.open(file_path, 'rb')
63
+ # Envelope is the first line.
64
+ envelope = JSON.parse(nugget_file.readline.chomp)
65
+ # Checksum is the second line.
66
+ checksum = nugget_file.readline.chomp
67
+ return EmailNugget.new({'envelope' => envelope, 'message' => {'data_stream' => nugget_file}})
68
+ rescue => e
69
+ # Unable to open or read nugget file.
70
+ #puts "Error creating email nugget from #{file_path}: #{e.to_s}"
71
+ return nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ class EmailNugget
2
+ class Envelope
3
+ attr_accessor :ip, :helo, :mail_from, :rcpt_to, :date, :context, :misc
4
+
5
+ def initialize(args = {})
6
+ self.ip = args[:ip] || args['ip'] || ""
7
+ self.helo = args[:helo] || args['helo'] || ""
8
+ self.mail_from = args[:mail_from] || args['mail_from'] || ""
9
+ self.rcpt_to = args[:rcpt_to] || args['rcpt_to'] || []
10
+ self.date = args[:date] || args['date'] || ""
11
+ self.context = args[:context] || args['context'] || ""
12
+ self.misc = args[:misc] || args['misc'] || {}
13
+ self.ensure_fields
14
+ end
15
+
16
+ def ensure_fields
17
+ if !self.rcpt_to.is_a?(Array)
18
+ self.rcpt_to = [self.rcpt_to]
19
+ end
20
+
21
+ if !self.misc.is_a?(Hash)
22
+ if self.misc.is_a?(Array)
23
+ temp = {}
24
+ self.misc.each do |m|
25
+ temp[m] = 1
26
+ end
27
+ self.misc = temp
28
+ elsif self.misc.is_a?(String) || self.misc.is_a?(Integer)
29
+ temp = {self.misc => 1}
30
+ self.misc = temp
31
+ else
32
+ self.misc = {}
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ require 'digest/md5'
2
+
3
+ class EmailNugget
4
+ class Message
5
+ attr_accessor :arg_checksum, :arg_data, :arg_data_stream
6
+
7
+ def initialize(args = {})
8
+ self.arg_checksum = args[:checksum] || args['checksum']
9
+ self.arg_data = args[:data] || args['data']
10
+ self.arg_data_stream = args[:data_stream] || args['data_stream']
11
+ end
12
+
13
+ def data_stream
14
+ if self.arg_data_stream
15
+ self.arg_data_stream
16
+ else
17
+ StringIO.new(self.data)
18
+ end
19
+ end
20
+
21
+ def data
22
+ if self.arg_data.nil?
23
+ self.arg_data = self.arg_data_stream.read
24
+ end
25
+ self.arg_data
26
+ end
27
+
28
+ def checksum
29
+ if self.arg_checksum.nil?
30
+ Digest::MD5.hexdigest(self.data)
31
+ else
32
+ self.arg_checksum
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1 @@
1
+ require 'email_nugget'
@@ -0,0 +1,7 @@
1
+ {"ip":"127.0.0.1","helo":"test.com","mail_from":"test@test.com","rcpt_to":"test@test.com","date":"2012-01-16 14:55:52 -0500","context":"inbound","misc":{"message_id" : "123456789"}}
2
+ a68a72d5abdb040c7b279c707ed5477e
3
+ From: "test" <test@test.com>
4
+ To: "test" <test@test.com>
5
+ Subject: Test nugget.
6
+
7
+ Test nugget 1.
@@ -0,0 +1,3 @@
1
+ {"ip":"127.0.0.1","helo":"test.com","mail_from":"test@test.com","rcpt_to":["test@test.com"],"date":"2012-03-26 16:29:26 -0400","context":"inbound","misc":{}}
2
+ 7df477726f7d2673a018d1789af53e24
3
+ Test write nugget.
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe EmailNugget::Envelope do
4
+ before do
5
+ @current_time = Time.now
6
+ @test_envelope_hash = {
7
+ 'ip' => '127.0.0.1',
8
+ 'helo' => 'localhost.localdomain',
9
+ 'mail_from' => 'root@localhost',
10
+ 'rcpt_to' => 'root@localhost',
11
+ 'date' => @current_time.to_s,
12
+ 'context' => 'inbound'
13
+ }
14
+ @envelope = EmailNugget::Envelope.new(@test_envelope_hash)
15
+ end
16
+
17
+ describe '.new' do
18
+ it "should create an email nugget envelope from a hash" do
19
+ @envelope.should be_a_kind_of(EmailNugget::Envelope)
20
+ end
21
+ it "should return empty string for fields not set in initialize" do
22
+ with_nil_params = {
23
+ 'ip' => '127.0.0.1',
24
+ 'rcpt_to' => 'root@localhost'
25
+ }
26
+ test_envelope = EmailNugget::Envelope.new(with_nil_params)
27
+ test_envelope.mail_from.should == ""
28
+ end
29
+ end
30
+
31
+ describe '#ip' do
32
+ it "should return the sender IP address" do
33
+ @envelope.ip.should == @test_envelope_hash['ip']
34
+ end
35
+ end
36
+
37
+ describe '#helo' do
38
+ it "should return the helo host" do
39
+ @envelope.helo.should == @test_envelope_hash['helo']
40
+ end
41
+ end
42
+
43
+ describe '#mail_from' do
44
+ it "should return the mail_from" do
45
+ @envelope.mail_from.should == @test_envelope_hash['mail_from']
46
+ end
47
+ end
48
+
49
+ describe '#rcpt_to' do
50
+ it "should return the rcpt_to array" do
51
+ @envelope.rcpt_to.should be_a_kind_of(Array)
52
+ end
53
+ it "should contain the first rcpt_to in the first array item" do
54
+ @envelope.rcpt_to[0].should == @test_envelope_hash['rcpt_to']
55
+ end
56
+ it "should be the same size as the input hash recipient array" do
57
+ multiple_rcpt = @test_envelope_hash
58
+ multiple_rcpt['rcpt_to'] = ["rcpt1@test.com", "rcpt2@test.com"]
59
+ test_envelope = EmailNugget::Envelope.new(multiple_rcpt)
60
+ test_envelope.rcpt_to.length.should == multiple_rcpt['rcpt_to'].length
61
+ end
62
+ end
63
+
64
+ describe '#date' do
65
+ it "should return the date" do
66
+ @envelope.date.should == @test_envelope_hash['date']
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe EmailNugget::Message do
4
+ before do
5
+ @test_message_hash = {
6
+ 'data' => 'This is a test message',
7
+ 'checksum' => Digest::MD5.hexdigest('This is a test message')
8
+ }
9
+ @message = EmailNugget::Message.new(@test_message_hash)
10
+ end
11
+
12
+ describe '.new' do
13
+ it "should create an email nugget message from a hash" do
14
+ @message.should be_a_kind_of(EmailNugget::Message)
15
+ end
16
+ end
17
+
18
+ describe '#checksum' do
19
+ it "should return the checksum of the data" do
20
+ @message.checksum.should == Digest::MD5.hexdigest(@test_message_hash['data'])
21
+ end
22
+ it "should return the checksum of the data if not provided" do
23
+ test_message = EmailNugget::Message.new({'data' => 'test'})
24
+ test_message.checksum.should == Digest::MD5.hexdigest('test')
25
+ end
26
+ end
27
+
28
+ describe '#data' do
29
+ it "should return the data provided in the message hash" do
30
+ @message.data.should == @test_message_hash['data']
31
+ end
32
+ end
33
+
34
+ describe '#data_stream' do
35
+ before do
36
+ @f = File.open(File.dirname(__FILE__) + '/../../fixtures/test1.nugget', 'r')
37
+ @f.readline
38
+ @checksum = @f.readline
39
+ @test_message = EmailNugget::Message.new({'data_stream' => @f, 'checksum' => @checksum})
40
+ end
41
+ it "should return a StringIO to the data string" do
42
+ @message.data_stream.should be_a_kind_of(StringIO)
43
+ end
44
+ it "should return a FileIO if data stream is provided" do
45
+ @test_message.should be_a_kind_of(EmailNugget::Message)
46
+ end
47
+ it "should return a string calling the data method when provide a data stream" do
48
+ @test_message.data.should be_a_kind_of(String)
49
+ end
50
+ it "should return the argument checksum" do
51
+ @test_message.checksum.should == @checksum
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe EmailNugget do
4
+ before do
5
+ @current_time = Time.now
6
+ @test_email_hash = {
7
+ 'envelope' => {
8
+ 'mail_from' => 'test@test.com',
9
+ 'helo' => 'test.com',
10
+ 'rcpt_to' => 'test@test.com',
11
+ 'ip' => '127.0.0.1',
12
+ 'date' => @current_time.to_s,
13
+ 'context' => 'inbound',
14
+ 'misc' => {'message_id' => '123456'},
15
+ },
16
+ 'message' => {
17
+ 'data' => 'Test write nugget.',
18
+ 'checksum' => Digest::MD5.hexdigest('Test write nugget.')
19
+ }
20
+ }
21
+ @nugget = EmailNugget.new(@test_email_hash)
22
+ end
23
+ #
24
+ describe '.new' do
25
+ it "should create a nugget from a hash" do
26
+ @nugget.should be_a_kind_of(EmailNugget)
27
+ end
28
+ end
29
+
30
+ describe '#envelope' do
31
+ it "should initialize the envelope from the hash" do
32
+ @nugget.envelope.should be_a_kind_of(EmailNugget::Envelope)
33
+ end
34
+ end
35
+
36
+ describe '#message' do
37
+ it "should initialize the message from the hash" do
38
+ @nugget.message.should be_a_kind_of(EmailNugget::Message)
39
+ end
40
+ end
41
+
42
+ describe '#id' do
43
+ it "should generate an ID if none is given" do
44
+ @nugget.id.should_not be_nil
45
+ end
46
+ it "should use the ID given in the hash" do
47
+ @test_email_hash['id'] = "asdf"
48
+ test_nugget = EmailNugget.new(@test_email_hash)
49
+ test_nugget.id.should == "asdf"
50
+ end
51
+ end
52
+
53
+ describe '.write_to()' do
54
+ it "should write the current nugget to the specified file" do
55
+ @nugget.write_to(File.dirname(__FILE__) + '/../fixtures/test2.nugget').should == true
56
+ end
57
+ it "should return false if write failed" do
58
+ @nugget.write_to("/a/a/a/a/bad_path_to.nugget").should == false
59
+ end
60
+ end
61
+
62
+ describe '.new_from()' do
63
+ it "should create a new nugget from the file path" do
64
+ nugget = EmailNugget.new_from(File.dirname(__FILE__) + '/../fixtures/test1.nugget')
65
+ nugget.should be_a_kind_of(EmailNugget)
66
+ end
67
+ it "should return nil if the nugget file path doesn't exist" do
68
+ nugget = EmailNugget.new_from("/a/a/a/a/bad_path_to.nugget")
69
+ nugget.should be_nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'email_nugget_rb'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: email_nugget_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Durbin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: uuid
16
+ requirement: &70342398812280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70342398812280
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &70342398811640 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70342398811640
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70342398810880 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.3.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70342398810880
47
+ - !ruby/object:Gem::Dependency
48
+ name: yard
49
+ requirement: &70342398810160 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70342398810160
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &70342398809420 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70342398809420
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &70342398829440 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.6.4
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70342398829440
80
+ description: Save email envelope and message in a single data format.
81
+ email: development@greenviewdata.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files:
85
+ - LICENSE.txt
86
+ - README.rdoc
87
+ files:
88
+ - .document
89
+ - .rspec
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - LICENSE.txt
93
+ - README.rdoc
94
+ - Rakefile
95
+ - lib/email_nugget.rb
96
+ - lib/email_nugget/envelope.rb
97
+ - lib/email_nugget/message.rb
98
+ - lib/email_nugget_rb.rb
99
+ - spec/fixtures/test1.nugget
100
+ - spec/fixtures/test2.nugget
101
+ - spec/lib/email_nugget/envelope_spec.rb
102
+ - spec/lib/email_nugget/message_spec.rb
103
+ - spec/lib/email_nugget_spec.rb
104
+ - spec/spec_helper.rb
105
+ homepage: http://github.com/gdi/email_nugget_rb
106
+ licenses:
107
+ - MIT
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ segments:
119
+ - 0
120
+ hash: 3983421339398493086
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 1.8.10
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Save email envelope and message in single data format.
133
+ test_files: []