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)
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)
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)