fcoury-gmail 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +44 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/bin/gmail +64 -0
- data/lib/gmail_sender.rb +69 -0
- data/lib/tls_smtp_patch.rb +10 -0
- data/test/gmail_sender_test.rb +10 -0
- data/test/test_helper.rb +6 -0
- metadata +67 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Daniel Cadenas
|
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,44 @@
|
|
1
|
+
= gmail_sender
|
2
|
+
|
3
|
+
A simple gem to send email through gmail
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'gmail_sender'
|
7
|
+
|
8
|
+
g = GmailSender.new("gmail_account_user_name", "gmail_account_password")
|
9
|
+
g.attach('/path/to/document.hz') # you can attach any number of files, but there are limits for total attachments size
|
10
|
+
g.send("someone@domain.com", "The subject", "The mail body")
|
11
|
+
|
12
|
+
== Command line usage
|
13
|
+
|
14
|
+
You can also use gmail_sender from the command line. First you need to create ~/.gmail with this content (YAML):
|
15
|
+
|
16
|
+
receiver_email: default_receiver@gmail.com
|
17
|
+
sender_user: gmail_account_user_name
|
18
|
+
sender_password: gmail_account_password
|
19
|
+
|
20
|
+
Is advisable to use a different sender account than your main email address so that it's not so bad if someone reads your configuration file and gets your password.
|
21
|
+
|
22
|
+
=== Examples
|
23
|
+
|
24
|
+
To send your directory list to the default receiver:
|
25
|
+
|
26
|
+
ls | gmail
|
27
|
+
|
28
|
+
You can specify some parameters like in this example which doesn't use pipes:
|
29
|
+
|
30
|
+
gmail -t somebody@gmail.com -s "This is the subject" -c "This is the email content"
|
31
|
+
|
32
|
+
You can send attachments by using the -a option (this example assumes that you have a receiver_email set in the ~/.gmail file so the -t is not needed):
|
33
|
+
|
34
|
+
gmail -c "hi, I'm sending some attachments" -a ./VERSION ./gmail_sender.gemspec
|
35
|
+
|
36
|
+
== Requirements
|
37
|
+
|
38
|
+
tlsmail if running Ruby 1.8.6
|
39
|
+
|
40
|
+
== Major contributors
|
41
|
+
|
42
|
+
* Daniel Cadenas - Maintainer
|
43
|
+
* Felipe Coury
|
44
|
+
* iwakura
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "fcoury-gmail"
|
8
|
+
gem.summary = %Q{A simple gem to send email through gmail}
|
9
|
+
gem.email = "dcadenas@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/dcadenas/gmail_sender"
|
11
|
+
gem.authors = ["Daniel Cadenas"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
Rake::TestTask.new(:test) do |test|
|
21
|
+
test.libs << 'lib' << 'test'
|
22
|
+
test.pattern = 'test/**/*_test.rb'
|
23
|
+
test.verbose = true
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'rcov/rcovtask'
|
28
|
+
Rcov::RcovTask.new do |test|
|
29
|
+
test.libs << 'test'
|
30
|
+
test.pattern = 'test/**/*_test.rb'
|
31
|
+
test.verbose = true
|
32
|
+
end
|
33
|
+
rescue LoadError
|
34
|
+
task :rcov do
|
35
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
if File.exist?('VERSION.yml')
|
45
|
+
config = YAML.load(File.read('VERSION.yml'))
|
46
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
47
|
+
else
|
48
|
+
version = ""
|
49
|
+
end
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "gmail_sender #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
56
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.1
|
data/bin/gmail
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'gmail_sender'
|
5
|
+
require 'choice'
|
6
|
+
|
7
|
+
Choice.options do
|
8
|
+
header ''
|
9
|
+
header 'options:'
|
10
|
+
|
11
|
+
option :receiver_email do
|
12
|
+
short '-t'
|
13
|
+
long '--to=RECEIVER'
|
14
|
+
desc 'Receiver of the email'
|
15
|
+
end
|
16
|
+
|
17
|
+
option :subject do
|
18
|
+
short '-s'
|
19
|
+
long '--subject=SUBJECT'
|
20
|
+
desc 'Subject of the email'
|
21
|
+
end
|
22
|
+
|
23
|
+
option :content do
|
24
|
+
short '-c'
|
25
|
+
long '--content=MAIL_CONTENTS'
|
26
|
+
desc 'Body of the email, uses STDIN if omitted'
|
27
|
+
end
|
28
|
+
|
29
|
+
option :attachments do
|
30
|
+
short '-a'
|
31
|
+
long '--attachments *ATTACHMENTS'
|
32
|
+
desc "A list of space separated list of files you wish to attach."
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def params
|
38
|
+
return @params if @params
|
39
|
+
|
40
|
+
config_file_path = File.join(ENV['HOME'],'.gmail')
|
41
|
+
if !File.exists?(config_file_path)
|
42
|
+
STDERR.puts "Please first create a ~/.gmail file with some defaults. Example:
|
43
|
+
receiver_email: default_receiver@gmail.com
|
44
|
+
sender_user: gmail_account_user_name
|
45
|
+
sender_password: gmail_account_user_password
|
46
|
+
"
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
50
|
+
defaults = {'subject' => 'Sent from command line',
|
51
|
+
'sender_domain' => 'gmail.com'}
|
52
|
+
|
53
|
+
@params = defaults.merge(YAML.load_file(config_file_path)).merge(Choice.choices)
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
mailer = GmailSender.new(params['sender_user'], params['sender_password'], params['sender_domain'])
|
58
|
+
if params['attachments']
|
59
|
+
params['attachments'].each do |attachment|
|
60
|
+
mailer.attach(attachment)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
content = params['content'] || (params['attachments'] && params['attachments'].join("\n"))
|
64
|
+
mailer.send(params['receiver_email'], params['subject'], content || STDIN.read)
|
data/lib/gmail_sender.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require "tls_smtp_patch"
|
3
|
+
|
4
|
+
class GmailSender
|
5
|
+
|
6
|
+
ATTACHMENT_READ_PORTION = 150360 # you may change this, but must be multiply to 3
|
7
|
+
|
8
|
+
def initialize(user, password, domain="gmail.com")
|
9
|
+
@sender_domain = domain
|
10
|
+
@sender_password = password
|
11
|
+
@sender_email = "#{user}@#{domain}"
|
12
|
+
@net_smtp = Net::SMTP.new("smtp.gmail.com", 587)
|
13
|
+
@net_smtp.enable_starttls
|
14
|
+
@attachments = []
|
15
|
+
@boundary = rand(2**256).to_s(16)
|
16
|
+
end
|
17
|
+
|
18
|
+
def attach(file)
|
19
|
+
@attachments << file if File.exist?(file)
|
20
|
+
end
|
21
|
+
|
22
|
+
def send(to, subject = "", content = "")
|
23
|
+
@net_smtp.start(@sender_domain, @sender_email, @sender_password, :plain) do |smtp|
|
24
|
+
smtp.open_message_stream(@sender_email, [to]) do |msg_stream|
|
25
|
+
set_message_stream(msg_stream, to, subject, content)
|
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?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
expect "From: gmail_account_name@gmail.com\nTo: to@gmail.com\nSubject: subject\n\nbody\n" do
|
5
|
+
gmail_sender = GmailSender.new("gmail_account_name", "gmail_account_password")
|
6
|
+
string_io = StringIO.new
|
7
|
+
gmail_sender.set_message_stream(string_io, "to@gmail.com", "subject", "body")
|
8
|
+
string_io.string
|
9
|
+
end
|
10
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fcoury-gmail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Cadenas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-20 00:00:00 -02:00
|
13
|
+
default_executable: gmail
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: dcadenas@gmail.com
|
18
|
+
executables:
|
19
|
+
- gmail
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- bin/gmail
|
33
|
+
- lib/gmail_sender.rb
|
34
|
+
- lib/tls_smtp_patch.rb
|
35
|
+
- test/gmail_sender_test.rb
|
36
|
+
- test/test_helper.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/dcadenas/gmail_sender
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: A simple gem to send email through gmail
|
65
|
+
test_files:
|
66
|
+
- test/gmail_sender_test.rb
|
67
|
+
- test/test_helper.rb
|