2016-04-30 132 views
0

我有一個django應用程序,它希望使用smtplib和email.mime庫將文件從S3存儲桶附加到電子郵件。使用MIMEApplication將s3文件附加到smtplib lib電子郵件

import smtplib 
from email.mime.text import MIMEText 
from email.mime.multipart import MIMEMultipart 
from email.mime.application import MIMEApplication 

# This takes the files and attaches each one within the bucket to the email. The server keeps erroring on the "with open(path,'rb') as fil" . 

def attach_files(path_to_aws_bucket,msg,files=[]): 

    for f in files or []: 
     path = path_to_aws_bucket + f 
     with open(path,'rb') as fil: 
      msg.attach(MIMEApplication(
       fil.read(), 
       Content_Disposition='attachment; filename="{}"' .format(os.path.basename(f)), 
       Name=os.path.basename(f) 
      )) 

    return msg 

def build_message(toaddress,fromaddress,subject,body): 

    msg = MIMEMultipart('alternative') 
    msg['To'] = toaddress 
    msg['From'] = fromaddress 
    msg['Subject'] = subject 
    b = u"{}" .format(body) 
    content = MIMEText(b.encode('utf-8') ,'html','UTF-8') 

    msg.attach(content) 

    return msg 


def send_gmail(msg,username,password,fromaddress,toaddress): 

    server = smtplib.SMTP('smtp.gmail.com:587') 
    server.ehlo() 
    server.starttls() 
    server.login(username,password) 
    server.sendmail(fromaddress, toaddress , msg.as_string()) 
    server.quit() 

Python無法打開該文件,因爲它聲稱無論s3 url我給它不是一個有效的目錄。我的所有權限都是正確的。我嘗試使用urllib.opener打開文件並附加它,但它也拋出了一個錯誤。

不知道從哪裏走,想知道是否有人以前做過這個。謝謝!

+0

你在django/python環境中如何連接到s3?您是否將本地目錄映射到s3存儲桶? python open函數期望讀取本地文件系統,而不是s3。 – georgeofallages

回答

0

使用urllib的工作對我來說,看看下面的,我有這樣的lambda函數來發送電子郵件,其中包含的smtplib:

import smtplib 
from email.mime.application import MIMEApplication 
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText 
from email.header import Header 
from email.utils import formataddr 
import urllib 
# ['subject','from', 'from_name','to','cc','body','smtp_server','smtp_user','smtp_password'] 

def lambda_handler(event, context): 
    msg = MIMEMultipart('alternative') 
    msg['Subject'] = event['subject'] 
    msg['From'] = formataddr((str(Header(event['from_name'], 'utf-8')), event['from'])) 
    msg['To'] = event['to'] 
    msg['Cc'] = event['cc'] # this is comma separated field 

    # Create the body of the message (a plain-text and an HTML version). 
    text = "Look in a browser or on a mobile device this HTML msg" 
    html = event['body'] 

    # Record the MIME types of both parts - text/plain and text/html. 
    part1 = MIMEText(text, 'plain') 
    part2 = MIMEText(html, 'html') 

    # Attach parts into message container. 
    # According to RFC 2046, the last part of a multipart message, in this case 
    # the HTML message, is best and preferred. 
    msg.attach(part1) 
    msg.attach(part2) 

    # Attach files from S3 
    opener = urllib.URLopener() 
    myurl = "https://s3.amazonaws.com/bucket_name/file_name.pdf" 
    fp = opener.open(myurl) 

    filename = 'file_name.pdf' 
    att = MIMEApplication(fp.read(),_subtype="pdf") 
    fp.close() 
    att.add_header('Content-Disposition','attachment',filename=filename) 
    msg.attach(att) 

    # Create de SMTP Object to Send 
    s = smtplib.SMTP(event['smtp_server'], 587) 
    s.login(event['smtp_user'], event['smtp_password']) 
    s.sendmail(msg['From'], [msg['To']], msg.as_string()) 

    return True 
0

你有沒有考慮使用S3的get_object代替的smtplib?

from email.mime.text import MIMEText 
from email.mime.multipart import MIMEMultipart 
from email.mime.application import MIMEApplication 
import boto3 

msg = MIMEMultipart() 
new_body = "asdf" 
text_part = MIMEText(new_body, _subtype="html") 
msg.attach(text_part) 

filename='abc.pdf' 
msg["To"] = "[email protected]" 
msg["From"] = "[email protected]" 
s3_object = boto3.client('s3', 'us-west-2') 
s3_object = s3_object.get_object(Bucket=‘bucket-name’, Key=filename) 
body = s3_object['Body'].read() 

part = MIMEApplication(body, filename) 
part.add_header("Content-Disposition", 'attachment', filename=filename) 
msg.attach(part) 
ses_aws_client = boto3.client('ses', 'us-west-2') 
ses_aws_client.send_raw_email(RawMessage={"Data" : msg.as_bytes()})