0
votes

This is a weird issue that is bugging me since the past 2 days. I wrote a simple send mail function that uses smtplib to send emails with image as attachment.

The problem is the body part gets concatenated to the Subject line. If I dont use a MIME message and just a string, they are separated out correctly. But, then normal strings don't allow image attachments.

Any library that I am missing here?

Please the code below:

# -*- coding: utf-8 -*-
"""
Created on Tue Jun 14 20:08:00 2016

@author: HOME
"""

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText 
import base64
import time
import datetime

print str(datetime.datetime.now())


def send_mail(pwd):

    password = base64.b64decode(pwd)

    # in the prod system, ask the mail exchange server and port

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo()
    server.starttls()

    server.login('[email protected]', password)

    msg = MIMEMultipart()

    body = "\nThe message body is this one. Thanks \n\n"
    subject = "Your daily digest " + str(datetime.datetime.now())

    msg['From'] = "[email protected]"
    msg['To'] = "[email protected]"

    # I was hoping that creating a string in the subject should parse for newline and automatically pick the 2nd line onwards as body
    # If I send mail using the commented code (line 46 t0 line 52), the subject and body are different. But I am unable to attach images
    # but if i use the MIMEMultipart message , then i can attach images, but the body comes in the subject line 
    msg['Subject'] = "\r\n".join([subject,"",body])

    #msg.attach(MIMEText(body,'text'))
    msg.preamble = 'Daily Updates'
    """
    msg = "\r\n".join([
    "From: [email protected]",
    "To: [email protected]",
    "Subject: Daily digest " + str(datetime.datetime.now()),
    "",
    "Good Morning, How are you ? "
    ])

    """
    # Image attachment code
    fp = open("D://sample.png",'rb')
    img = MIMEImage(fp.read())
    msg.attach(img)

    print msg
    #try:
    server.sendmail('[email protected]','[email protected]',msg.as_string())
    print "Mail send successfully to [email protected]"
    server.close()
    #except:
    #   print "Mail not sent"

if __name__ == '__main__':
    pwd = base64.b64encode('howdy')
    send_mail(pwd)
2

2 Answers

0
votes

I was hoping that creating a string in the subject should parse for newline and automatically pick the 2nd line onwards as body

No such guarantees are made anywhere in the documentation. You're joining the subject and body and setting them as the subject, so that's what you get.

If I dont use a MIME message and just a string, they are separated out correctly. But, then normal strings don't allow image attachments.

I take this to mean building a message as a string manually. That means you built it correctly, but that has nothing to do with how the Message object works.

To include the body in the multipart message follow the examples:

from email.mime.text import MIMEText

...

msg.attach(MIMEText(body, 'plain'))
0
votes

I created yagmail to make it very easy to send attachments.

import yagmail
yag = yagmail.SMTP(username, password)
yag.send(to="[email protected]", 
         subject="Daily digest " + str(datetime.datetime.now()), 
         contents="Good Morning, How are you ?", 
         attachments="D://sample.png")

For an introductory read, please have a look here.