⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtplib.py

📁 mallet是自然语言处理、机器学习领域的一个开源项目。
💻 PY
📖 第 1 页 / 共 2 页
字号:
        if name:            self.putcmd("helo", name)        else:            self.putcmd("helo", socket.getfqdn())        (code,msg)=self.getreply()        self.helo_resp=msg        return (code,msg)    def ehlo(self, name=''):        """ SMTP 'ehlo' command.        Hostname to send for this command defaults to the FQDN of the local        host.        """        self.esmtp_features = {}        if name:            self.putcmd("ehlo", name)        else:            self.putcmd("ehlo", socket.getfqdn())        (code,msg)=self.getreply()        # According to RFC1869 some (badly written)        # MTA's will disconnect on an ehlo. Toss an exception if        # that happens -ddm        if code == -1 and len(msg) == 0:            self.close()            raise SMTPServerDisconnected("Server not connected")        self.ehlo_resp=msg        if code != 250:            return (code,msg)        self.does_esmtp=1        #parse the ehlo response -ddm        resp=self.ehlo_resp.split('\n')        del resp[0]        for each in resp:            # To be able to communicate with as many SMTP servers as possible,            # we have to take the old-style auth advertisement into account,            # because:            # 1) Else our SMTP feature parser gets confused.            # 2) There are some servers that only advertise the auth methods we            #    support using the old style.            auth_match = OLDSTYLE_AUTH.match(each)            if auth_match:                # This doesn't remove duplicates, but that's no problem                self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \                        + " " + auth_match.groups(0)[0]                continue            # RFC 1869 requires a space between ehlo keyword and parameters.            # It's actually stricter, in that only spaces are allowed between            # parameters, but were not going to check for that here.  Note            # that the space isn't present if there are no parameters.            m=re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*)',each)            if m:                feature=m.group("feature").lower()                params=m.string[m.end("feature"):].strip()                if feature == "auth":                    self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \                            + " " + params                else:                    self.esmtp_features[feature]=params        return (code,msg)    def has_extn(self, opt):        """Does the server support a given SMTP service extension?"""        return self.esmtp_features.has_key(opt.lower())    def help(self, args=''):        """SMTP 'help' command.        Returns help text from server."""        self.putcmd("help", args)        return self.getreply()    def rset(self):        """SMTP 'rset' command -- resets session."""        return self.docmd("rset")    def noop(self):        """SMTP 'noop' command -- doesn't do anything :>"""        return self.docmd("noop")    def mail(self,sender,options=[]):        """SMTP 'mail' command -- begins mail xfer session."""        optionlist = ''        if options and self.does_esmtp:            optionlist = ' ' + ' '.join(options)        self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender) ,optionlist))        return self.getreply()    def rcpt(self,recip,options=[]):        """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""        optionlist = ''        if options and self.does_esmtp:            optionlist = ' ' + ' '.join(options)        self.putcmd("rcpt","TO:%s%s" % (quoteaddr(recip),optionlist))        return self.getreply()    def data(self,msg):        """SMTP 'DATA' command -- sends message data to server.        Automatically quotes lines beginning with a period per rfc821.        Raises SMTPDataError if there is an unexpected reply to the        DATA command; the return value from this method is the final        response code received when the all data is sent.        """        self.putcmd("data")        (code,repl)=self.getreply()        if self.debuglevel >0 : print "data:", (code,repl)        if code != 354:            raise SMTPDataError(code,repl)        else:            q = quotedata(msg)            if q[-2:] != CRLF:                q = q + CRLF            q = q + "." + CRLF            self.send(q)            (code,msg)=self.getreply()            if self.debuglevel >0 : print "data:", (code,msg)            return (code,msg)    def verify(self, address):        """SMTP 'verify' command -- checks for address validity."""        self.putcmd("vrfy", quoteaddr(address))        return self.getreply()    # a.k.a.    vrfy=verify    def expn(self, address):        """SMTP 'verify' command -- checks for address validity."""        self.putcmd("expn", quoteaddr(address))        return self.getreply()    # some useful methods    def login(self, user, password):        """Log in on an SMTP server that requires authentication.        The arguments are:            - user:     The user name to authenticate with.            - password: The password for the authentication.        If there has been no previous EHLO or HELO command this session, this        method tries ESMTP EHLO first.        This method will return normally if the authentication was successful.        This method may raise the following exceptions:         SMTPHeloError            The server didn't reply properly to                                  the helo greeting.         SMTPAuthenticationError  The server didn't accept the username/                                  password combination.         SMTPException            No suitable authentication method was                                  found.        """        def encode_cram_md5(challenge, user, password):            challenge = base64.decodestring(challenge)            response = user + " " + hmac.HMAC(password, challenge).hexdigest()            return encode_base64(response, eol="")        def encode_plain(user, password):            return encode_base64("%s\0%s\0%s" % (user, user, password), eol="")        AUTH_PLAIN = "PLAIN"        AUTH_CRAM_MD5 = "CRAM-MD5"        AUTH_LOGIN = "LOGIN"        if self.helo_resp is None and self.ehlo_resp is None:            if not (200 <= self.ehlo()[0] <= 299):                (code, resp) = self.helo()                if not (200 <= code <= 299):                    raise SMTPHeloError(code, resp)        if not self.has_extn("auth"):            raise SMTPException("SMTP AUTH extension not supported by server.")        # Authentication methods the server supports:        authlist = self.esmtp_features["auth"].split()        # List of authentication methods we support: from preferred to        # less preferred methods. Except for the purpose of testing the weaker        # ones, we prefer stronger methods like CRAM-MD5:        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]        # Determine the authentication method we'll use        authmethod = None        for method in preferred_auths:            if method in authlist:                authmethod = method                break        if authmethod == AUTH_CRAM_MD5:            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)            if code == 503:                # 503 == 'Error: already authenticated'                return (code, resp)            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))        elif authmethod == AUTH_PLAIN:            (code, resp) = self.docmd("AUTH",                AUTH_PLAIN + " " + encode_plain(user, password))        elif authmethod == AUTH_LOGIN:            (code, resp) = self.docmd("AUTH",                "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))            if code != 334:                raise SMTPAuthenticationError(code, resp)            (code, resp) = self.docmd(encode_base64(password, eol=""))        elif authmethod == None:            raise SMTPException("No suitable authentication method found.")        if code not in [235, 503]:            # 235 == 'Authentication successful'            # 503 == 'Error: already authenticated'            raise SMTPAuthenticationError(code, resp)        return (code, resp)    def starttls(self, keyfile = None, certfile = None):        """Puts the connection to the SMTP server into TLS mode.        If the server supports TLS, this will encrypt the rest of the SMTP        session. If you provide the keyfile and certfile parameters,        the identity of the SMTP server and client can be checked. This,        however, depends on whether the socket module really checks the        certificates.        """        (resp, reply) = self.docmd("STARTTLS")        if resp == 220:            sslobj = socket.ssl(self.sock, keyfile, certfile)            self.sock = SSLFakeSocket(self.sock, sslobj)            self.file = SSLFakeFile(sslobj)        return (resp, reply)    def sendmail(self, from_addr, to_addrs, msg, mail_options=[],                 rcpt_options=[]):        """This command performs an entire mail transaction.        The arguments are:            - from_addr    : The address sending this mail.            - to_addrs     : A list of addresses to send this mail to.  A bare                             string will be treated as a list with 1 address.            - msg          : The message to send.            - mail_options : List of ESMTP options (such as 8bitmime) for the                             mail command.            - rcpt_options : List of ESMTP options (such as DSN commands) for                             all the rcpt commands.        If there has been no previous EHLO or HELO command this session, this        method tries ESMTP EHLO first.  If the server does ESMTP, message size        and each of the specified options will be passed to it.  If EHLO        fails, HELO will be tried and ESMTP options suppressed.        This method will return normally if the mail is accepted for at least        one recipient.  It returns a dictionary, with one entry for each        recipient that was refused.  Each entry contains a tuple of the SMTP        error code and the accompanying error message sent by the server.        This method may raise the following exceptions:         SMTPHeloError          The server didn't reply properly to                                the helo greeting.         SMTPRecipientsRefused  The server rejected ALL recipients                                (no mail was sent).         SMTPSenderRefused      The server didn't accept the from_addr.         SMTPDataError          The server replied with an unexpected                                error code (other than a refusal of                                a recipient).        Note: the connection will be open even after an exception is raised.        Example:         >>> import smtplib         >>> s=smtplib.SMTP("localhost")         >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]         >>> msg = '''\\         ... From: Me@my.org         ... Subject: testin'...         ...         ... This is a test '''         >>> s.sendmail("me@my.org",tolist,msg)         { "three@three.org" : ( 550 ,"User unknown" ) }         >>> s.quit()        In the above example, the message was accepted for delivery to three        of the four addresses, and one was rejected, with the error code        550.  If all addresses are accepted, then the method will return an        empty dictionary.        """        if self.helo_resp is None and self.ehlo_resp is None:            if not (200 <= self.ehlo()[0] <= 299):                (code,resp) = self.helo()                if not (200 <= code <= 299):                    raise SMTPHeloError(code, resp)        esmtp_opts = []        if self.does_esmtp:            # Hmmm? what's this? -ddm            # self.esmtp_features['7bit']=""            if self.has_extn('size'):                esmtp_opts.append("size=" + `len(msg)`)            for option in mail_options:                esmtp_opts.append(option)        (code,resp) = self.mail(from_addr, esmtp_opts)        if code != 250:            self.rset()            raise SMTPSenderRefused(code, resp, from_addr)        senderrs={}        if isinstance(to_addrs, types.StringTypes):            to_addrs = [to_addrs]        for each in to_addrs:            (code,resp)=self.rcpt(each, rcpt_options)            if (code != 250) and (code != 251):                senderrs[each]=(code,resp)        if len(senderrs)==len(to_addrs):            # the server refused all our recipients            self.rset()            raise SMTPRecipientsRefused(senderrs)        (code,resp) = self.data(msg)        if code != 250:            self.rset()            raise SMTPDataError(code, resp)        #if we got here then somebody got our mail        return senderrs    def close(self):        """Close the connection to the SMTP server."""        if self.file:            self.file.close()        self.file = None        if self.sock:            self.sock.close()        self.sock = None    def quit(self):        """Terminate the SMTP session."""        self.docmd("quit")        self.close()# Test the sendmail method, which tests most of the others.# Note: This always sends to localhost.if __name__ == '__main__':    import sys    def prompt(prompt):        sys.stdout.write(prompt + ": ")        return sys.stdin.readline().strip()    fromaddr = prompt("From")    toaddrs  = prompt("To").split(',')    print "Enter message, end with ^D:"    msg = ''    while 1:        line = sys.stdin.readline()        if not line:            break        msg = msg + line    print "Message length is " + `len(msg)`    server = SMTP('localhost')    server.set_debuglevel(1)    server.sendmail(fromaddr, toaddrs, msg)    server.quit()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -