Skip to content
This repository

Attachment Support (#26) #36

Closed
wants to merge 15 commits into from

4 participants

David Cornu Jeremy tylercollier Vasiliy Ermolovich
David Cornu

Write attachments to an attachments directory alongside plain.html and rich.html

Changes

  • Modified delivery_method.rb to use the text_part and html_part methods provided by mail to avoid rendering attachments as the plain version
  • Modified message.rb to write out the attachments and added an @attachments variable to simplify the template
  • Added links to the attachments in message.html.erb and changed styling accordingly
  • Modified delivery_method_spec.rb to test added functionality
David Cornu

@cj are the changes working out for you?

Jeremy

I successively used https://github.com/davidcornu/letter_opener.git to test attachments. Very nice.

Jeremy

bump.

Is there any technical reason this hasn't been merged?

Tyler Collier and others added some commits
Tyler Collier Regexp replacement of inline attachment urls with relative path, so t…
…hat e.g. images will shown in html body
25d9463
Tyler Collier Added a test 3f78683
David Cornu Merge pull request #1 from tylercollier/master
Inline attachments
ead65b4
tylercollier

Ditto: I successively used https://github.com/davidcornu/letter_opener.git to test attachments. Very nice.

Suggest merging this.

Ryan Bates ryanb referenced this pull request
Closed

Attachments? #26

Vasiliy Ermolovich
Collaborator

@davidcornu hey, thanks for the pull request. Could you rebase it against master? Thanks!

David Cornu

@nashby Will do

David Cornu

@nashby, I've rebased davidcornu/letter_opener#master against ryanb/letter_opener#master and pushed it to davidcornu/letter_opener#rebased as pushing to my own master would cause all sorts of havoc.

Let me know if you'd like me to open another pull request with that branch.

Vasiliy Ermolovich
Collaborator

@davidcornu yeah, please open a new PR. Thanks.

David Cornu

#48
Closing this pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
1  lib/letter_opener.rb
... ... @@ -1,6 +1,7 @@
1 1 require "fileutils"
2 2 require "digest/sha1"
3 3 require "cgi"
  4 +require "uri"
4 5 require "launchy"
5 6
6 7 require "letter_opener/message"
4 lib/letter_opener/delivery_method.rb
@@ -6,7 +6,9 @@ def initialize(options = {})
6 6
7 7 def deliver!(mail)
8 8 location = File.join(@options[:location], "#{Time.now.to_i}_#{Digest::SHA1.hexdigest(mail.encoded)[0..6]}")
9   - messages = mail.parts.map { |part| Message.new(location, mail, part) }
  9 + messages = []
  10 + messages << Message.new(location, mail, mail.html_part) if mail.html_part
  11 + messages << Message.new(location, mail, mail.text_part) if mail.text_part
10 12 messages << Message.new(location, mail) if messages.empty?
11 13 messages.each { |message| message.render }
12 14 Launchy.open(URI.parse("file://#{messages.first.filepath}"))
23 lib/letter_opener/message.html.erb
@@ -6,7 +6,7 @@
6 6 top: 0px;
7 7 left: 0;
8 8 width: 100%;
9   - height: 85px;
  9 + height: 90px;
10 10 padding: 10px 0 0 0;
11 11 margin: 0;
12 12 background: #fff;
@@ -22,7 +22,7 @@
22 22 }
23 23
24 24 #message_headers dt {
25   - width: 60px;
  25 + width: 100px;
26 26 padding: 1px;
27 27 float: left;
28 28 text-align: right;
@@ -31,7 +31,7 @@
31 31 }
32 32
33 33 #message_headers dd {
34   - margin-left: 70px;
  34 + margin-left: 110px;
35 35 padding: 1px;
36 36 }
37 37
@@ -51,7 +51,7 @@
51 51 }
52 52
53 53 body {
54   - margin-top: 96px !important;
  54 + margin-top: 101px !important;
55 55 }
56 56 </style>
57 57
@@ -68,13 +68,24 @@
68 68
69 69 <dt>To:</dt>
70 70 <dd><%= mail.to.join(", ") %></dd>
  71 +
  72 + <dt>Attachments:</dt>
  73 + <dd>
  74 + <% if @attachments.size > 0 %>
  75 + <% @attachments.each do |filename, path| %>
  76 + <a href="<%= path %>"><%= filename %></a>&nbsp;
  77 + <% end %>
  78 + <% else %>
  79 + None
  80 + <% end %>
  81 + </dd>
