From: Steve Tuckner Date: 2002-05-16T03:48:20+09:00 Subject: RE: Email attachments Here is the code off of Ruby Cookbook that you might have been thinking of... require "net/smtp" require "getoptlong" #�File:����CyOSendMimeMailSmtp.rb #�Author:��Oliver�Mensinger #�Version:�2002-01-22 #�Status:��Usable�and�stable�for�simple�mails�(incl.�binary�attachm.) # #�Description: #�Create�Mime�mail�with�text�and�attachments�and�send�it�via�SMTP # #�Changes: #�2002-01-22�After�Ian�reported�a�problem,�the�mail�server�address�is�now�gi ven #������������to�Net::SMTP::new�instead�to�Net:SMTP::start # #�Supported�functions:�text�part,�binary�attachments�read�from�file #�To�do:�html�part,�binary�attachment�given�to�method�as�parameter,�several� recipients�(cc,�bcc) class�CyOSendMimeMailSmtp ��attr_accessor�:text ��attr_accessor�:server,�:from,�:to,�:subject ��def�initialize() ����@boundary�=�createBoundary() ����@attachments�=�[]��#�or�Array.new,�attachments�are�stored�in�an�array,�e ach�index�is�an�hash�(see�attach�method) ����@server�=�"localhost" ����@subject�=�"no�subject" ����@from�=�@to�=�@text�=�"" ��end ��def�createBoundary() ����return�"----=_CyOSendMimeMailSmtp_Part_"�+�uniqueNumber() ��end ��private�:createBoundary ��#�create�an�unique�number,�length�variables ��def�uniqueNumber() ����return�sprintf("%02X",�rand(99999999�-�10000000)�+�10000000)�+��#�random �part ������sprintf("%02X",�Time.new.to_i)�+��#�machine�time ������sprintf("%02X",�$$)�+��#�process�number ������sprintf("%02X",�Time.new.usec())��#�micro�seconds�of�machine ��end ��private�:uniqueNumber ��#�attachBinaryFile(phy_filename,�real_filename�=�"") ��#�adds�a�file�and�converts�it�to�base64 ��#�phy_filename�is�the�physical�filename�(incl.�path)�of�a�file�that�must�e xist ��#�real_filename�will�be�the�name�of�the�file�in�the�mail�message ��#�if�real_filename�_is�not�given_,�it�will�be�the�physical�filename ��#�returns�true�if�file�exists�and�was�attached�to�mail,�otherwise�false ��def�attachBinaryFile(phy_filename,�real_filename�=�"") ����#�read�file�into�string�and�convert�it�to�base64 ����begin ������f�=�File.new(phy_filename); ������data�=�f.read() ������f.close() ����rescue ������return�false ����end ����data�=�[data].pack("m*"); ����real_filename�=�phy_filename�if�real_filename�==�"" ����#�the�very�special�problem�of�phy_filename�and�real_filename: ����#�the�physical�filename�could�by�something�like�/tmp/12367672647342342, ����#�as�an�external�binary�file�stored�outside�of�a�database,�where�the ����#�real�filename�is�the�original�filename�which�is�stored�in�the�database . ����#�so�we�take�the�real_filename�for�determining�the�files�type ����attachment�=�{�"type"�=>�contentType(real_filename),�"name"�=>�File.base name(real_filename),�"data"�=>�data�} ����@attachments.push(attachment) ��end ��def�contentType(filename) ����filename�=�File.basename(filename).downcase ����if�filename�=~�/\.jp(e?)g$/�then�return�"image/jpg"�end ����if�filename�=~�/\.gif$/�then�return�"image/gif"�end ����if�filename�=~�/\.htm(l?)$/�then�return�"text/html"�end ����if�filename�=~�/\.txt$/�then�return�"text/plain"�end ����if�filename�=~�/\.zip$/�then�return�"application/zip"�end ����#�more�types?! ����return�"application/octet-stream" ��end ��private�:contentType ��def�sendMail() ����raise�"mail�server�not�specified"�if�@server.length�==�0 ����raise�"sender�address�not�specified"�if�@from.length�==�0 ����raise�"receiver�address�not�specified"�if�@to.length�==�0 ����#raise�"nothing�to�send"�if�(@text.length�==�0)�&&�(@attachments.length� ==�0) ����smtp�=�Net::SMTP.new(@server) ����smtp.start() ����smtp.ready(@from,�@to)�do�|wa| ������wa.write("Reply-To:�#{@from}\r\n") ������wa.write("To:�#{@to}\r\n") ������wa.write("Subject:�#{@subject}\r\n") ������wa.write("MIME-Version:�1.0\r\n") ������#�add�multipart�header�if�we�have�got�attachments ������if�(@attachments.length�>�0) ��������wa.write("Content-Type:�multipart/mixed;�boundary=\"#{@boundary}\"\r \n") ��������wa.write("\r\n") ��������wa.write("This�is�a�multi-part�message�in�MIME�format.\r\n") ��������wa.write("\r\n") ������end ������#�add�text�part�if�given ������if�(@text.length�>�0) ��������#�add�boundary�if�we�are�multiparted,�otherwise�just�add�text ��������if�(@attachments.length�>�0) ����������wa.write("--#{@boundary}\r\n") ����������wa.write("Content-Type:�text/plain;�charset=\"iso-8859-1\"\r\n") ����������wa.write("Content-Transfer- Encoding:�8bit\r\n")��#�we�don't�take�care�of�very�old�mail�servers�with�7�b it�only ��������else ����������#�if�only�text�and�no�attachm.�we�give�the�encoding ����������wa.write("Content-Type:�text/plain;�charset=iso-8859-1\r\n") ����������wa.write("Content-Transfer-Encoding:�8bit\r\n") ��������end ��������wa.write("\r\n") ��������wa.write("#{@text}\r\n") ��������wa.write("\r\n") ������end ������#�add�attachments�if�given ������if�(@attachments.length�>�0) ��������@attachments.each�do�|part| ����������wa.write("--#{@boundary}\r\n") ����������wa.write("Content-Type:�#{part['type']};�name=\"#{part['name']}\"\ r\n") ����������wa.write("Content-Transfer-Encoding:�base64\r\n") ����������wa.write("Content-Disposition:�attachment;�filename=\"#{part['name ']}\"\r\n") ����������wa.write("\r\n") ����������wa.write("#{part['data']}")��#�no�more�need�for�\r\n�here! ����������wa.write("\r\n") ��������end ������end ������#�closing�boundary�if�multiparted ������wa.write("--#{@boundary}--\r\n")�if�(@attachments.length�>�0) ����end��#�smtp.ready(...) ��end��#�def�sendMail() end��#�class�CyOSendMimeMailSmtp =begin ��#�example�for�using�CyOSendMimeMailSmtp�class ��#require�"CyOSendMimeMailSmtp.rb" �mail�=�CyOSendMimeMailSmtp.new() ��mail.server��=�"localhost"��#�localhost�is�also�default ��mail.from����=�"cyo@localhost" ��mail.to������=�"Mensinger,�Oliver�" ��mail.subject�=�"1st�test�using�class�CyOSendMimeMailSmtp"��#�default�is�"n o�subject" ��mail.text����=�"I�love�Ruby!\n2nd�line." ��#if�(!mail.attachBinaryFile("/home/cyo/ruby.jpg")) ��#��puts�"could�not�attach�file" ��#end ��begin ����mail.sendMail() ��rescue ����puts�"error�on�sending:�#{$!}" ��end =end -----Original Message----- From: Mr. Sunblade [mailto:djberge@qwest.com] Sent: Wednesday, May 15, 2002 1:38 PM To: ruby-talk ML Subject: Email attachments Hi all, I'm looking for a way to send attachments via smtp. I looked at Tmail and RubyMail, but those only seem geared towards decoding mime-base64, not encoding. Perhaps I've missed something? I've searched out on google a bit, and came across this post by Oliver Mensinger. Unfortunately, rubycookbook.org doesn't see to be up any more. http://groups.google.com/groups?hl=en&threadm=003b01c1b01e%243a4e4500%246904 a8c0%40multitech.prv&rnum=2&prev=/groups%3Fhl%3Den%26q%3Dattachments%26meta% 3Dgroup%253Dcomp.lang.ruby Any ideas? Regards, Dan