global _dnspython_present

try:
    import dns.resolver
    _dnspython_present = True
except ImportError:
    _dnspython_present = False

import smtplib
import socket
import time
from email import MIMEText

from mint.mint_error import MailError
import xmlrpclib

def digMX(hostname):
    try:
        answers = dns.resolver.query(hostname, 'MX')
    except dns.resolver.NoAnswer:
        return None
    return answers

def sendMailWithChecks(fromEmail, fromEmailName, toEmail, subject, body):
    validateEmailDomain(toEmail)
    try:
        sendMail(fromEmail, fromEmailName, toEmail, subject, body)
    except smtplib.SMTPRecipientsRefused:
        raise MailError("Email could not be sent: Recipient refused by server.")
    except socket.error, e:
        raise MailError("Email could not be sent: %s" % str(e))


def validateEmailDomain(toEmail):
    toDomain = smtplib.quoteaddr(toEmail).split('@')[-1][0:-1]
    VALIDATED_DOMAINS = ('localhost', 'localhost.localdomain')
    # basically if we don't implicitly know this domain,
    # and we can't look up the DNS entry of the MX
    # use gethostbyname to validate the email address
    try:
        if not ((toDomain in VALIDATED_DOMAINS) or digMX(toDomain)):
            socket.gethostbyname(toDomain)
    except (socket.gaierror, dns.resolver.NXDOMAIN):
        raise MailError("Email could not be sent: Bad domain name.")


def sendMail(fromEmail, fromEmailName, toEmail, subject, body):
    """
    @param fromEmail: email address for the From: header
    @type fromEmail: str
    @param fromEmailName: name for the From: header
    @type fromEmailName: str
    @param toEmail: recipient's email address
    @type toEmail: str
    @param subject: Email subject
    @type subject: str
    @param body: Email body text
    @type body: str
    """

    msg = MIMEText.MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = '"%s" <%s>' % (fromEmailName, fromEmail)
    msg['To'] = toEmail

    s = smtplib.SMTP()
    try:
        rAPA = xmlrpclib.ServerProxy('http://localhost:8004/xmlrpc/')
        config = rAPA.configure.Notify.index()
        s = smtplib.SMTP(host=config['mailRelay'])               
    except:
        # This simply means that we couldn't contact rAPA to get the relay,
        # and so we attempt to send mail directly
        pass

    for i in range(2):
        try:
            _send(s, fromEmail, toEmail, msg)
        except smtplib.SMTPServerDisconnected:
            time.sleep(.3 + i * .2)
        else:
            return
    # If we got this far, we failed to send the email, so add something in the
    # logs.
    import logging
    log = logging.getLogger(__name__)
    log.error("Unable to send email to %s:\n%s", toEmail, body)

def _send(smtpconn, fromEmail, toEmail, msg):
    smtpconn.connect()
    smtpconn.sendmail(fromEmail, [toEmail], msg.as_string())
    smtpconn.close()

@@ -1954,31 +1954,8 @@
 il%0A%0A
-    s = smtplib.SMTP()%0A
     
@@ -1951,32 +1951,32 @@
 Email%0A%0A    try:%0A
+
         rAPA = x
@@ -2088,30 +2088,16 @@
     
-s = smtplib.SMTP(host=
+relay = 
 conf
@@ -2115,24 +2115,8 @@
 ay'%5D
-)               
 %0A   
@@ -2262,12 +2262,27 @@
     
-pass
+relay = '127.0.0.1'
 %0A%0A  
@@ -2331,17 +2331,60 @@
     
-_send(s, 
+s = smtplib.SMTP(host=relay)%0A            s.sendmail(
 from
@@ -2390,28 +2390,64 @@
 mEmail, 
+%5B
 toEmail
+%5D
 , msg
+.as_string())%0A            s.close(
 )%0A      
@@ -2704,16 +2704,16 @@
 name__)%0A
+
     log.
@@ -2772,156 +2772,4 @@
 dy)%0A
-%0Adef _send(smtpconn, fromEmail, toEmail, msg):%0A    smtpconn.connect()%0A    smtpconn.sendmail(fromEmail, %5BtoEmail%5D, msg.as_string())%0A    smtpconn.close()%0A

Fix SMTP connecting twice, causing hangs with external relays. (RBL-8759)