How to unzip a zip attachment from IMAP

Hi,

I used this code snippet to get the attachment from an email using imap in python2.5.

if part.get_content_type() == 'application/octet-stream':
                csv_zip = str(part.get_payload(decode=1))

OK...now what?  I tried file = zipfile.ZipFile(csv_zip) but I got this error...

Traceback (most recent call last):
  File "/home/davidmontgom/workspace/ans_console_adnetscales4/cgi-bin/imap/test.py", line 93, in <module>
    file = zipfile.ZipFile(csv_zip)
  File "/usr/lib/python2.5/zipfile.py", line 339, in __init__
    self.fp = open(file, modeDict[mode])
TypeError: file() argument 1 must be (encoded string without NULL bytes), not str


How do I extract the contents in python.  I know it is a csv file.

Please be ;precise...I am new to this....

thanks
dmontgomAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ramromconsultant Commented:
I have little experience with zipfile. The manual says that csv_zip must be a file or file-like object. Try writing csv_zip to a file then use zipfile.ZipFile(csv_zip_filename).

Also since "file" is a built-in I suggest not using it as a variable name.

Check out the csv module for processing the unzipped results.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dmontgomAuthor Commented:
Thanks....easy..but I would think there would be a way to do it without having to save to a file....
0
ramromconsultant Commented:
You can use a file-like object. See

4.5 StringIO -- Read and write strings as files

This module implements a file-like class, StringIO, that reads and writes a string buffer (also known as memory files).
0
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

Dave HoweSoftware and Hardware EngineerCommented:
the problem here is that you have a variable *containing* a zipfile, and zipfile expects the filename for a zipfile, not to have an actual zipfile passed as the argument. you will need to write out the output of the get_payload to a temp file, then pass the name of that file to zipfile.ZipFile()
0
Dave HoweSoftware and Hardware EngineerCommented:
ramrom: I looked at using StringIO, but that gives you a file handle, not something you could pass as a filename to ZipFile() - of course, if you *have* found a way to do that, I am all ears...
0
ramromconsultant Commented:
12.4.1 ZipFile Objects

class ZipFile( file[, mode[, compression[, allowZip64]]])

Open a ZIP file, where file can be either a path to a file (a string) or a file-like object.
0
Dave HoweSoftware and Hardware EngineerCommented:
ramrom: yes, I know. but StringIO doesn't give you a path to a file or file-like object. it gives you a file handle, which is different
0
ramromconsultant Commented:
The following works for me:
import StringIO
output = StringIO.StringIO()
import zipfile
x = zipfile.ZipFile(output, 'w')
x.writestr('foo', "this is a test")

Open in new window

0
Dave HoweSoftware and Hardware EngineerCommented:
My apologies, ramrom - you are correct. The following test code worked perfectly for me:


import email
import StringIO
import zipfile
emlfile = open("Test.eml")
msg = email.message_from_file(emlfile)
for msgpart in msg.walk():
	if msgpart.get_content_type() == 'application/octet-stream':
		zipstring=msgpart.get_payload(decode=1)
zipstrio = StringIO.StringIO(zipstring)
zipobj = zipfile.ZipFile(zipstrio,'r')
zipobj.printdir()
zipobj.close()
zipstrio.close()
emlfile.close()

Open in new window

0
Dave HoweSoftware and Hardware EngineerCommented:
Slightly longer example :)
import email, StringIO, zipfile
import csv
emlfile = open("Test.eml")
msg = email.message_from_file(emlfile)
for msgpart in msg.walk():
	if msgpart.get_content_type() == 'application/octet-stream':
		zipstring=msgpart.get_payload(decode=1)
zipstrio = StringIO.StringIO(zipstring)
zipobj = zipfile.ZipFile(zipstrio,'r')
csvobj = zipobj.read(zipobj.namelist()[0])
csvread = csv.DictReader(csvobj.split())
for csvrow in csvread:
	print csvrow
zipobj.close()
zipstrio.close()
emlfile.close()

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Email Protocols

From novice to tech pro — start learning today.