Python – Mass-Mail w/ Attachment

I wrote a Python script today to mass-mail files to our clients. Our wonderful ERP system screwed up again, leaving us with PDFs of the information we needed to send out, the filenames being prefixed with a unique ID per-recipient. Rather than re-generate all documents and have them sent out properly (which likely wouldn’t have happened due to bugs in the system from a recent upgrade) we wrote this script to mail out the documents we already had. We created a CSV file with two columns: column one has the unique filename prefix, column two has the corresponding recipient’s email address.

import csv
import os
import smtplib
import mimetypes
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText

def readCSV():
    clientCSVList = []
    try:
        #set below to the CSV file you want to read.  Two columns:
        #1 - file prefix to search
        #2 - email address to send file to 
        with open("csvFile", 'rb') as csvfile: 
            clientReader = csv.reader(csvfile, delimiter=',')

            missing = 0
            for clientNum, email in clientReader:
                found = False
                for file in os.listdir("folder_with_files"):
                    if file.startswith(clientNum):
                        clientCSVList.append([clientNum, email, file])
                        found = True
                        continue
                if found == False:
                    missing += 1
                    print clientNum + " " + email

        print clientCSVList
        print "Missing: " + str(missing)
    except Exception as e:
        print "Exception: " + str(e.args)

    try:
        for client in clientCSVList:
            send_email("sender@domain.com", client[1], "Email Subject Here", "This text is supposed to be the body, but doesn't seem to appear", client[2])
            print client[0] + " Success"

    except Exception as e:
        print "Exception: " + str(e.args)
        print client[0] + " Failure"

def send_email(sender, receiver, subject, message, fileattachment=None):
    emailfrom = sender
    emailto = receiver
    fileToSend = fileattachment
    username = "smtp_username"
    password = "smtp_password"

    msg = MIMEMultipart()
    msg["From"] = emailfrom
    msg["To"] = emailto
    msg["Subject"] = subject
    msg["Message"] = message
    msg.preamble = message

    ctype, encoding = mimetypes.guess_type(fileToSend)
    if ctype is None or encoding is not None:
        ctype = "application/octet-stream"

    maintype, subtype = ctype.split("/", 1)

    if maintype == "text":
        fp = open(fileToSend)
        # Note: we should handle calculating the charset
        attachment = MIMEText(fp.read(), _subtype=subtype)
        fp.close()
    elif maintype == "image":
        fp = open(fileToSend, "rb")
        attachment = MIMEImage(fp.read(), _subtype=subtype)
        fp.close()
    elif maintype == "audio":
        fp = open(fileToSend, "rb")
        attachment = MIMEAudio(fp.read(), _subtype=subtype)
        fp.close()
    else:
        fp = open(fileToSend, "rb")
        attachment = MIMEBase(maintype, subtype)
        attachment.set_payload(fp.read())
        fp.close()
        encoders.encode_base64(attachment)
    attachment.add_header("Content-Disposition", "attachment", filename=fileToSend)
    msg.attach(attachment)

    server = smtplib.SMTP("server:25") #insert SMTP server:port in quotes
    server.starttls()
    server.login(username,password)
    server.sendmail(emailfrom, emailto, msg.as_string())
    server.quit()

def main():
    readCSV()

if __name__ == "__main__":
    main()