ddollar-pony 0.4.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
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = Pony, the express way to send email in Ruby
2
+
3
+ == Overview
4
+
5
+ Ruby no longer has to be jealous of PHP's mail() function, which can send an email in a single command.
6
+
7
+ Pony.mail(:to => 'you@example.com', :from => 'me@example.com', :subject => 'hi', :body => 'Hello there.')
8
+
9
+ Any option key may be omitted except for :to.
10
+
11
+ == Transport
12
+
13
+ Pony uses /usr/sbin/sendmail to send mail if it is available, otherwise it uses SMTP to localhost.
14
+
15
+ This can be over-ridden if you specify a via option
16
+
17
+ Pony.mail(:to => 'you@example.com', :via => :smtp) # sends via SMTP
18
+
19
+ Pony.mail(:to => 'you@example.com', :via => :sendmail) # sends via sendmail
20
+
21
+ You can also specify options for SMTP:
22
+
23
+ Pony.mail(:to => 'you@example.com', :via => :smtp, :smtp => {
24
+ :host => 'smtp.yourserver.com',
25
+ :port => '25',
26
+ :user => 'user',
27
+ :pass => 'pass',
28
+ :auth => :plain # :plain, :login, :cram_md5, no auth by default
29
+ :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
30
+ }
31
+
32
+ == TLS/SSL
33
+
34
+ With smtp transport it also possible to use TLS/SSL:
35
+
36
+ Pony.mail(:to => 'you@example.com', :via => :smtp, :smtp => {
37
+ :host => 'smtp.gmail.com',
38
+ :port => '587',
39
+ :tls => true,
40
+ :user => 'user',
41
+ :pass => 'pass',
42
+ :auth => :plain # :plain, :login, :cram_md5, no auth by default
43
+ :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
44
+ })
45
+
46
+ == Attachments
47
+
48
+ You can attach a file or two with the :attachments option:
49
+
50
+ Pony.mail(..., :attachments => {"foo.zip" => File.read("path/to/foo.zip"), "hello.txt" => "hello!"})
51
+
52
+ == Meta
53
+
54
+ Written by Adam Wiggins
55
+
56
+ Patches contributed by: Mathieu Martin, Arun Thampi, Thomas Hurst, Stephen
57
+ Celis, Othmane Benkirane, and Neil Mock
58
+
59
+ Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
60
+
61
+ http://github.com/adamwiggins/pony
62
+
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "pony"
8
+ gem.summary = %Q{Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')}
9
+ gem.description = %Q{Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')}
10
+ gem.email = "<ddollar@gmail.com>"
11
+ gem.homepage = "http://github.com/ddollar/pony"
12
+ gem.authors = ["Adam Wiggins", "David Dollar"]
13
+ gem.add_development_dependency "rspec"
14
+ gem.add_development_dependency "yard"
15
+ gem.add_dependency "tmail", "~> 1.0"
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+
34
+ task :spec => :check_dependencies
35
+
36
+ task :default => :spec
37
+
38
+ begin
39
+ require 'yard'
40
+ YARD::Rake::YardocTask.new
41
+ rescue LoadError
42
+ task :yardoc do
43
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
44
+ end
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.4.0
data/lib/pony.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'rubygems'
2
+ require 'net/smtp'
3
+ begin
4
+ require 'smtp_tls'
5
+ rescue LoadError
6
+ end
7
+ require 'base64'
8
+ begin
9
+ require 'tmail'
10
+ rescue LoadError
11
+ require 'actionmailer'
12
+ end
13
+
14
+ module Pony
15
+ def self.mail(options)
16
+ raise(ArgumentError, ":to is required") unless options[:to]
17
+
18
+ via = options.delete(:via)
19
+ if via.nil?
20
+ transport build_tmail(options)
21
+ else
22
+ if via_options.include?(via.to_s)
23
+ send("transport_via_#{via}", build_tmail(options), options)
24
+ else
25
+ raise(ArgumentError, ":via must be either smtp or sendmail")
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.build_tmail(options)
31
+ mail = TMail::Mail.new
32
+ mail.to = options[:to]
33
+ mail.from = options[:from] || 'pony@unknown'
34
+ mail.subject = options[:subject]
35
+ mail.body = options[:body] || ""
36
+ mail.set_content_type(options[:content_type] || 'text/plain')
37
+ (options[:attachments] || []).each do |name, body|
38
+ attachment = TMail::Mail.new
39
+ attachment.transfer_encoding = "base64"
40
+ attachment.body = Base64.encode64(body)
41
+ # attachment.set_content_type # TODO: if necessary
42
+ attachment.set_content_disposition "attachment", "filename" => name
43
+ mail.parts.push attachment
44
+ end
45
+ mail
46
+ end
47
+
48
+ def self.sendmail_binary
49
+ @sendmail_binary ||= `which sendmail`.chomp
50
+ end
51
+
52
+ def self.transport(tmail)
53
+ if File.executable? sendmail_binary
54
+ transport_via_sendmail(tmail)
55
+ else
56
+ transport_via_smtp(tmail)
57
+ end
58
+ end
59
+
60
+ def self.via_options
61
+ %w(sendmail smtp)
62
+ end
63
+
64
+ def self.transport_via_sendmail(tmail, options={})
65
+ IO.popen('-', 'w+') do |pipe|
66
+ if pipe
67
+ pipe.write(tmail.to_s)
68
+ else
69
+ exec(sendmail_binary, *tmail.to)
70
+ end
71
+ end
72
+ end
73
+
74
+ def self.transport_via_smtp(tmail, options={:smtp => {}})
75
+ default_options = {:smtp => { :host => 'localhost', :port => '25', :domain => 'localhost.localdomain' }}
76
+ o = default_options[:smtp].merge(options[:smtp])
77
+ smtp = Net::SMTP.new(o[:host], o[:port])
78
+ if o[:tls]
79
+ raise "You may need: gem install smtp_tls" unless smtp.respond_to?(:enable_starttls)
80
+ smtp.enable_starttls
81
+ end
82
+ if o.include?(:auth)
83
+ smtp.start(o[:domain], o[:user], o[:password], o[:auth])
84
+ else
85
+ smtp.start(o[:domain])
86
+ end
87
+ smtp.send_message tmail.to_s, tmail.from, tmail.to
88
+ smtp.finish
89
+ end
90
+ end
data/pony.gemspec ADDED
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{pony}
8
+ s.version = "0.4.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Adam Wiggins", "David Dollar"]
12
+ s.date = %q{2009-09-09}
13
+ s.description = %q{Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')}
14
+ s.email = %q{<ddollar@gmail.com>}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ "README.rdoc",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/pony.rb",
25
+ "pony.gemspec",
26
+ "spec/base.rb",
27
+ "spec/pony_spec.rb"
28
+ ]
29
+ s.homepage = %q{http://github.com/ddollar/pony}
30
+ s.rdoc_options = ["--charset=UTF-8"]
31
+ s.require_paths = ["lib"]
32
+ s.rubygems_version = %q{1.3.5}
33
+ s.summary = %q{Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')}
34
+ s.test_files = [
35
+ "spec/base.rb",
36
+ "spec/pony_spec.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
44
+ s.add_development_dependency(%q<rspec>, [">= 0"])
45
+ s.add_development_dependency(%q<yard>, [">= 0"])
46
+ s.add_runtime_dependency(%q<tmail>, ["~> 1.0"])
47
+ else
48
+ s.add_dependency(%q<rspec>, [">= 0"])
49
+ s.add_dependency(%q<yard>, [">= 0"])
50
+ s.add_dependency(%q<tmail>, ["~> 1.0"])
51
+ end
52
+ else
53
+ s.add_dependency(%q<rspec>, [">= 0"])
54
+ s.add_dependency(%q<yard>, [">= 0"])
55
+ s.add_dependency(%q<tmail>, ["~> 1.0"])
56
+ end
57
+ end
data/spec/base.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require File.dirname(__FILE__) + '/../lib/pony'
data/spec/pony_spec.rb ADDED
@@ -0,0 +1,147 @@
1
+ require File.dirname(__FILE__) + '/base'
2
+
3
+ describe Pony do
4
+ it "sends mail" do
5
+ Pony.should_receive(:transport) do |tmail|
6
+ tmail.to.should == [ 'joe@example.com' ]
7
+ tmail.from.should == [ 'sender@example.com' ]
8
+ tmail.subject.should == 'hi'
9
+ tmail.body.should == 'Hello, Joe.'
10
+ end
11
+ Pony.mail(:to => 'joe@example.com', :from => 'sender@example.com', :subject => 'hi', :body => 'Hello, Joe.')
12
+ end
13
+
14
+ it "requires :to param" do
15
+ Pony.stub!(:transport)
16
+ lambda { Pony.mail({}) }.should raise_error(ArgumentError)
17
+ end
18
+
19
+ it "doesn't require any other param" do
20
+ Pony.stub!(:transport)
21
+ lambda { Pony.mail(:to => 'joe@example.com') }.should_not raise_error
22
+ end
23
+
24
+ ####################
25
+
26
+ describe "builds a TMail object with field:" do
27
+ it "to" do
28
+ Pony.build_tmail(:to => 'joe@example.com').to.should == [ 'joe@example.com' ]
29
+ end
30
+
31
+ it "from" do
32
+ Pony.build_tmail(:from => 'joe@example.com').from.should == [ 'joe@example.com' ]
33
+ end
34
+
35
+ it "from (default)" do
36
+ Pony.build_tmail({}).from.should == [ 'pony@unknown' ]
37
+ end
38
+
39
+ it "content_type" do
40
+ Pony.build_tmail(:content_type => 'text/html').content_type.should == 'text/html'
41
+ end
42
+
43
+ it "content_type (default)" do
44
+ Pony.build_tmail({}).content_type.should == 'text/plain'
45
+ end
46
+
47
+ it "subject" do
48
+ Pony.build_tmail(:subject => 'hello').subject.should == 'hello'
49
+ end
50
+
51
+ it "body" do
52
+ Pony.build_tmail(:body => 'What do you know, Joe?').body.should == 'What do you know, Joe?'
53
+ end
54
+
55
+ it "attachments" do
56
+ tmail = Pony.build_tmail(:attachments => {"foo.txt" => "content of foo.txt"})
57
+ tmail.should have(1).parts
58
+ tmail.parts.first.to_s.should == <<-PART
59
+ Content-Transfer-Encoding: Base64
60
+ Content-Disposition: attachment; filename=foo.txt
61
+
62
+ Y29udGVudCBvZiBmb28udHh0
63
+ PART
64
+ end
65
+ end
66
+
67
+ describe "transport" do
68
+ it "transports via the sendmail binary if it exists" do
69
+ File.stub!(:executable?).and_return(true)
70
+ Pony.should_receive(:transport_via_sendmail).with(:tmail)
71
+ Pony.transport(:tmail)
72
+ end
73
+
74
+ it "transports via smtp if no sendmail binary" do
75
+ Pony.stub!(:sendmail_binary).and_return('/does/not/exist')
76
+ Pony.should_receive(:transport_via_smtp).with(:tmail)
77
+ Pony.transport(:tmail)
78
+ end
79
+
80
+ it "transports mail via /usr/sbin/sendmail binary" do
81
+ pipe = mock('sendmail pipe')
82
+ IO.should_receive(:popen).with('-',"w+").and_yield(pipe)
83
+ pipe.should_receive(:write).with('message')
84
+ Pony.transport_via_sendmail(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
85
+ end
86
+
87
+ describe "SMTP transport" do
88
+ before do
89
+ @smtp = mock('net::smtp object')
90
+ @smtp.stub!(:start)
91
+ @smtp.stub!(:send_message)
92
+ @smtp.stub!(:finish)
93
+ Net::SMTP.stub!(:new).and_return(@smtp)
94
+ end
95
+
96
+ it "defaults to localhost as the SMTP server" do
97
+ Net::SMTP.should_receive(:new).with('localhost', '25').and_return(@smtp)
98
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
99
+ end
100
+
101
+ it "uses SMTP authorization when auth key is provided" do
102
+ o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain'}}
103
+ @smtp.should_receive(:start).with('localhost.localdomain', 'user', 'password', 'plain')
104
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
105
+ end
106
+
107
+ it "enable starttls when tls option is true" do
108
+ o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain', :tls => true}}
109
+ @smtp.should_receive(:enable_starttls)
110
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
111
+ end
112
+
113
+ it "starts the job" do
114
+ @smtp.should_receive(:start)
115
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
116
+ end
117
+
118
+ it "sends a tmail message" do
119
+ @smtp.should_receive(:send_message)
120
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
121
+ end
122
+
123
+ it "finishes the job" do
124
+ @smtp.should_receive(:finish)
125
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ describe ":via option should over-ride the default transport mechanism" do
132
+ it "should send via sendmail if :via => sendmail" do
133
+ Pony.should_receive(:transport_via_sendmail)
134
+ Pony.mail(:to => 'joe@example.com', :via => :sendmail)
135
+ end
136
+
137
+ it "should send via smtp if :via => smtp" do
138
+ Pony.should_receive(:transport_via_smtp)
139
+ Pony.mail(:to => 'joe@example.com', :via => :smtp)
140
+ end
141
+
142
+ it "should raise an error if via is neither smtp nor sendmail" do
143
+ lambda { Pony.mail(:to => 'joe@plumber.com', :via => :pigeon) }.should raise_error(ArgumentError)
144
+ end
145
+ end
146
+
147
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ddollar-pony
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Wiggins
8
+ - David Dollar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-09-09 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: yard
28
+ type: :development
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: tmail
38
+ type: :runtime
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: "1.0"
45
+ version:
46
+ description: "Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')"
47
+ email: <ddollar@gmail.com>
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - README.rdoc
54
+ files:
55
+ - .document
56
+ - .gitignore
57
+ - README.rdoc
58
+ - Rakefile
59
+ - VERSION
60
+ - lib/pony.rb
61
+ - pony.gemspec
62
+ - spec/base.rb
63
+ - spec/pony_spec.rb
64
+ has_rdoc: false
65
+ homepage: http://github.com/ddollar/pony
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.2.0
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: "Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')"
90
+ test_files:
91
+ - spec/base.rb
92
+ - spec/pony_spec.rb