71 82 </dl>
72 83
73 84 <% if mail.multipart? %>
74 85 <p class="alternate">
75   - <% if type == "plain" %>
  86 + <% if type == "plain" && mail.html_part %>
76 87 <a href="rich.html">View HTML version</a>
77   - <% else %>
  88 + <% elsif type == "rich" && mail.text_part %>
78 89 <a href="plain.html">View plain text version</a>
79 90 <% end %>
80 91 </p>
23 lib/letter_opener/message.rb
@@ -6,10 +6,24 @@ def initialize(location, mail, part = nil)
6 6 @location = location
7 7 @mail = mail
8 8 @part = part
  9 + @attachments = []
9 10 end
10 11
11 12 def render
12 13 FileUtils.mkdir_p(@location)
  14 +
  15 + if mail.attachments.size > 0
  16 + attachments_dir = File.join(@location,'attachments')
  17 + FileUtils.mkdir_p(attachments_dir)
  18 + mail.attachments.each do |attachment|
  19 + path = File.join(attachments_dir, attachment.filename)
  20 + unless File.exists?(path) # true if other parts have already been rendered
  21 + File.open(path, 'wb') { |f| f.write(attachment.body.raw_source) }
  22 + end
  23 + @attachments << [attachment.filename, "attachments/#{URI.escape(attachment.filename)}"]
  24 + end
  25 + end
  26 +
13 27 File.open(filepath, 'w') do |f|
14 28 f.write ERB.new(template).result(binding)
15 29 end
@@ -28,7 +42,14 @@ def content_type
28 42 end
29 43
30 44 def body
31   - @body ||= (@part && @part.body || @mail.body).to_s
  45 + if !@body_string
  46 + @body_string = (@part && @part.body || @mail.body).to_s
  47 + mail.attachments.each do |attachment|
  48 + @body_string.gsub!(attachment.url, "attachments/#{attachment.filename}")
  49 + end
  50 + @body = @body_string
  51 + end
  52 + @body
32 53 end
33 54
34 55 def from
36 spec/letter_opener/delivery_method_spec.rb
@@ -46,5 +46,41 @@
46 46 html.should include("View plain text version")
47 47 html.should include("<h1>This is HTML</h1>")
48 48 end
  49 +
  50 + it "saves attachments into a seperate directory" do
  51 + mail = Mail.deliver do
  52 + from 'foo@example.com'
  53 + to 'bar@example.com'
  54 + subject 'With attachments'
  55 + text_part do
  56 + body 'This is <plain> text'
  57 + end
  58 + attachments[File.basename(__FILE__)] = File.read(__FILE__)
  59 + end
  60 + attachment_path = Dir["#{@location}/*/attachments/#{File.basename(__FILE__)}"].first
  61 + File.exists?(attachment_path).should == true
  62 + text = File.read(Dir["#{@location}/*/plain.html"].first)
  63 + text.should include(File.basename(__FILE__))
  64 + end
  65 +
  66 + it "replaces inline attachment urls" do
  67 + mail = Mail.deliver do
  68 + from 'foo@example.com'
  69 + to 'bar@example.com'
  70 + subject 'With attachments'
  71 + attachments[File.basename(__FILE__)] = File.read(__FILE__)
  72 + url = attachments[0].url
  73 + html_part do
  74 + content_type 'text/html; charset=UTF-8'
  75 + body "Here's an image: <img src='#{url}' />"
  76 + end
  77 + end
  78 + attachment_path = Dir["#{@location}/*/attachments/#{File.basename(__FILE__)}"].first
  79 + File.exists?(attachment_path).should == true
  80 + text = File.read(Dir["#{@location}/*/rich.html"].first)
  81 + mail.parts[0].body.should include(mail.attachments[0].url)
  82 + text.should_not include(mail.attachments[0].url)
  83 + text.should include("attachments/#{File.basename(__FILE__)}")
  84 + end
49 85 end
50 86

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.