I'm using Ruby script and the "mail" gem to send emails.
Question - How could how to send a graph via email in Ruby without saving to disk? Is this possible? Which graphing tool would you recommend and would the "mail" gem support somehow streaming this out? (or it it a given you have to save to disk first) If it's possible/easy sample code lines should how to would be great....
Your complete answer.
This uses a pure Ruby PNG graph for simplicity; a real world app would likely use SVG, or fast native code, or a graph API.
#!/usr/bin/env ruby
=begin
How to send a graph via email in Ruby without saving to disk
Example code by Joel Parker Henderson at SixArm, [email protected]
http://stackoverflow.com/questions/9779565
You need two gems:
gem install chunky_png
gem install mail
Documentation:
http://rdoc.info/gems/chunky_png/frames
https://github.com/mikel/mail
=end
# Create a simple PNG image from scratch with an x-axis and y-axis.
# We use ChunkyPNG because it's pure Ruby and easy to write results;
# a real-world app would more likely use an SVG library or graph API.
require 'chunky_png'
png = ChunkyPNG::Image.new(100, 100, ChunkyPNG::Color::WHITE)
png.line(0, 50, 100, 50, ChunkyPNG::Color::BLACK) # x-axis
png.line(50, 0, 50, 100, ChunkyPNG::Color::BLACK) # y-axis
# We do IO to a String in memory, rather than to a File on disk.
# Ruby does this by using the StringIO class which akin to a stream.
# For more on using a string as a file in Ruby, see this blog post:
# http://macdevelopertips.com/ruby/using-a-string-as-a-file-in-ruby.html
io = StringIO.new
png.write(io)
io.rewind
# Create a mail message using the Ruby mail gem as usual.
# We create it item by item; you may prefer to create it in a block.
require 'mail'
mail = Mail.new
mail.to = '[email protected]'
mail.from = '[email protected]'
mail.subject = 'Hello World'
# Attach the PNG graph, set the correct mime type, and read from the StringIO
mail.attachments['graph.png'] = {
:mime_type => 'image/png',
:content => io.read
}
# Send mail as usual. We choose sendmail because it bypasses the OpenSSL error.
mail.delivery_method :sendmail
mail.deliver
I don't see why you couldn't. In mail's documentation, you can see this sample code :
mail = Mail.new do
from '[email protected]'
to '[email protected]'
subject 'Here is the image you wanted'
body File.read('body.txt')
add_file :filename => 'somefile.png', :content => File.read('/somefile.png')
end
mail.deliver!
You just have to replace target of :content => ...
with your in-memory file content. And that should be enough. There's no real need of having attachments saved, even temporarily, to disk since they are re-encoded in base64 and added at the end of your mail.
For the second part of your question, there's many plot/graph lib around there. See this question or this lib for instance.
There's not really one lib above the others for this kind of matters. There's many lib for many different usage and you have to choose what fits more your needs and your constraints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With