Advertisement
Guest User

Untitled

a guest
Jun 1st, 2017
1,006
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.67 KB | None | 0 0
  1. Python send email with html and plain versions and attachments
  2.  
  3. import os.path
  4. import types
  5.  
  6. import smtplib
  7. import email.Message
  8. from email import Encoders
  9. from email.MIMEAudio import MIMEAudio
  10. from email.MIMEBase import MIMEBase
  11. from email.MIMEMultipart import MIMEMultipart
  12. from email.MIMEImage import MIMEImage
  13. from email.MIMEText import MIMEText
  14. import mimetypes
  15.  
  16. class SendMail(object):
  17.     '''The swiss army knife of email programs. Here are some of the features:
  18.  
  19.        1) you can build parts of the message in pieces. This is useful for when
  20.        you need to send out lots of emails with similar content. For example,
  21.        I needed to added a unique unsubcribe token to each email. The email had
  22.        a large attachment. This made it so I did not have to reprocess the
  23.        attachment for each email.
  24.  
  25.        2) allows you to include both html and plain text versions of the message
  26.        in the email.
  27.  
  28.        3) handles the encoding of a wide range of attachment file types.
  29.  
  30.        4) sends the email with the TLS protocol if the server uses TLS
  31.           gmail uses TLS.
  32.  
  33.    This code was pieced together from snippets of code found using google.
  34.  
  35.    How to use? Just look down the list of methods. Use the ones you need.
  36.    It should be pretty obvious. You will need to set the attributes:
  37.    "from_email_addr" and "subject" directly before calling send.
  38.  
  39.    This code has NOT been throughly tested because there are too many combinations.
  40.    I just test the combinations I need.
  41.    '''
  42.     def __init__(self,smtpserver,smtpuser = '',smtppass = '',port=None, debug=False):
  43.         self.smtpserver=smtpserver
  44.         self.smtpuser=smtpuser
  45.         self.smtppass=smtppass
  46.         self.port=port
  47.         self.debug=debug
  48.         self.encoded_attachments=[]
  49.         self.cc_list=[]
  50.  
  51.     def add_attachments(self,attachment_list):
  52.         '''attachment_list: a list of full file paths'''
  53.         self.encoded_attachments=[]
  54.         for path in attachment_list:
  55.             dirname,filename=os.path.split(path)
  56.             # Guess the content type based on the file's extension.  Encoding
  57.             # will be ignored, although we should check for simple things like
  58.             # gzip'd or compressed files.
  59.             ctype, encoding = mimetypes.guess_type(path)
  60.             if ctype is None or encoding is not None:
  61.                 # No guess could be made, or the file is encoded (compressed), so
  62.                 # use a generic bag-of-bits type.
  63.                 ctype = 'application/octet-stream'
  64.             maintype, subtype = ctype.split('/', 1)
  65.             if maintype == 'text':
  66.                 fp = open(path)
  67.                 # Note: we should handle calculating the charset
  68.                 msg = MIMEText(fp.read(), _subtype=subtype)
  69.                 fp.close()
  70.             elif maintype == 'image':
  71.                 fp = open(path, 'rb')
  72.                 msg = MIMEImage(fp.read(), _subtype=subtype)
  73.                 fp.close()
  74.             elif maintype == 'audio':
  75.                 fp = open(path, 'rb')
  76.                 msg = MIMEAudio(fp.read(), _subtype=subtype)
  77.                 fp.close()
  78.             else:  # includes MS Word docs
  79.                 fp = open(path, 'rb')
  80.                 msg = MIMEBase(maintype, subtype)
  81.                 msg.set_payload(fp.read())
  82.                 fp.close()
  83.                 # Encode the payload using Base64
  84.                 Encoders.encode_base64(msg)
  85.             # Set the filename parameter
  86.             msg.add_header('Content-Disposition', 'attachment', filename=filename)
  87.             self.encoded_attachments.append(msg)
  88.  
  89.     def add_to(self,to_list):
  90.         self.to_list=to_list
  91.         self.to_str=','.join(to_list)
  92.  
  93.     def add_cc(self,cc_list):
  94.         self.cc_list=cc_list
  95.         self.cc_str=','.join(cc_list)
  96.  
  97.     def add_body(self,body):
  98.         if type(body) is types.StringType:
  99.             self.body=MIMEText(body,'plain')
  100.         else:
  101.             self.body=MIMEMultipart('alternative')
  102.             for k in body:
  103.                 self.body.attach(MIMEText(body[k],k))
  104.  
  105.     def send(self):
  106.         '''No error checking. It should just crash if some stuff is not setup. '''
  107.         message=MIMEMultipart()
  108.         message.preamble = 'You will not see this in a MIME-aware mail reader.\n'
  109.         message.epilogue = ''  # To guarantee the message ends with a newline
  110.         message.attach(self.body)
  111.  
  112.         message['To']=self.to_str
  113.         if self.cc_list:
  114.             message['CC']=self.cc_str
  115.  
  116.         # Set these attributes up directly before calling this method
  117.         message['Subject'] = self.subject
  118.         message['From']=self.from_email_addr
  119.  
  120.         print self.encoded_attachments
  121.         for a in self.encoded_attachments:
  122.             message.attach(a)
  123.  
  124.         # Send it
  125.         server = smtplib.SMTP(self.smtpserver,self.port)
  126.         try:
  127.             server.set_debuglevel(self.debug)
  128.             server.ehlo()
  129.             # If we can encrypt this session, do it
  130.             if server.has_extn('STARTTLS'):
  131.                 server.starttls()
  132.                 server.ehlo() # re-identify ourselves over TLS connection
  133.             server.login(self.smtpuser, self.smtppass)
  134.             smtpresult =server.sendmail(self.from_email_addr, self.to_list+self.cc_list, message.as_string())
  135.         finally:
  136.             server.quit()
  137.        
  138.         if smtpresult:
  139.             for recip in smtpresult.keys():
  140.                 print  """Could not delivery mail to: %s Server said: %s %s""" \
  141.                       % (recip, smtpresult[recip][0], smtpresult[recip][1])
  142.                 return False
  143.         else:
  144.             return True
  145.  
  146.     def send_simple_email(self,to_list,from_email_addr,subject,body,attachment_list=[],
  147.                           cc_list=[]):
  148.         '''A wrapper for if you do not need to do things in pieces. You can also use this
  149.        as a guide for how to build up an email in pieces.
  150.        '''
  151.         self.add_to(to_list)
  152.         self.add_cc(cc_list)
  153.         self.from_email_addr=from_email_addr
  154.         self.subject=subject
  155.         self.add_body(body)
  156.         self.add_attachments(attachment_list)
  157.         return self.send()
  158.        
  159.  
  160. if __name__=="__main__":
  161.     smtpuser = 'my_email@gmail.com'
  162.     smtppass=raw_input('Enter gmail password->')
  163.    
  164.     body={}
  165.     body['html']='<h1>hi</h1>'
  166.     body['plain']='hello'
  167.    
  168.     sm=SendMail('smtp.gmail.com', smtpuser = smtpuser, smtppass = smtppass, port=587)
  169.     r=sm.send_simple_email(['to_someone@yahoo.com'],'my_email@gmail.com','Test - from Fred',
  170.         body,attachment_list=[r'C:\Documents and Settings\my_media\uploads\Case-of-the-Week invite 02-24-10.doc'])
  171.     print r
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement