chrisb-pony 0.0.1

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 ADDED
@@ -0,0 +1,6 @@
1
+ = Pony, the express way to send email in Ruby
2
+
3
+ This is a small patch to hiroshi-pony that adds header support. Intended for projects using Ruby 1.8.6 that require TLS support (Gmail).
4
+
5
+ Read up on Pony at the official project: http://github.com/benprew/pony
6
+ Fork source: http://github.com/hiroshi/pony
data/Rakefile ADDED
@@ -0,0 +1,73 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc "Run all specs"
5
+ Spec::Rake::SpecTask.new('spec') do |t|
6
+ t.spec_files = FileList['spec/*_spec.rb']
7
+ end
8
+
9
+ desc "Print specdocs"
10
+ Spec::Rake::SpecTask.new(:doc) do |t|
11
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
12
+ t.spec_files = FileList['spec/*_spec.rb']
13
+ end
14
+
15
+ desc "Run all examples with RCov"
16
+ Spec::Rake::SpecTask.new('rcov') do |t|
17
+ t.spec_files = FileList['spec/*_spec.rb']
18
+ t.rcov = true
19
+ t.rcov_opts = ['--exclude', 'examples']
20
+ end
21
+
22
+ task :default => :spec
23
+
24
+ ######################################################
25
+
26
+ require 'rake'
27
+ require 'rake/testtask'
28
+ require 'rake/clean'
29
+ require 'rake/gempackagetask'
30
+ require 'fileutils'
31
+
32
+ version = "0.3"
33
+ name = "pony"
34
+
35
+ spec = Gem::Specification.new do |s|
36
+ s.name = name
37
+ s.version = version
38
+ s.summary = "Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')"
39
+ s.description = "Send email in one command: Pony.mail(:to => 'someone@example.com', :body => 'hello')"
40
+ s.author = "Adam Wiggins"
41
+ s.email = "adam@heroku.com"
42
+ s.homepage = "http://github.com/adamwiggins/pony"
43
+ s.rubyforge_project = "pony"
44
+
45
+ s.platform = Gem::Platform::RUBY
46
+ s.has_rdoc = false
47
+
48
+ s.files = %w(Rakefile) + Dir.glob("{lib,spec}/**/*")
49
+
50
+ s.require_path = "lib"
51
+ s.add_dependency( 'tmail', '~> 1.0' )
52
+ end
53
+
54
+ Rake::GemPackageTask.new(spec) do |p|
55
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
56
+ end
57
+
58
+ task :install => [ :package ] do
59
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
60
+ end
61
+
62
+ task :uninstall => [ :clean ] do
63
+ sh %{sudo gem uninstall #{name}}
64
+ end
65
+
66
+ Rake::TestTask.new do |t|
67
+ t.libs << "spec"
68
+ t.test_files = FileList['spec/*_spec.rb']
69
+ t.verbose = true
70
+ end
71
+
72
+ CLEAN.include [ 'pkg', '*.gem', '.config' ]
73
+
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{chrisb-pony}
5
+ s.version = "0.0.1"
6
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.authors = ["Chris Bielinski"]
8
+ s.date = %q{2010-12-08}
9
+ s.description = %q{hiroshi/pony + headers.}
10
+ s.email = %q{chris@shadowreactor.com}
11
+ s.files = ["README.rdoc", "Rakefile", "lib/pony.rb", "chrisb-pony.gemspec", "spec/base.rb", "spec/pony_spec.rb"]
12
+ s.has_rdoc = false
13
+ s.homepage = %q{http://github.com/chrisb/pony}
14
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.3.1}
17
+ s.summary = s.description
18
+ end
data/lib/pony.rb ADDED
@@ -0,0 +1,92 @@
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
+ (options[:attachments] || []).each do |name, body|
37
+ attachment = TMail::Mail.new
38
+ attachment.transfer_encoding = "base64"
39
+ attachment.body = Base64.encode64(body)
40
+ # attachment.set_content_type # TODO: if necessary
41
+ attachment.set_content_disposition "attachment", "filename" => name
42
+ mail.parts.push attachment
43
+ end
44
+ (options[:headers] ||= {}).each do |key, value|
45
+ mail[key] = value
46
+ end
47
+ mail
48
+ end
49
+
50
+ def self.sendmail_binary
51
+ @sendmail_binary ||= `which sendmail`.chomp
52
+ end
53
+
54
+ def self.transport(tmail)
55
+ if File.executable? sendmail_binary
56
+ transport_via_sendmail(tmail)
57
+ else
58
+ transport_via_smtp(tmail)
59
+ end
60
+ end
61
+
62
+ def self.via_options
63
+ %w(sendmail smtp)
64
+ end
65
+
66
+ def self.transport_via_sendmail(tmail, options={})
67
+ IO.popen('-', 'w+') do |pipe|
68
+ if pipe
69
+ pipe.write(tmail.to_s)
70
+ else
71
+ exec(sendmail_binary, *tmail.to)
72
+ end
73
+ end
74
+ end
75
+
76
+ def self.transport_via_smtp(tmail, options={:smtp => {}})
77
+ default_options = {:smtp => { :host => 'localhost', :port => '25', :domain => 'localhost.localdomain' }}
78
+ o = default_options[:smtp].merge(options[:smtp])
79
+ smtp = Net::SMTP.new(o[:host], o[:port])
80
+ if o[:tls]
81
+ raise "You may need: gem install smtp_tls" unless smtp.respond_to?(:enable_starttls)
82
+ smtp.enable_starttls
83
+ end
84
+ if o.include?(:auth)
85
+ smtp.start(o[:domain], o[:user], o[:password], o[:auth])
86
+ else
87
+ smtp.start(o[:domain])
88
+ end
89
+ smtp.send_message tmail.to_s, tmail.from, tmail.to
90
+ smtp.finish
91
+ end
92
+ 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,139 @@
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 "subject" do
40
+ Pony.build_tmail(:subject => 'hello').subject.should == 'hello'
41
+ end
42
+
43
+ it "body" do
44
+ Pony.build_tmail(:body => 'What do you know, Joe?').body.should == 'What do you know, Joe?'
45
+ end
46
+
47
+ it "attachments" do
48
+ tmail = Pony.build_tmail(:attachments => {"foo.txt" => "content of foo.txt"})
49
+ tmail.should have(1).parts
50
+ tmail.parts.first.to_s.should == <<-PART
51
+ Content-Transfer-Encoding: Base64
52
+ Content-Disposition: attachment; filename=foo.txt
53
+
54
+ Y29udGVudCBvZiBmb28udHh0
55
+ PART
56
+ end
57
+ end
58
+
59
+ describe "transport" do
60
+ it "transports via the sendmail binary if it exists" do
61
+ File.stub!(:executable?).and_return(true)
62
+ Pony.should_receive(:transport_via_sendmail).with(:tmail)
63
+ Pony.transport(:tmail)
64
+ end
65
+
66
+ it "transports via smtp if no sendmail binary" do
67
+ Pony.stub!(:sendmail_binary).and_return('/does/not/exist')
68
+ Pony.should_receive(:transport_via_smtp).with(:tmail)
69
+ Pony.transport(:tmail)
70
+ end
71
+
72
+ it "transports mail via /usr/sbin/sendmail binary" do
73
+ pipe = mock('sendmail pipe')
74
+ IO.should_receive(:popen).with('-',"w+").and_yield(pipe)
75
+ pipe.should_receive(:write).with('message')
76
+ Pony.transport_via_sendmail(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
77
+ end
78
+
79
+ describe "SMTP transport" do
80
+ before do
81
+ @smtp = mock('net::smtp object')
82
+ @smtp.stub!(:start)
83
+ @smtp.stub!(:send_message)
84
+ @smtp.stub!(:finish)
85
+ Net::SMTP.stub!(:new).and_return(@smtp)
86
+ end
87
+
88
+ it "defaults to localhost as the SMTP server" do
89
+ Net::SMTP.should_receive(:new).with('localhost', '25').and_return(@smtp)
90
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
91
+ end
92
+
93
+ it "uses SMTP authorization when auth key is provided" do
94
+ o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain'}}
95
+ @smtp.should_receive(:start).with('localhost.localdomain', 'user', 'password', 'plain')
96
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
97
+ end
98
+
99
+ it "enable starttls when tls option is true" do
100
+ o = { :smtp => { :user => 'user', :password => 'password', :auth => 'plain', :tls => true}}
101
+ @smtp.should_receive(:enable_starttls)
102
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'), o)
103
+ end
104
+
105
+ it "starts the job" do
106
+ @smtp.should_receive(:start)
107
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
108
+ end
109
+
110
+ it "sends a tmail message" do
111
+ @smtp.should_receive(:send_message)
112
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
113
+ end
114
+
115
+ it "finishes the job" do
116
+ @smtp.should_receive(:finish)
117
+ Pony.transport_via_smtp(mock('tmail', :to => 'to', :from => 'from', :to_s => 'message'))
118
+ end
119
+
120
+ end
121
+ end
122
+
123
+ describe ":via option should over-ride the default transport mechanism" do
124
+ it "should send via sendmail if :via => sendmail" do
125
+ Pony.should_receive(:transport_via_sendmail)
126
+ Pony.mail(:to => 'joe@example.com', :via => :sendmail)
127
+ end
128
+
129
+ it "should send via smtp if :via => smtp" do
130
+ Pony.should_receive(:transport_via_smtp)
131
+ Pony.mail(:to => 'joe@example.com', :via => :smtp)
132
+ end
133
+
134
+ it "should raise an error if via is neither smtp nor sendmail" do
135
+ lambda { Pony.mail(:to => 'joe@plumber.com', :via => :pigeon) }.should raise_error(ArgumentError)
136
+ end
137
+ end
138
+
139
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chrisb-pony
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Chris Bielinski
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-08 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: hiroshi/pony + headers.
23
+ email: chris@shadowreactor.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - README.rdoc
32
+ - Rakefile
33
+ - lib/pony.rb
34
+ - chrisb-pony.gemspec
35
+ - spec/base.rb
36
+ - spec/pony_spec.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/chrisb/pony
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --inline-source
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: hiroshi/pony + headers.
72
+ test_files: []
73
+