#! /Usr/bin/env python #-*-Coding: UTF-8 -*- _ Author _ = 'zoa chou' # See http://www.mudoom.com/Article/show/id/29.html for detail Import logging Import smtplib Import mimetypes Import socket From email import encoders From email. header import Header From email. mime. text import MIMEText, MIMENonMultipart From email. mime. base import MIMEBase From email. utils import parseaddr, formataddr Class Mailer (object ): Def _ init _ (self ): Pass Def send_mail (self, smtp_server, from_address, to_address, subject, body, files = None ): """ Main email sending program : Param smtp_server: dict Mail Server Settings : Keyword host: string smtp server address : Keyword port: int smtp server port number : Keyword user: string user Name : Keyword passwd: string Password : Keyword ssl: whether to enable ssl for bool. The default value is False. : Keyword timeout: int timeout. The default value is 10 s. : Param from_address: sender's email address : Param to_address: Recipient's email address : Param subject: Mail title : Param body: email content : Param files: attachment : Raise: NetworkError/MailerException """ # Formatting mail content Body = self. _ encode_utf8 (body) # Mail type Content_type = 'html' if body. startswith (' Msg = MIMENonMultipart () if files else MIMEText (body, content_type, 'utf-8 ') # Formatting mail data Msg ['from'] = self. _ format_address (from_address) Msg ['to'] = ','. join (self. _ format_list (to_address )) Msg ['subobject'] = self. _ encode_utf8 (subject) # Construct attachment data If files: Msg. attach (MIMEText (body, content_type, 'utf-8 ')) Cid = 0 For file_name, payload in files: File_name = self. _ encode_utf8 (file_name) Main_type, sub_type = self. _ get_file_type (file_name) If hasattr (payload, 'read '): Payload = payload. read () F_name = self. _ encode_header (file_name) Mime = MIMEBase (main_type, sub_type, filename = f_name) Mime. add_header ('content-disposition', 'attachment', filename = f_name) Mime. add_header ('content-id', '<% s>' % cid) Mime. add_header ('x-Attachment-id', '% s' % cid) Mime. set_payload (payload) Encoders. encode_base64 (mime) Msg. attach (mime) Cid + = 1 Host = smtp_server.get ('host ') Port = smtp_server.get ('Port ') User = smtp_server.get ('user ') Passwd = smtp_server.get ('passwd ') Ssl = smtp_server.get ('ssl ', False) Time_out = smtp_server.get ('timeout', 10) # Use the default port if no port is input If port is None or port = 0: If ssl: Port = 465 Else: Port = 25 Logging. debug ('send mail form % s to % s' % (msg ['from'], msg ['to']) Try: If ssl: # Enable the ssl connection mode Server = smtplib. SMTP_SSL ('% s: % d' % (host, port), timeout = time_out) Else: Server = smtplib. SMTP ('% s: % d' % (host, port), timeout = time_out) # Enable debugging mode # Server. set_debuglevel (1) # Try to log on if the user name and password exist If user and passwd: Server. login (user, passwd) # Send an email Server. sendmail (from_address, to_address, msg. as_string ()) Logging. debug ('mail sent success .') # Closing the stmp connection Server. quit () Handle t socket. gaierror, e: "The network cannot be connected """ Logging. exception (e) Raise NetworkError (e) Using t smtplib. SMTPServerDisconnected, e: "Network connection exception """ Logging. exception (e) Raise NetworkError (e) Failed t smtplib. SMTPException, e: "An error occurred while sending emails """ Logging. exception (e) Raise MailerException (e) Def _ format_address (self, s ): """ Format the email address : Param s: string email address : Return: string formatted email address """ Name, address = parseaddr (s) Return formataddr (self. _ encode_header (name), self. _ encode_utf8 (address ))) Def _ encode_header (self, s ): """ Format MIME-compliant header data : Param s: string data to be formatted : Return: formatted data """ Return Header (s, 'utf-8'). encode () Def _ encode_utf8 (self, s ): """ Format to UTF-8 encoding : Param s: string data to be formatted : Return: string formatted data """ If isinstance (s, unicode ): Return s. encode ('utf-8 ') Else: Return s Def _ get_file_type (self, file_name ): """ Obtain the attachment type : Param file_name: attachment file name : Return: dict attachment MIME """ S = file_name.lower () Pos = s. rfind ('.') If pos =-1: Return 'application', 'octet-stream' Ext = s [pos:] Mime = mimetypes. types_map.get (ext, 'application/octet-stream ') Pos = mime. find ('/') If pos = (-1 ): Return mime ,'' Return mime [: pos], mime [pos + 1:] Def _ format_list (self, address ): """ Format the recipient address to list : Param address: string/list recipient email : Return: list recipient email list """ L = address If isinstance (l, basestring ): L = [l] Return [self. _ format_address (s) for s in l] Class MailerException (Exception ): "Email sending exception """ Pass Class NetworkError (MailerException ): "Network exception """ Pass # Test for @ qq.com If _ name _ = '_ main __': Import sys Def prompt (prompt ): """ Receiving Terminal input data """ Sys. stdout. write (prompt + ":") Return sys. stdin. readline (). strip () From_address = prompt ("From (Only @ qq.com )") Passwd = prompt ("Password ") To_address = prompt ("To"). split (',') Subject = prompt ("Subject ") Print "Enter message, end with ^ D :" Msg ='' While 1: Line = sys. stdin. readline () If not line: Break Msg = msg + line Print "Message length is % d" % len (msg) # QQ mail default settings Smtp_server = {'host': 'smtp .qq.com ', 'Port': None, 'user': from_address, 'passwd': passwd, 'ssl': True} Mailer = Mailer () Try: Mailer. send_mail (smtp_server, from_address, to_address, subject, msg) Failed t MailerException, e: Print (e) |