[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Retrieve email attachments using Net::IMAP

luke

5/31/2006 8:21:00 AM

Hi,

I'm trying to write a Ruby script that will connect to my mail server
using IMAP, check for new email, and if an email has an attachment then
it will save the attachment into a certain local directory. And that's
it! I don't actually care about the contents of the email. This will be
simply a way of collecting files that are sent as attachments to a
certain email address.

I've been looking around for 2 nights and so far haven't been able to
find something myself that demonstrates how to retrieve attachments
using the Net::IMAP library, or using something that works into that
library.

I have my code to the point where it connects successfully to my mail
server, and then prints some subject lines just to say email is being
detected. I've tried googling, checking script libraries and reading
through the API docs for the standard library to no avail. Can someone
give me some pointers?

Thanks
Luke

6 Answers

luke

6/1/2006 10:04:00 AM

0

OK, I've made a bit of progress on this issue, but still I can't locate
where the binary file is, or work out how to initiate a transfer of it
to another local directory.

What I've got so far is below:

require 'net/imap'

imap = Net::IMAP.new('domain.name.com')
imap.authenticate('LOGIN', 'mailbox', 'password')
imap.select('INBOX')
imap.search(["SINCE", "8-Aug-2002"]).each do |message_id|
attach = imap.fetch(message_id, "BODY")[0].attr["BODY"]
puts "#{attach.parts[1].media_type}"
puts "#{attach.parts[1].param['NAME']}"
puts "#{attach.parts[1].subtype}"
puts "#{(attach.parts[1].size)/1024} kb"
end


It simply prints out information about the attachment, like this:

IMAGE
filename.jpg
JPEG
35 kb


I hope this isn't a really basic question, but what is the next step to
saving this file attachment?

Thanks
Luke

luke wrote:
> Hi,
>
> I'm trying to write a Ruby script that will connect to my mail server
> using IMAP, check for new email, and if an email has an attachment then
> it will save the attachment into a certain local directory. And that's
> it! I don't actually care about the contents of the email. This will be
> simply a way of collecting files that are sent as attachments to a
> certain email address.
>
> I've been looking around for 2 nights and so far haven't been able to
> find something myself that demonstrates how to retrieve attachments
> using the Net::IMAP library, or using something that works into that
> library.
>
> I have my code to the point where it connects successfully to my mail
> server, and then prints some subject lines just to say email is being
> detected. I've tried googling, checking script libraries and reading
> through the API docs for the standard library to no avail. Can someone
> give me some pointers?
>
> Thanks
> Luke

Dave Burt

6/1/2006 10:26:00 AM

0

luked wrote:
> OK, I've made a bit of progress on this issue, but still I can't locate
> where the binary file is, or work out how to initiate a transfer of it
> to another local directory.
>
> What I've got so far is below:
>
> require 'net/imap'
>
> imap = Net::IMAP.new('domain.name.com')
> imap.authenticate('LOGIN', 'mailbox', 'password')
> imap.select('INBOX')
> imap.search(["SINCE", "8-Aug-2002"]).each do |message_id|
> attach = imap.fetch(message_id, "BODY")[0].attr["BODY"]
> puts "#{attach.parts[1].media_type}"
> puts "#{attach.parts[1].param['NAME']}"
> puts "#{attach.parts[1].subtype}"
> puts "#{(attach.parts[1].size)/1024} kb"
> end
>
>
> It simply prints out information about the attachment, like this:
>
> IMAGE
> filename.jpg
> JPEG
> 35 kb
>
>
> I hope this isn't a really basic question, but what is the next step to
> saving this file attachment?

You should be hoping it _is_ a really basic question; that way someone
will be able to help you!

I have two pieces of advice. The first is trivial and won't help you
much: 'puts "#{foo}"' is the same as 'puts foo', so you should use the
latter for at least three of those four debug-print lines.

Secondly, you can find out what kind of object parts[1] is by printing
parts[1].class and what interesting methods it has by p'ing (it's an
array) parts[1].class.instance_methods(false).sort or (parts[1].methods
- Object.instance_methods).sort.

HTH
Dave

ts

6/1/2006 11:03:00 AM

0

>>>>> "l" == luked <lduncalfe@gmail.com> writes:


Try this

l> require 'net/imap'

l> imap = Net::IMAP.new('domain.name.com')
l> imap.authenticate('LOGIN', 'mailbox', 'password')
l> imap.select('INBOX')
l> imap.search(["SINCE", "8-Aug-2002"]).each do |message_id|
l> attach = imap.fetch(message_id, "BODY")[0].attr["BODY"]
l> puts "#{attach.parts[1].media_type}"
l> puts "#{attach.parts[1].param['NAME']}"
l> puts "#{attach.parts[1].subtype}"
l> puts "#{(attach.parts[1].size)/1024} kb"

puts imap.fetch(message_id, "BODY[2]")

l> end

it will give you a Net::IMAP::FetchData object


--

Guy Decoux

luke

6/2/2006 4:10:00 AM

0


Thanks, that's helped another step!

It's returning an Array with 1 element. When I print the array to
screen I get a whole lot of ASCII characters, and when I save the
contents of the Array to a file it creates a file that equals the file
size of the attachment.

The problem though is that this file that I'm saving is not a
recognisable jpg. It won't open when I try to view it, so I imagine
that I haven't copied the binary.

When I open the file in a text editor I see 1 line of characters that
starts with

#<struct Net::IMAP::FetchData seqno=1,
attr={"BODY[2]"=>"/9j/4AAQSkZJRgABAQAAAQABAAD/2w

So it looks like I've just saved information about the array rather
than the contents.

Luke


ts wrote:
> >>>>> "l" == luked <lduncalfe@gmail.com> writes:
>
>
> Try this
>
> l> require 'net/imap'
>
> l> imap = Net::IMAP.new('domain.name.com')
> l> imap.authenticate('LOGIN', 'mailbox', 'password')
> l> imap.select('INBOX')
> l> imap.search(["SINCE", "8-Aug-2002"]).each do |message_id|
> l> attach = imap.fetch(message_id, "BODY")[0].attr["BODY"]
> l> puts "#{attach.parts[1].media_type}"
> l> puts "#{attach.parts[1].param['NAME']}"
> l> puts "#{attach.parts[1].subtype}"
> l> puts "#{(attach.parts[1].size)/1024} kb"
>
> puts imap.fetch(message_id, "BODY[2]")
>
> l> end
>
> it will give you a Net::IMAP::FetchData object
>
>
> --
>
> Guy Decoux

Clifford Heath

6/2/2006 4:33:00 AM

0

luked wrote:
> Thanks, that's helped another step!
> It's returning an Array with 1 element.
> #<struct Net::IMAP::FetchData seqno=1,
> attr={"BODY[2]"=>"/9j/4AAQSkZJRgABAQAAAQABAAD/2w
>
> So it looks like I've just saved information about the array rather
> than the contents.

That looks like base64 encoding. Did you check to see whether
the MIME headers mentioned a Content-Transfer-Encoding or a
Content-Encoding? You'll need to apply the reverse encoding
to get back your attachment.

Clifford Heath.

ts

6/2/2006 10:54:00 AM

0

>>>>> "l" == luked <lduncalfe@gmail.com> writes:

l> The problem though is that this file that I'm saving is not a
l> recognisable jpg. It won't open when I try to view it, so I imagine
l> that I haven't copied the binary.

It's in base64 : you must decode it


--

Guy Decoux