def send_all(): """ Send all eligible messages in the queue. """ # The actual backend to use for sending, defaulting to the Django default. # To make testing easier this is not stored at module level. EMAIL_BACKEND = getattr(settings, "MAILER_EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") lock = FileLock(EMAIL_LOCK_FILE) logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() deferred = 0 sent = 0 try: connection = None for message in prioritize(MAXIMUM_MAILS_PER_COMMAND): try: if connection is None: connection = get_connection(backend=EMAIL_BACKEND) logging.info("sending message [%s] '%s' to %s" % (message.id, message.subject, message.recipients)) email = message.email email.connection = connection email.send() message.set_sent() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: message.defer() logging.info("message deferred due to failure: %s" % err) deferred += 1 # Get new connection, it case the connection itself has an error. connection = None finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))
def send_all(): """ Send all eligible messages in the queue. """ # The actual backend to use for sending, defaulting to the Django default. # To make testing easier this is not stored at module level. EMAIL_BACKEND = getattr(settings, "MAILER_EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") lock = FileLock(getattr(settings, "MAILER_SEND_MAIL_LOCK", "send_mail")) logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() dont_send = 0 deferred = 0 sent = 0 try: connection = None for message in prioritize(): try: if connection is None: connection = get_connection(backend=EMAIL_BACKEND) logging.info("sending message '%s' to %s" % (message.subject.encode("utf-8"), u", ".join(message.to_addresses).encode("utf-8"))) if message.subject.encode("utf-8").find("edit-tweet") > 0: print "skipped" else: email = message.email email.connection = connection email.send() MessageLog.objects.log(message, 1) # @@@ avoid using literal result code sent += 1 message.delete() except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) # @@@ avoid using literal result code deferred += 1 # Get new connection, it case the connection itself has an error. connection = None finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))
def send_all(limit=None, timeout=None): """ Send all eligible messages in the queue. """ # Get lock so only one process sends at the same time lock = FileLock('send_mail') try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logger.info('Already locked.') return except LockTimeout: logger.info('Lock timed out.') return # Check for multiple mail hosts hosts = getattr(settings, 'EMAIL_HOSTS', None) if hosts is not None: from gargoyle import gargoyle for host, config in hosts.items(): if gargoyle.is_active('mailer-%s' % host): settings.EMAIL_HOST = config['host'] settings.EMAIL_USE_TLS = config['use_tls'] settings.EMAIL_PORT = config['port'] settings.EMAIL_HOST_USER = config['user'] settings.EMAIL_HOST_PASSWORD = config['password'] break # Start sending mails total, successes, failures = 0, 0, 0 try: for message in prioritize(): # Check limit if limit is not None and total >= int(limit): logger.info('Limit (%s) reached, stopping.' % limit) break # Check whitelist and don't send list if DontSendEntry.objects.has_address(message.to_address) or not in_whitelist(message.to_address): logger.info('Skipping mail to %s - on don\'t send list.' % message.to_address) MessageLog.objects.log(message, RESULT_MAPPING['don\'t send']) message.delete() else: try: logger.info('Sending message to %s' % message.to_address.encode("utf-8")) # Prepare body if message.html_body: msg = EmailMultiAlternatives(message.subject, message.message_body, message.from_address, [message.to_address]) msg.attach_alternative(message.html_body, 'text/html') else: msg = EmailMessage(message.subject, message.message_body, message.from_address, [message.to_address]) # Prepare attachments for attachment in message.attachment_set.all(): mimetype = attachment.mimetype or 'application/octet-stream' msg.attach(attachment.filename, attachment.attachment_file.read(), mimetype) # If a timeout is set, set up a signal to throw an error, and cancel it when the send is done if timeout is not None: signal.signal(signal.SIGALRM, _handle_timeout) signal.alarm(timeout) try: msg.send() finally: signal.alarm(0) else: msg.send() except (socket_error, UnicodeEncodeError, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError, smtplib.SMTPDataError), err: # Sending failed, defer message message.defer() logger.info('Message deferred due to failure: %s' % err) MessageLog.objects.log(message, RESULT_MAPPING['failure'], log_message=str(err)) failures += 1 else: # Sending succeeded MessageLog.objects.log(message, RESULT_MAPPING['success']) message.delete() successes += 1 total += 1
def send_all_throttled(): """ Send all eligible messages in the queue. Source: https://github.com/pinax/django-mailer/blob/master/mailer/engine.py This customized version will send only X mails per run. """ # The actual backend to use for sending, defaulting to the Django default. # To make testing easier this is not stored at module level. EMAIL_BACKEND = getattr( settings, 'MAILER_EMAIL_BACKEND', 'django.core.mail.backends.smtp.EmailBackend') lock = FileLock('send_mail') logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() deferred = 0 sent = 0 try: connection = None for message in prioritize(): try: if connection is None: connection = get_connection(backend=EMAIL_BACKEND) logging.info("sending message '%s' to %s" % (message.subject.encode("utf-8"), u", ".join(message.to_addresses).encode("utf-8"))) # NOQA email = message.email email.connection = connection email.send() MessageLog.objects.log(message, 1) message.delete() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: # NOQA message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) deferred += 1 # Get new connection, it case the connection itself has an # error. connection = None if sent == getattr(settings, 'MAILER_THROTTLE_AMOUNT', 25): break finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))
def send_all(max_messages=None): """ Send all eligible messages in the queue. """ # The actual backend to use for sending, defaulting to the Django default. # To make testing easier this is not stored at module level. EMAIL_BACKEND = getattr( settings, "MAILER_EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend" ) lock = FileLock("send_mail") logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() deferred = 0 sent = 0 try: connection = None for message in prioritize(): # Some providers, like SendGrid, has a limit on the number of emails per connection. if max_messages is not None and (sent + deferred) > max_messages: break try: if connection is None: connection = get_connection(backend=EMAIL_BACKEND) logging.info("sending message '{0}' to {1}".format( message.subject.encode("utf-8"), u", ".join(message.to_addresses).encode("utf-8")) ) email = message.email email.connection = connection email.send() MessageLog.objects.log(message, 1) # @@@ avoid using literal result code message.delete() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: # noqa message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) # @@@ avoid using literal result code # noqa deferred += 1 # Get new connection, it case the connection itself has an error. connection = None finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))
def send_all_throttled(): """ Send all eligible messages in the queue. Source: https://github.com/pinax/django-mailer/blob/master/mailer/engine.py This customized version will send only X mails per run. """ # The actual backend to use for sending, defaulting to the Django default. # To make testing easier this is not stored at module level. EMAIL_BACKEND = getattr(settings, 'MAILER_EMAIL_BACKEND', 'django.core.mail.backends.smtp.EmailBackend') lock = FileLock('send_mail') logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() deferred = 0 sent = 0 try: connection = None for message in prioritize(): try: if connection is None: connection = get_connection(backend=EMAIL_BACKEND) logging.info( "sending message '%s' to %s" % (message.subject.encode("utf-8"), u", ".join( message.to_addresses).encode("utf-8"))) # NOQA email = message.email email.connection = connection email.send() MessageLog.objects.log(message, 1) message.delete() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: # NOQA message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) deferred += 1 # Get new connection, it case the connection itself has an # error. connection = None if sent == getattr(settings, 'MAILER_THROTTLE_AMOUNT', 25): break finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))
def send_all(): """ Send all eligible messages in the queue. """ try: lock_path = settings.MAILER_LOCKFILE except AttributeError: lock_path = "send_mail" lock = FileLock(lock_path) logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() dont_send = 0 deferred = 0 sent = 0 try: connections = {} for message in prioritize(): try: connection = connections.get(message.get_priority_display()) if connection is None: connection = get_connection(backend=EMAIL_PRIORITY_BACKENDS.get(message.get_priority_display()) or EMAIL_BACKEND) connections[message.get_priority_display()] = connection logging.info("sending message '%s' to %s" % (message.subject.encode("utf-8"), u", ".join(message.to_addresses).encode("utf-8"))) email = message.email email.connection = connection email.send() MessageLog.objects.log(message, 1) # @@@ avoid using literal result code message.delete() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError) as err: message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) # @@@ avoid using literal result code deferred += 1 # Get new connection, it case the connection itself has an error. connection = None except Exception, err: if type(err) not in EMAIL_EXCEPTIONS: raise message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) # @@@ avoid using literal result code deferred += 1 # Get new connection, it case the connection itself has an error. connection = None finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred;" % (sent, deferred)) logging.info("done in %.2f seconds" % (time.time() - start_time))