summaryrefslogtreecommitdiff
path: root/src/mailman/queue/outgoing.py
diff options
context:
space:
mode:
authorBarry Warsaw2011-05-29 12:45:19 -0400
committerBarry Warsaw2011-05-29 12:45:19 -0400
commit521a179d309fac857fdbbe162d5db136c3ec3b1e (patch)
treeec6e635e9c0f8a5bd655a254f9c346f1acb6dd8e /src/mailman/queue/outgoing.py
parent0f760798fb2490a03041c42018afbd59749e6cbd (diff)
downloadmailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.tar.gz
mailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.tar.zst
mailman-521a179d309fac857fdbbe162d5db136c3ec3b1e.zip
Diffstat (limited to 'src/mailman/queue/outgoing.py')
-rw-r--r--src/mailman/queue/outgoing.py160
1 files changed, 0 insertions, 160 deletions
diff --git a/src/mailman/queue/outgoing.py b/src/mailman/queue/outgoing.py
deleted file mode 100644
index ed27f014c..000000000
--- a/src/mailman/queue/outgoing.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright (C) 2000-2011 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Outgoing queue runner."""
-
-import socket
-import logging
-
-from datetime import datetime
-from lazr.config import as_boolean, as_timedelta
-from zope.component import getUtility
-
-from mailman.config import config
-from mailman.interfaces.bounce import BounceContext, IBounceProcessor
-from mailman.interfaces.mailinglist import Personalization
-from mailman.interfaces.membership import ISubscriptionService
-from mailman.interfaces.mta import SomeRecipientsFailed
-from mailman.interfaces.pending import IPendings
-from mailman.queue import Runner
-from mailman.utilities.datetime import now
-from mailman.utilities.modules import find_name
-
-
-# This controls how often _do_periodic() will try to deal with deferred
-# permanent failures. It is a count of calls to _do_periodic()
-DEAL_WITH_PERMFAILURES_EVERY = 10
-
-log = logging.getLogger('mailman.error')
-smtp_log = logging.getLogger('mailman.smtp')
-
-
-
-class OutgoingRunner(Runner):
- """The outgoing queue runner."""
-
- def __init__(self, slice=None, numslices=1):
- super(OutgoingRunner, self).__init__(slice, numslices)
- # We look this function up only at startup time.
- self._func = find_name(config.mta.outgoing)
- # This prevents smtp server connection problems from filling up the
- # error log. It gets reset if the message was successfully sent, and
- # set if there was a socket.error.
- self._logged = False
- self._retryq = config.switchboards['retry']
-
- def _dispose(self, mlist, msg, msgdata):
- # See if we should retry delivery of this message again.
- deliver_after = msgdata.get('deliver_after', datetime.fromtimestamp(0))
- if now() < deliver_after:
- return True
- # Calculate whether we should VERP this message or not. The results of
- # this set the 'verp' key in the message metadata.
- interval = int(config.mta.verp_delivery_interval)
- if 'verp' in msgdata:
- # Honor existing settings.
- pass
- # If personalization is enabled for this list and we've configured
- # Mailman to always VERP personalized deliveries, then yes we VERP it.
- # Also, if personalization is /not/ enabled, but
- # verp_delivery_interval is set (and we've hit this interval), then
- # again, this message should be VERP'd. Otherwise, no.
- elif mlist.personalize != Personalization.none:
- if as_boolean(config.mta.verp_personalized_deliveries):
- msgdata['verp'] = True
- elif interval == 0:
- # Never VERP.
- msgdata['verp'] = False
- elif interval == 1:
- # VERP every time.
- msgdata['verp'] = True
- else:
- # VERP every 'interval' number of times.
- msgdata['verp'] = (mlist.post_id % interval == 0)
- try:
- self._func(mlist, msg, msgdata)
- self._logged = False
- except socket.error:
- # There was a problem connecting to the SMTP server. Log this
- # once, but crank up our sleep time so we don't fill the error
- # log.
- port = int(config.mta.smtp_port)
- if port == 0:
- port = 'smtp' # Log this just once.
- if not self._logged:
- log.error('Cannot connect to SMTP server %s on port %s',
- config.mta.smtp_host, port)
- self._logged = True
- return True
- except SomeRecipientsFailed as error:
- processor = getUtility(IBounceProcessor)
- # BAW: msg is the original message that failed delivery, not a
- # bounce message. This may be confusing if this is what's sent to
- # the user in the probe message. Maybe we should craft a
- # bounce-like message containing information about the permanent
- # SMTP failure?
- if 'probe_token' in msgdata:
- # This is a failure of our local MTA to deliver to a probe
- # message recipient. Register the bounce event for permanent
- # failures. Start by grabbing and confirming (i.e. removing)
- # the pendable record associated with this bounce token,
- # regardless of what address was actually failing.
- if len(error.permanent_failures) > 0:
- pended = getUtility(IPendings).confirm(
- msgdata['probe_token'])
- # It's possible the token has been confirmed out of the
- # database. Just ignore that.
- if pended is not None:
- member = getUtility(ISubscriptionService).get_member(
- pended['member_id'])
- processor.register(
- mlist, member.address.email, msg,
- BounceContext.probe)
- else:
- # Delivery failed at SMTP time for some or all of the
- # recipients. Permanent failures are registered as bounces,
- # but temporary failures are retried for later.
- for email in error.permanent_failures:
- processor.register(mlist, email, msg, BounceContext.normal)
- # Move temporary failures to the qfiles/retry queue which will
- # occasionally move them back here for another shot at
- # delivery.
- if error.temporary_failures:
- current_time = now()
- recipients = error.temporary_failures
- last_recip_count = msgdata.get('last_recip_count', 0)
- deliver_until = msgdata.get('deliver_until', current_time)
- if len(recipients) == last_recip_count:
- # We didn't make any progress. If we've exceeded the
- # configured retry period, log this failure and
- # discard the message.
- if current_time > deliver_until:
- smtp_log.error('Discarding message with '
- 'persistent temporary failures: '
- '{0}'.format(msg['message-id']))
- return False
- else:
- # We made some progress, so keep trying to delivery
- # this message for a while longer.
- deliver_until = current_time + as_timedelta(
- config.mta.delivery_retry_period)
- msgdata['last_recip_count'] = len(recipients)
- msgdata['deliver_until'] = deliver_until
- msgdata['recipients'] = recipients
- self._retryq.enqueue(msg, msgdata)
- # We've successfully completed handling of this message.
- return False