django-orchestra/orchestra/contrib/mailer/engine.py

59 lines
2.0 KiB
Python
Raw Normal View History

2015-05-04 19:52:53 +00:00
import smtplib
2015-05-07 19:00:02 +00:00
from datetime import timedelta
2015-05-04 19:52:53 +00:00
from socket import error as SocketError
from django.core.mail import get_connection
2015-05-07 19:00:02 +00:00
from django.db.models import Q
from django.utils import timezone
2015-05-04 19:52:53 +00:00
from django.utils.encoding import smart_str
2015-06-05 12:39:58 +00:00
from orchestra.utils.sys import LockFile, OperationLocked
2015-05-06 10:51:12 +00:00
2015-05-07 19:00:02 +00:00
from . import settings
2015-05-04 19:52:53 +00:00
from .models import Message
2015-06-05 12:39:58 +00:00
def send_message(message, num=0, connection=None, bulk=settings.MAILER_BULK_MESSAGES):
2015-06-05 12:22:17 +00:00
if num >= bulk and connection is not None:
2015-05-04 19:52:53 +00:00
connection.close()
connection = None
if connection is None:
2015-06-05 12:39:58 +00:00
# Reset connection with django
num = 0
2015-05-04 19:52:53 +00:00
connection = get_connection(backend='django.core.mail.backends.smtp.EmailBackend')
connection.open()
error = None
try:
connection.connection.sendmail(message.from_address, [message.to_address], smart_str(message.content))
2015-07-02 10:49:44 +00:00
except (SocketError,
smtplib.SMTPSenderRefused,
2015-05-04 19:52:53 +00:00
smtplib.SMTPRecipientsRefused,
smtplib.SMTPAuthenticationError) as err:
message.defer()
error = err
else:
message.sent()
message.log(error)
2015-07-02 10:49:44 +00:00
return connection
2015-05-04 19:52:53 +00:00
2015-06-05 12:39:58 +00:00
def send_pending(bulk=settings.MAILER_BULK_MESSAGES):
try:
with LockFile('/dev/shm/mailer.send_pending.lock'):
connection = None
num = 0
for message in Message.objects.filter(state=Message.QUEUED).order_by('priority'):
2015-07-02 10:49:44 +00:00
connection = send_message(message, num, connection, bulk)
2015-06-05 12:39:58 +00:00
num += 1
now = timezone.now()
qs = Q()
for retries, seconds in enumerate(settings.MAILER_DEFERE_SECONDS):
delta = timedelta(seconds=seconds)
qs = qs | Q(retries=retries, last_retry__lte=now-delta)
for message in Message.objects.filter(state=Message.DEFERRED).filter(qs).order_by('priority'):
send_message(message, num, connection, bulk)
if connection is not None:
connection.close()
except OperationLocked:
pass