简体   繁体   中英

Unzip email attachment in memory using python and then send it in a post request

I'm trying to open an email with an attachment using python code and then send the unzipped file in a post request to a php script.

The attachment is always a zip file with a single csv file inside it.

import requests
import imaplib
import email
import os
from zipfile import ZipFile

# Open zip file and return it with a different name.
def extract_zip(input_zip):
    input_zip=ZipFile(input_zip)
    return {'file': ('report.csv', input_zip.open(input_zip.namelist()[0], 'r'))}

# Connect to gmail server.
mail=imaplib.IMAP4_SSL('imap.gmail.com')
mail.login("z@z","z")
mail.list()
mail.select("inbox")

typ, msgs = mail.search(None, '(SUBJECT "Report")')
msgs = msgs[0].split()
data_file = '';

for emailid in msgs:
    resp, data = mail.fetch(emailid, "(RFC822)")
    email_body = data[0][1] 
    m = email.message_from_string(email_body)

    if m.get_content_maintype() != 'multipart':
        continue

    for part in m.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue

        filename=part.get_filename()
        if filename is not None:
            data_file = extract_zip(filename) # Error Here

# Send the file to a data.php on a localhost,
# Text output should be file content.
http_post_request = requests.post("http://localhost/data.php", files=data_file)
if(http_post_request.status_code != 200):
    print 'Error sending POST request'
print http_post_request.text

The problem is that the code expects the zip file name to be a string of the location / name of the file. Which I have no idea how to do when I want to open an attachment I got in an email.

If I pass the filename it will simply give me a file-not-found error.

How can I get the path to the attachment without saving it to disk?

The solution I came up with thanks to @Nullman :

I took the payload of the attachment, decoded it and used io.BytesIO to create a file stream (file like object).

import requests
import imaplib
import email
import os
import io
from zipfile import ZipFile

# Open zip file and return it with a different name.
def extract_zip(input_zip):
    input_zip=ZipFile(input_zip)
    return {'file': ('report.csv', input_zip.open(input_zip.namelist()[0], 'r'))}

# Connect to gmail server.
mail=imaplib.IMAP4_SSL('imap.gmail.com')
mail.login("z@z","z")
mail.list()
mail.select("inbox")

typ, msgs = mail.search(None, '(SUBJECT "Report")')
msgs = msgs[0].split()
data_file = '';

for emailid in msgs:
    resp, data = mail.fetch(emailid, "(RFC822)")
    email_body = data[0][1] 
    m = email.message_from_string(email_body)

    if m.get_content_maintype() != 'multipart':
        continue

    for part in m.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue

        filename=part.get_filename()
        if filename is not None:
            # Get the payload bytes into a file like object:
            file_bytes = io.BytesIO(part.get_payload(decode=True))
            data_file = extract_zip(file_bytes)

# Send the file to a data.php on a localhost,
# Text output should be file content.
http_post_request = requests.post("http://localhost/data.php", files=data_file)
if(http_post_request.status_code != 200):
    print 'Error sending POST request'
print http_post_request.text

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM