gmail_sender 0.3.1 → 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.
- data/README.rdoc +4 -0
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/gmail +1 -1
- data/gmail_sender.gemspec +11 -2
- data/lib/gmail_sender.rb +12 -52
- data/lib/gmail_sender/message_stream_writer.rb +54 -0
- data/test/gmail_sender_test.rb +32 -5
- data/test/message_stream_writer_test.rb +48 -0
- data/test/test_helper.rb +2 -0
- metadata +26 -4
data/README.rdoc
CHANGED
@@ -9,6 +9,10 @@ A simple gem to send email through gmail
|
|
9
9
|
g.attach('/path/to/document.hz') # you can attach any number of files, but there are limits for total attachments size
|
10
10
|
g.send("someone@domain.com", "The subject", "The mail body")
|
11
11
|
|
12
|
+
To use your google apps domain instead of gmail.com include the complete sender email instead of just the user name:
|
13
|
+
|
14
|
+
g = GmailSender.new("gmail_account_user_name@yourdomain.com", "gmail_account_password")
|
15
|
+
|
12
16
|
== Command line usage
|
13
17
|
|
14
18
|
You can also use gmail_sender from the command line. First you need to create ~/.gmail with this content (YAML):
|
data/Rakefile
CHANGED
@@ -9,6 +9,8 @@ begin
|
|
9
9
|
gem.email = "dcadenas@gmail.com"
|
10
10
|
gem.homepage = "http://github.com/dcadenas/gmail_sender"
|
11
11
|
gem.authors = ["Daniel Cadenas"]
|
12
|
+
gem.add_development_dependency "expectations"
|
13
|
+
gem.add_development_dependency "filetesthelper"
|
12
14
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
15
|
end
|
14
16
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/bin/gmail
CHANGED
@@ -54,7 +54,7 @@ def params
|
|
54
54
|
end
|
55
55
|
|
56
56
|
|
57
|
-
mailer = GmailSender.new(params['sender_user']
|
57
|
+
mailer = GmailSender.new("#{params['sender_user']}@#{params['sender_domain']}", params['sender_password'])
|
58
58
|
if params['attachments']
|
59
59
|
params['attachments'].each do |attachment|
|
60
60
|
mailer.attach(attachment)
|
data/gmail_sender.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gmail_sender}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Daniel Cadenas"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-02-21}
|
13
13
|
s.default_executable = %q{gmail}
|
14
14
|
s.email = %q{dcadenas@gmail.com}
|
15
15
|
s.executables = ["gmail"]
|
@@ -27,8 +27,10 @@ Gem::Specification.new do |s|
|
|
27
27
|
"bin/gmail",
|
28
28
|
"gmail_sender.gemspec",
|
29
29
|
"lib/gmail_sender.rb",
|
30
|
+
"lib/gmail_sender/message_stream_writer.rb",
|
30
31
|
"lib/tls_smtp_patch.rb",
|
31
32
|
"test/gmail_sender_test.rb",
|
33
|
+
"test/message_stream_writer_test.rb",
|
32
34
|
"test/test_helper.rb"
|
33
35
|
]
|
34
36
|
s.homepage = %q{http://github.com/dcadenas/gmail_sender}
|
@@ -38,6 +40,7 @@ Gem::Specification.new do |s|
|
|
38
40
|
s.summary = %q{A simple gem to send email through gmail}
|
39
41
|
s.test_files = [
|
40
42
|
"test/gmail_sender_test.rb",
|
43
|
+
"test/message_stream_writer_test.rb",
|
41
44
|
"test/test_helper.rb"
|
42
45
|
]
|
43
46
|
|
@@ -46,9 +49,15 @@ Gem::Specification.new do |s|
|
|
46
49
|
s.specification_version = 3
|
47
50
|
|
48
51
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
52
|
+
s.add_development_dependency(%q<expectations>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<filetesthelper>, [">= 0"])
|
49
54
|
else
|
55
|
+
s.add_dependency(%q<expectations>, [">= 0"])
|
56
|
+
s.add_dependency(%q<filetesthelper>, [">= 0"])
|
50
57
|
end
|
51
58
|
else
|
59
|
+
s.add_dependency(%q<expectations>, [">= 0"])
|
60
|
+
s.add_dependency(%q<filetesthelper>, [">= 0"])
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
data/lib/gmail_sender.rb
CHANGED
@@ -1,68 +1,28 @@
|
|
1
1
|
require 'base64'
|
2
|
-
require
|
2
|
+
require 'tls_smtp_patch'
|
3
|
+
require 'gmail_sender/message_stream_writer'
|
3
4
|
|
4
5
|
class GmailSender
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@sender_domain = domain
|
6
|
+
def initialize(user_or_email, password, net_smtp_class = Net::SMTP, message_stream_writer_class = MessageStreamWriter)
|
7
|
+
user, domain = user_or_email.split("@")
|
8
|
+
@sender_domain = domain || "gmail.com"
|
9
|
+
@sender_email = "#{user}@#{@sender_domain}"
|
10
10
|
@sender_password = password
|
11
|
-
|
12
|
-
@net_smtp =
|
11
|
+
|
12
|
+
@net_smtp = net_smtp_class.new("smtp.gmail.com", 587)
|
13
13
|
@net_smtp.enable_starttls
|
14
|
-
|
15
|
-
@
|
14
|
+
|
15
|
+
@message_stream_writer = message_stream_writer_class.new(@sender_email)
|
16
16
|
end
|
17
17
|
|
18
18
|
def attach(file)
|
19
|
-
@attachments << file if File.exist?(file)
|
19
|
+
@message_stream_writer.attachments << file if File.exist?(file)
|
20
20
|
end
|
21
21
|
|
22
22
|
def send(to, subject = "", content = "")
|
23
23
|
@net_smtp.start(@sender_domain, @sender_email, @sender_password, :plain) do |smtp|
|
24
24
|
smtp.open_message_stream(@sender_email, [to]) do |msg_stream|
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def set_message_stream(msg_stream, to, subject, content)
|
31
|
-
set_headers(msg_stream, to, subject)
|
32
|
-
set_content(msg_stream, content)
|
33
|
-
set_attachments(msg_stream)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
def set_headers(msg_stream, to, subject)
|
38
|
-
msg_stream.puts "From: #{@sender_email}"
|
39
|
-
msg_stream.puts "To: #{to}"
|
40
|
-
msg_stream.puts "Subject: #{subject}"
|
41
|
-
unless @attachments.empty?
|
42
|
-
msg_stream.puts 'MIME-Version: 1.0'
|
43
|
-
msg_stream.puts %{Content-Type: multipart/mixed; boundary="#{@boundary}"}
|
44
|
-
end
|
45
|
-
msg_stream.puts
|
46
|
-
unless @attachments.empty?
|
47
|
-
msg_stream.puts "--#{@boundary}"
|
48
|
-
msg_stream.puts 'Content-Type: text/plain'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def set_content(msg_stream, content)
|
53
|
-
msg_stream.puts content
|
54
|
-
end
|
55
|
-
|
56
|
-
def set_attachments(msg_stream)
|
57
|
-
@attachments.each do |file|
|
58
|
-
msg_stream.puts "--#{@boundary}"
|
59
|
-
msg_stream.puts %{Content-Type: application/octet-stream; name="#{File.basename(file)}"}
|
60
|
-
msg_stream.puts %{Content-Disposition: attachment; filename="#{File.basename(file)}"}
|
61
|
-
msg_stream.puts 'Content-Transfer-Encoding: base64'
|
62
|
-
msg_stream.puts "Content-ID: <#{File.basename(file)}>"
|
63
|
-
msg_stream.puts
|
64
|
-
File.open(file) do |fd|
|
65
|
-
msg_stream.puts Base64.encode64(fd.read(ATTACHMENT_READ_PORTION)) until fd.eof?
|
25
|
+
@message_stream_writer.write(msg_stream, to, subject, content)
|
66
26
|
end
|
67
27
|
end
|
68
28
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class GmailSender
|
2
|
+
class MessageStreamWriter
|
3
|
+
ATTACHMENT_READ_PORTION = 150360 # you may change this, but must be multiply to 3
|
4
|
+
|
5
|
+
attr_reader :attachments
|
6
|
+
|
7
|
+
def initialize(sender_email)
|
8
|
+
@sender_email = sender_email
|
9
|
+
@attachments = []
|
10
|
+
@boundary = rand(2**256).to_s(16)
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(msg_stream, to, subject, content)
|
14
|
+
write_headers(msg_stream, to, subject)
|
15
|
+
write_content(msg_stream, content)
|
16
|
+
write_attachments(msg_stream)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def write_headers(msg_stream, to, subject)
|
21
|
+
msg_stream.puts "From: #{@sender_email}"
|
22
|
+
msg_stream.puts "To: #{to}"
|
23
|
+
msg_stream.puts "Subject: #{subject}"
|
24
|
+
unless @attachments.empty?
|
25
|
+
msg_stream.puts 'MIME-Version: 1.0'
|
26
|
+
msg_stream.puts %{Content-Type: multipart/mixed; boundary="#{@boundary}"}
|
27
|
+
end
|
28
|
+
msg_stream.puts
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_content(msg_stream, content)
|
32
|
+
unless @attachments.empty?
|
33
|
+
msg_stream.puts "--#{@boundary}" unless @attachments.empty?
|
34
|
+
msg_stream.puts 'Content-Type: text/plain'
|
35
|
+
end
|
36
|
+
|
37
|
+
msg_stream.puts content
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_attachments(msg_stream)
|
41
|
+
@attachments.each do |file|
|
42
|
+
msg_stream.puts "--#{@boundary}"
|
43
|
+
msg_stream.puts %{Content-Type: application/octet-stream; name="#{File.basename(file)}"}
|
44
|
+
msg_stream.puts %{Content-Disposition: attachment; filename="#{File.basename(file)}"}
|
45
|
+
msg_stream.puts 'Content-Transfer-Encoding: base64'
|
46
|
+
msg_stream.puts "Content-ID: <#{File.basename(file)}>"
|
47
|
+
msg_stream.puts
|
48
|
+
File.open(file) do |fd|
|
49
|
+
msg_stream.puts Base64.encode64(fd.read(ATTACHMENT_READ_PORTION)) until fd.eof?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/gmail_sender_test.rb
CHANGED
@@ -1,10 +1,37 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
class FakedNetSMTP
|
4
|
+
def initialize(*args)
|
5
|
+
end
|
6
|
+
|
7
|
+
def start(*args)
|
8
|
+
yield self
|
9
|
+
end
|
10
|
+
|
11
|
+
def enable_starttls
|
12
|
+
end
|
13
|
+
|
14
|
+
def open_message_stream(*args)
|
15
|
+
stream = StringIO.new
|
16
|
+
yield stream
|
17
|
+
@@sent_email = stream.string
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.sent_email
|
21
|
+
@@sent_email
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
3
25
|
Expectations do
|
4
|
-
expect "From:
|
5
|
-
gmail_sender = GmailSender.new("
|
6
|
-
|
7
|
-
|
8
|
-
|
26
|
+
expect "From: me@gmail.com\nTo: someone@somehost.com\nSubject: hi!\n\nho\n" do
|
27
|
+
gmail_sender = GmailSender.new("me", "password", FakedNetSMTP)
|
28
|
+
gmail_sender.send("someone@somehost.com", "hi!", "ho")
|
29
|
+
FakedNetSMTP.sent_email
|
30
|
+
end
|
31
|
+
|
32
|
+
expect "From: me@somehost.com\nTo: someone@someotherhost.com\nSubject: hi!\n\nho\n" do
|
33
|
+
gmail_sender = GmailSender.new("me@somehost.com", "password", FakedNetSMTP)
|
34
|
+
gmail_sender.send("someone@someotherhost.com", "hi!", "ho")
|
35
|
+
FakedNetSMTP.sent_email
|
9
36
|
end
|
10
37
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
expect "From: sender@gmail.com\nTo: to@gmail.com\nSubject: subject\n\nbody\n" do
|
5
|
+
string_io = StringIO.new
|
6
|
+
message_stream_writer = GmailSender::MessageStreamWriter.new("sender@gmail.com")
|
7
|
+
message_stream_writer.write(string_io, "to@gmail.com", "subject", "body")
|
8
|
+
string_io.string
|
9
|
+
end
|
10
|
+
|
11
|
+
expect eval(<<-MAIL_WITH_ATTACHMENT_REGEXP) do
|
12
|
+
/From: sender@gmail.com
|
13
|
+
To: to@gmail.com
|
14
|
+
Subject: subject
|
15
|
+
MIME-Version: 1.0
|
16
|
+
Content-Type: multipart\\/mixed; boundary="([a-f0-9]+)"
|
17
|
+
|
18
|
+
--\\1
|
19
|
+
Content-Type: text\\/plain
|
20
|
+
body
|
21
|
+
--\\1
|
22
|
+
Content-Type: application\\/octet-stream; name="first_file.txt"
|
23
|
+
Content-Disposition: attachment; filename="first_file.txt"
|
24
|
+
Content-Transfer-Encoding: base64
|
25
|
+
Content-ID: <first_file.txt>
|
26
|
+
|
27
|
+
dGhpcyBpcyB0aGUgZmlyc3QgZmlsZSBjb250ZW50
|
28
|
+
--\\1
|
29
|
+
Content-Type: application\\/octet-stream; name="second_file.txt"
|
30
|
+
Content-Disposition: attachment; filename="second_file.txt"
|
31
|
+
Content-Transfer-Encoding: base64
|
32
|
+
Content-ID: <second_file.txt>
|
33
|
+
|
34
|
+
YW5kIHRoaXMgaXMgdGhlIHNlY29uZCBmaWxlIGNvbnRlbnQ=
|
35
|
+
/
|
36
|
+
MAIL_WITH_ATTACHMENT_REGEXP
|
37
|
+
string_io = StringIO.new
|
38
|
+
message_stream_writer = GmailSender::MessageStreamWriter.new("sender@gmail.com")
|
39
|
+
message_stream_writer.attachments << "first_file.txt"
|
40
|
+
message_stream_writer.attachments << "second_file.txt"
|
41
|
+
|
42
|
+
with_files("first_file.txt" => "this is the first file content", "second_file.txt" => "and this is the second file content") do
|
43
|
+
message_stream_writer.write(string_io, "to@gmail.com", "subject", "body")
|
44
|
+
end
|
45
|
+
|
46
|
+
string_io.string
|
47
|
+
end
|
48
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmail_sender
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Cadenas
|
@@ -9,10 +9,29 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-02-21 00:00:00 -02:00
|
13
13
|
default_executable: gmail
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: expectations
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: filetesthelper
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
16
35
|
description:
|
17
36
|
email: dcadenas@gmail.com
|
18
37
|
executables:
|
@@ -32,8 +51,10 @@ files:
|
|
32
51
|
- bin/gmail
|
33
52
|
- gmail_sender.gemspec
|
34
53
|
- lib/gmail_sender.rb
|
54
|
+
- lib/gmail_sender/message_stream_writer.rb
|
35
55
|
- lib/tls_smtp_patch.rb
|
36
56
|
- test/gmail_sender_test.rb
|
57
|
+
- test/message_stream_writer_test.rb
|
37
58
|
- test/test_helper.rb
|
38
59
|
has_rdoc: true
|
39
60
|
homepage: http://github.com/dcadenas/gmail_sender
|
@@ -65,4 +86,5 @@ specification_version: 3
|
|
65
86
|
summary: A simple gem to send email through gmail
|
66
87
|
test_files:
|
67
88
|
- test/gmail_sender_test.rb
|
89
|
+
- test/message_stream_writer_test.rb
|
68
90
|
- test/test_helper.rb
|