示例#1
0
def send_queued_mail():
    """sends mail from the mail queue to smtplib for delivery.  Also,
    on successes, empties the mail queue and adds all emails to the
    sent_mail list."""
    now = datetime.datetime.now(g.tz)
    if not c.site:
        c.site = Default

    clear = False
    session = smtplib.SMTP(g.smtp_server)

    # convienence funciton for sending the mail to the singly-defined session and
    # marking the mail as read.
    def sendmail(email):
        try:
            session.sendmail(email.fr_addr, email.to_addr,
                             email.to_MIMEText().as_string())
            email.set_sent(rejected=False)
        # exception happens only for local recipient that doesn't exist
        except (smtplib.SMTPRecipientsRefused, smtplib.SMTPSenderRefused):
            # handle error and print, but don't stall the rest of the queue
            print "Handled error sending mail (traceback to follow)"
            traceback.print_exc(file=sys.stdout)
            email.set_sent(rejected=True)

    try:
        for email in Email.get_unsent(now):
            clear = True

            should_queue = email.should_queue()
            # check only on sharing that the mail is invalid
            if email.kind == Email.Kind.SHARE and should_queue:
                email.body = Share(username=email.from_name(),
                                   msg_hash=email.msg_hash,
                                   link=email.thing,
                                   body=email.body).render(style="email")
                email.subject = _("[reddit] %(user)s has shared a link with you") % \
                                {"user": email.from_name()}
                sendmail(email)
            elif email.kind == Email.Kind.OPTOUT:
                email.body = Mail_Opt(msg_hash=email.msg_hash,
                                      leave=True).render(style="email")
                email.subject = _("[reddit] email removal notice")
                sendmail(email)

            elif email.kind == Email.Kind.OPTIN:
                email.body = Mail_Opt(msg_hash=email.msg_hash,
                                      leave=False).render(style="email")
                email.subject = _("[reddit] email addition notice")
                sendmail(email)

            elif email.kind in (Email.Kind.FEEDBACK, Email.Kind.ADVERTISE):
                if email.kind == Email.Kind.FEEDBACK:
                    email.subject = "[feedback] feedback from '%s'" % \
                                    email.from_name()
                else:
                    email.subject = "[ad_inq] feedback from '%s'" % \
                                    email.from_name()
                sendmail(email)
            # handle failure
            else:
                email.set_sent(rejected=True)

    finally:
        session.quit()

    # clear is true if anything was found and processed above
    if clear:
        Email.handler.clear_queue(now)
示例#2
0
文件: emailer.py 项目: wqx081/reddit
def send_queued_mail(test=False):
    """sends mail from the mail queue to smtplib for delivery.  Also,
    on successes, empties the mail queue and adds all emails to the
    sent_mail list."""
    from r2.lib.pages import Share, Mail_Opt
    now = datetime.datetime.now(g.tz)
    if not c.site:
        c.site = DefaultSR()

    clear = False
    if not test:
        session = smtplib.SMTP(g.smtp_server)

    def sendmail(email):
        try:
            mimetext = email.to_MIMEText()
            if mimetext is None:
                print("Got None mimetext for email from %r and to %r" %
                      (email.fr_addr, email.to_addr))
            if test:
                print mimetext.as_string()
            else:
                session.sendmail(email.fr_addr, email.to_addr,
                                 mimetext.as_string())
                email.set_sent(rejected=False)
        # exception happens only for local recipient that doesn't exist
        except (smtplib.SMTPRecipientsRefused, smtplib.SMTPSenderRefused,
                UnicodeDecodeError, AttributeError, HeaderParseError):
            # handle error and print, but don't stall the rest of the queue
            print "Handled error sending mail (traceback to follow)"
            traceback.print_exc(file=sys.stdout)
            email.set_sent(rejected=True)

    try:
        for email in Email.get_unsent(now):
            clear = True

            should_queue = email.should_queue()
            # check only on sharing that the mail is invalid
            if email.kind == Email.Kind.SHARE:
                if should_queue:
                    email.body = Share(username=email.from_name(),
                                       msg_hash=email.msg_hash,
                                       link=email.thing,
                                       body=email.body).render(style="email")
                else:
                    email.set_sent(rejected=True)
                    continue
            elif email.kind == Email.Kind.OPTOUT:
                email.body = Mail_Opt(msg_hash=email.msg_hash,
                                      leave=True).render(style="email")
            elif email.kind == Email.Kind.OPTIN:
                email.body = Mail_Opt(msg_hash=email.msg_hash,
                                      leave=False).render(style="email")
            # handle unknown types here
            elif not email.body:
                print("Rejecting email with an empty body from %r and to %r" %
                      (email.fr_addr, email.to_addr))
                email.set_sent(rejected=True)
                continue
            sendmail(email)

    finally:
        if not test:
            session.quit()

    # clear is true if anything was found and processed above
    if clear:
        Email.handler.clear_queue(now)
示例#3
0
def _send_queued_mail(test=False):
    """sends mail from the mail queue to smtplib for delivery.  Also,
    on successes, empties the mail queue and adds all emails to the
    sent_mail list."""
    from r2.lib.pages import Share, Mail_Opt

    uids_to_clear = []
    if not test:
        session = smtplib.SMTP(g.smtp_server)
    else:
        session = None

    def sendmail_multiplexer(email):
        """Use mailgun for password resets.

        Use old sendmail for everything else
        """
        if email.kind == Email.Kind.RESET_PASSWORD:
            _sendmail_using_mailgun(email, test)
        else:
            _sendmail(email, session, test)

    try:
        for email in Email.get_unsent(datetime.datetime.now(pytz.UTC)):
            uids_to_clear.append(email.uid)

            should_queue = email.should_queue()
            # check only on sharing that the mail is invalid
            if not test:
                if email.kind == Email.Kind.SHARE:
                    if should_queue:
                        email.body = Share(
                            username=email.from_name(),
                            msg_hash=email.msg_hash,
                            link=email.thing,
                            body=email.body).render(style="email")
                    else:
                        email.set_sent(rejected=True)
                        continue
                elif email.kind == Email.Kind.OPTOUT:
                    email.body = Mail_Opt(msg_hash=email.msg_hash,
                                          leave=True).render(style="email")
                elif email.kind == Email.Kind.OPTIN:
                    email.body = Mail_Opt(msg_hash=email.msg_hash,
                                          leave=False).render(style="email")
                # handle unknown types here
                elif not email.body:
                    print("Rejecting email with empty body from %r and to %r" %
                          (email.fr_addr, email.to_addr))
                    email.set_sent(rejected=True)
                    continue
            exponential_retrier(lambda: sendmail_multiplexer(email),
                                should_retry_exception)
            g.log.info("Sent email from %r to %r", email.fr_addr,
                       email.to_addr)
    except:
        # Log exceptions here and re-throw to make sure we are not swallowing
        # elsewhere
        g.log.exception("Unable to deliver email")
        raise
    finally:
        g.stats.flush()
        if not test:
            session.quit()
            # always perform clear_queue_by_uids, even if we have an
            # unhandled exception
            if len(uids_to_clear) > 0:
                Email.handler.clear_queue_by_uids(uids_to_clear)