redsnapper-mail 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ == mail
2
+
3
+ Put appropriate LICENSE for your project here.
data/README ADDED
@@ -0,0 +1,63 @@
1
+ Mail Lib
2
+
3
+ An mail parsing lib.
4
+
5
+ == Features
6
+
7
+ * clean API
8
+
9
+ == Usage
10
+
11
+ Create new Mail
12
+
13
+ mail = Mail::Mail.new
14
+ mail.header.to = "test_to@test.de"
15
+ mail.header.from = "test_from@test.de"
16
+ mail.header.subject = "Test Mail"
17
+ mail.header.content_transfer_encoding = "quoted-printable"
18
+ mail.header.content_type.charset = "UTF-8"
19
+ mail.content = {:text_plain => "Hallo World !!!"}
20
+
21
+ Create new Mail with Text and HTML part
22
+
23
+ mail = Mail::Mail.new
24
+ mail.header.to = "test_to@test.de"
25
+ mail.header.from = "test_from@test.de"
26
+ mail.header.subject = "Test Mail"
27
+ mail.header.content_transfer_encoding = "quoted-printable"
28
+ mail.header.content_type.charset = "UTF-8"
29
+ mail.content = {
30
+ :text_plain => "Hallo World !!!",
31
+ :text_html => "<strong>Hallo World !!!</strong>"
32
+ }
33
+
34
+ Create new Mail Attachment
35
+
36
+ mail = Mail::Mail.new
37
+ mail.header.to = "test_to@test.de"
38
+ mail.header.from = "test_from@test.de"
39
+ mail.header.subject = "Test Mail"
40
+ mail.header.content_transfer_encoding = "quoted-printable"
41
+ mail.header.content_type.charset = "UTF-8"
42
+ mail.content = {
43
+ :text_plain => "Hallo World !!!",
44
+ :image_jpeg => File.read("path/to/image")
45
+ }
46
+
47
+ Load an existing Mail
48
+
49
+ mail = Mail::Mail.new(File.read("path/to/mail"))
50
+
51
+ puts mail.header.to => ["test_to@test.de"]
52
+
53
+ Get attachments from a Mail
54
+
55
+ mail = Mail::Mail.new(File.read("path/to/mail"))
56
+
57
+ if mail.header.attachments?
58
+ mail.attachments do |attachment|
59
+ puts attachment.header.content_type.type => "image/tiff"
60
+ puts attachment.header.content_disposition.filename => "fax.tif"
61
+ puts attachment.size => 408850
62
+ end
63
+ end
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+ require File.join(File.expand_path(File.dirname(__FILE__)),'lib','mail')
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'mail'
11
+ s.version = Mail::VERSION
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = ['README', 'LICENSE']
14
+ s.summary = 'Mail Parsing lib'
15
+ s.description = s.summary
16
+ s.author = 'Alexander Klaiber'
17
+ s.email = 'aklaiber@mybrief.de'
18
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
19
+ s.require_path = "lib"
20
+ end
21
+
22
+ Rake::GemPackageTask.new(spec) do |p|
23
+ p.gem_spec = spec
24
+ p.need_tar = true
25
+ p.need_zip = true
26
+ end
27
+
28
+ Rake::RDocTask.new do |rdoc|
29
+ files =['README', 'LICENSE', 'lib/**/*.rb']
30
+ rdoc.rdoc_files.add(files)
31
+ rdoc.main = "README"
32
+ rdoc.title = "mail Docs"
33
+ rdoc.rdoc_dir = 'doc/rdoc'
34
+ rdoc.options << '--line-numbers'
35
+ end
36
+
37
+ Rake::TestTask.new do |t|
38
+ t.test_files = FileList['test/**/*.rb']
39
+ end
40
+
41
+ desc "Create .gemspec file (useful for github)"
42
+ task :gemspec do
43
+ filename = "#{spec.name}.gemspec"
44
+ File.open(filename, "w") do |f|
45
+ f.puts spec.to_ruby
46
+ end
47
+ end
48
+
49
+ desc "Install the gem locally"
50
+ task :install => [:package] do
51
+ sh %{sudo gem install pkg/couchrest-#{CouchRest::VERSION}}
52
+ end
53
+
54
+
data/lib/mail.rb ADDED
@@ -0,0 +1,134 @@
1
+ # Author:: Alexander Klaiber (mailto:aklaiber@mybrief.de)
2
+ # Copyright:: Copyright (c) 2009 Alexander Klaiber
3
+ # License::
4
+
5
+ require "#{File.dirname(__FILE__)}/mail/header"
6
+ require "#{File.dirname(__FILE__)}/mail/content_type"
7
+ require "#{File.dirname(__FILE__)}/mail/content_disposition"
8
+ require "#{File.dirname(__FILE__)}/mail/part"
9
+ require "#{File.dirname(__FILE__)}/mail/attachment"
10
+ require "#{File.dirname(__FILE__)}/plugins/json"
11
+
12
+ module Mail
13
+
14
+ VERSION = '0.0.2' unless self.const_defined?("VERSION")
15
+
16
+ class Mail < Part
17
+ include Json
18
+
19
+ attr_reader :header, :body
20
+
21
+ def initialize(mail_str = nil)
22
+ super(mail_str)
23
+ @content_typs = Array.new
24
+ @parts = Hash.new
25
+ if mail_str
26
+ set_parts(mail_str)
27
+ end
28
+ end
29
+
30
+ def to_s
31
+ mail = @header.to_s
32
+ mail << "\n\n"
33
+ @parts.each do |type, part|
34
+ if @header.content_type.boundary
35
+ mail << "--#{@header.content_type.boundary}\n"
36
+ mail << part.header.content_type.to_s
37
+ mail << "\n\n"
38
+ end
39
+ mail << part.to_s
40
+ mail << "\n\n" if @header.content_type.boundary
41
+ end
42
+ mail << "--#{@header.content_type.boundary}--" if @header.content_type.boundary
43
+ return mail
44
+ end
45
+
46
+ def content=(options)
47
+ options.each do |type, content|
48
+ content_type = type.to_s.sub(/_/, '/')
49
+ if content_type
50
+ @parts[content_type] = Part.new(:content_type => content_type, :content => content)
51
+ @content_typs.push(content_type)
52
+ end
53
+ end
54
+ set_content_type
55
+ end
56
+
57
+ def content(type)
58
+ return parts[type].to_s
59
+ end
60
+
61
+ def parts
62
+ return @parts
63
+ end
64
+
65
+ def text_parts
66
+ parts.each do |content_type, part|
67
+ if content_type.eql?('text/plain') || content_type.eql?('text/html')
68
+ yield part
69
+ end
70
+ end
71
+ end
72
+
73
+ def attachments
74
+ parts.each do |content_type, part|
75
+ if !content_type.eql?('text/plain') && !content_type.eql?('text/html')
76
+ yield Attachment.new(part.to_s)
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def set_content_type
84
+ if @content_typs.size == 1
85
+ @header.content_type.type = @content_typs.first
86
+ elsif @content_typs.include?('text/plain') && @content_typs.include?('text/html')
87
+ @header.content_type.type = "multipart/alternative"
88
+ @header.content_type.boundary="#{Time.now.to_i}"
89
+ elsif @content_typs.size == 2
90
+ @header.content_type.type = "multipart/mixed"
91
+ @header.content_type.boundary="#{Time.now.to_i}"
92
+ end
93
+ end
94
+
95
+ def set_parts(str)
96
+ buffer = String.new
97
+ body = split_body(str)
98
+ if @header.content_type && @header.content_type.boundary
99
+ part_found = false
100
+ body.each do |line|
101
+ if line.strip.eql?("--#{@header.content_type.boundary}") || line.strip.eql?("--#{@header.content_type.boundary}--")
102
+ part_found = true
103
+ unless buffer.empty?
104
+ part = Part.new(buffer)
105
+ @parts[part.header.content_type.type] = part
106
+ buffer = String.new
107
+ end
108
+ elsif part_found
109
+ buffer << line
110
+ end
111
+ end
112
+ else
113
+ body.each do |line|
114
+ buffer << line
115
+ end
116
+ @parts[@header.content_type.type] = Part.new(buffer)
117
+ end
118
+ end
119
+
120
+ def split_body(str)
121
+ buffer = String.new
122
+ body_found = false
123
+ str.each_line do |line|
124
+ if body_found
125
+ buffer << line
126
+ end
127
+ body_found = true if !body_found && line.strip.empty?
128
+ end
129
+ return buffer
130
+ return nil
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,29 @@
1
+ require "base64"
2
+
3
+ module Mail
4
+ class Attachment < Part
5
+ def initialize(str_part)
6
+ super(str_part)
7
+ @binary = nil
8
+ end
9
+
10
+ def size
11
+ content.size
12
+ end
13
+
14
+ def content
15
+ unless @binary
16
+ buffer = String.new
17
+ body_found = false
18
+ @part_str.each_line do |line|
19
+ if body_found
20
+ buffer << line
21
+ end
22
+ body_found = true if !body_found && line.strip.empty?
23
+ end
24
+ @binary = Base64.decode64(buffer)
25
+ end
26
+ return @binary
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,57 @@
1
+ module Mail
2
+ class ContentDisposition
3
+ def initialize(options = nil)
4
+ @params = Hash.new
5
+ if options
6
+ if options.kind_of?(Hash)
7
+ @type = options[:type]
8
+ elsif options.kind_of?(String)
9
+ set_params(options)
10
+ end
11
+ end
12
+ end
13
+
14
+ def to_s
15
+ @content_type_str = String.new
16
+ @params.each do |key, value|
17
+ case key
18
+ when :type
19
+ @content_type_str << "Content-Type: #{type};"
20
+ else
21
+ @content_type_str << " #{key}=#{value}\n"
22
+ end
23
+ end
24
+ return @content_type_str
25
+ end
26
+
27
+ def type=(value)
28
+ @params[:type] = value
29
+ end
30
+
31
+ def type
32
+ return @params[:type]
33
+ end
34
+
35
+ def method_missing(name, *args, &block)
36
+ if name.to_s.include?("=")
37
+ @params[name.to_s.delete("=").to_sym] = args.to_s
38
+ else
39
+ return @params[name]
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def set_params(str)
46
+ @pattern = Hash.new
47
+ @pattern[:type] = "^(.*);"
48
+ @pattern[:filename] = "filename=(.*)$"
49
+ @pattern.each do |param_name, pattern|
50
+ match = str.match(pattern)
51
+ if match
52
+ @params[param_name] = match[1].strip
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,59 @@
1
+ module Mail
2
+ class ContentType
3
+ def initialize(options = nil)
4
+ @params = Hash.new
5
+ if options
6
+ if options.kind_of?(Hash)
7
+ @params[:type] = options[:type]
8
+ elsif options.kind_of?(String)
9
+ set_params(options)
10
+ end
11
+ end
12
+ end
13
+
14
+ def to_s
15
+ @content_type_str = String.new
16
+ @params.each do |key, value|
17
+ case key
18
+ when :type
19
+ @content_type_str << "Content-Type: #{type};"
20
+ else
21
+ @content_type_str << " #{key}=#{value}\n"
22
+ end
23
+ end
24
+ return @content_type_str
25
+ end
26
+
27
+ def type=(value)
28
+ @params[:type] = value
29
+ end
30
+
31
+ def type
32
+ return @params[:type]
33
+ end
34
+
35
+ def method_missing(name, *args, &block)
36
+ if name.to_s.include?("=")
37
+ @params[name.to_s.delete("=").to_sym] = args.to_s
38
+ else
39
+ return @params[name]
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def set_params(str)
46
+ @pattern = Hash.new
47
+ @pattern[:type] = "^(.*);"
48
+ @pattern[:boundary] = "boundary=\"(.*)\""
49
+ @pattern[:name] = "name=(.*)$"
50
+ @pattern[:charset] = "charset=(.*)$"
51
+ @pattern.each do |param_name, pattern|
52
+ match = str.match(pattern)
53
+ if match
54
+ @params[param_name] = match[1].strip
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,101 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+
4
+ module Mail
5
+ class Header
6
+
7
+ def initialize(options = nil)
8
+ @params = Hash.new
9
+ if options
10
+ if options.kind_of?(Hash) && options.key?(:content_type)
11
+ @params[:content_type] = ContentType.new(:type => options[:content_type])
12
+ elsif options.kind_of?(String)
13
+ set_params(options)
14
+ end
15
+ else
16
+ @params[:content_type] = ContentType.new
17
+ end
18
+ end
19
+
20
+ def to_s
21
+ str_header = String.new
22
+ @params.each do |key, value|
23
+ case key
24
+ when :content_type
25
+ str_header << value.to_s
26
+ else
27
+ str_header << "#{format_key(key)}: #{value}\n"
28
+ end
29
+ end
30
+ str_header << @content_type.to_s
31
+ return str_header
32
+ end
33
+
34
+ def to_json
35
+ @params.to_json
36
+ end
37
+
38
+ def multipart?
39
+ self.content_type.type.include?("multipart")
40
+ end
41
+
42
+ def attachments?
43
+ if self.multipart?
44
+ return self.content_type.type.eql?("multipart/mixed")
45
+ end
46
+ return false
47
+ end
48
+
49
+ def method_missing(name, *args, &block)
50
+ if name.to_s.include?("=")
51
+ @params[name.to_s.delete("=").to_sym] = args.to_s
52
+ else
53
+ return @params[name]
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def set_params(str)
60
+ str.each_line do |line|
61
+ match = line.split(":")
62
+ if match && !match.empty?
63
+ key = match[0].downcase.gsub('-', '_').to_sym
64
+ value = match[1].strip if match[1]
65
+ case key
66
+ when :to
67
+ @params[key] = value.split(",").collect! { |x| x.strip }
68
+ when :from
69
+ @params[key] = value.split(",").collect! { |x| x.strip }
70
+ when :date
71
+ @params[key] = DateTime.parse(value)
72
+ when :content_type
73
+ @params[key] = ContentType.new(value)
74
+ when :content_disposition
75
+ @params[key] = ContentDisposition.new(value)
76
+ else
77
+ @params[key] = value
78
+ end
79
+ end
80
+ end
81
+ @params[:content_type] = ContentType.new(:type => "text/plain") unless @params.key?(:content_type)
82
+ end
83
+
84
+ def format_key(key)
85
+ if key.to_s.include?("_")
86
+ buffer = String.new
87
+ key.to_s.split("_").each do |part|
88
+ if buffer.empty?
89
+ buffer << part.capitalize
90
+ else
91
+ buffer << "-#{part.capitalize}"
92
+ end
93
+ end
94
+ return buffer
95
+ else
96
+ return key.to_s.capitalize
97
+ end
98
+ end
99
+
100
+ end
101
+ end
data/lib/mail/part.rb ADDED
@@ -0,0 +1,52 @@
1
+ module Mail
2
+ class Part
3
+ attr_reader :header
4
+
5
+ def initialize(options)
6
+ if options.kind_of?(String)
7
+ @part_str = options
8
+ set_header(options)
9
+ elsif options.kind_of?(Hash)
10
+ @part_str = options[:content]
11
+ @header = Header.new(:content_type => options[:content_type])
12
+ else
13
+ @header = Header.new
14
+ end
15
+ end
16
+
17
+ def to_s
18
+ @part_str
19
+ end
20
+
21
+ def empty?
22
+ @part_str.empty?
23
+ end
24
+
25
+ def content
26
+ buffer = String.new
27
+ body_found = false
28
+ @part_str.each_line do |line|
29
+ if body_found
30
+ buffer << line
31
+ end
32
+ body_found = true if !body_found && line.strip.empty?
33
+ end
34
+ return buffer
35
+ end
36
+
37
+ private
38
+
39
+ def set_header(str)
40
+ buffer = String.new
41
+ header_found = true
42
+ str.each_line do |line|
43
+ if header_found
44
+ buffer << line
45
+ end
46
+ header_found = false if header_found && line.strip.empty?
47
+ end
48
+ @header = Header.new(buffer)
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,12 @@
1
+ module Json
2
+ def to_json
3
+ mail = Hash.new
4
+ # text_parts do |parts|
5
+ # puts parts
6
+ # end
7
+
8
+ # mail['header'] = @header.to_json
9
+ # mail['parts'] = @parts.to_json
10
+ # mail.to_json
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redsnapper-mail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Klaiber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-15 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Mail Parsing lib
17
+ email: aklaiber@mybrief.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ files:
26
+ - LICENSE
27
+ - README
28
+ - Rakefile
29
+ - lib/mail.rb
30
+ - lib/mail
31
+ - lib/mail/attachment.rb
32
+ - lib/mail/content_type.rb
33
+ - lib/mail/header.rb
34
+ - lib/mail/content_disposition.rb
35
+ - lib/mail/part.rb
36
+ - lib/plugins
37
+ - lib/plugins/json.rb
38
+ has_rdoc: false
39
+ homepage:
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.2.0
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Mail Parsing lib
64
+ test_files: []
65
+