Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-flufl.bounce for
openSUSE:Factory checked in at 2021-11-20 02:39:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-flufl.bounce (Old)
and /work/SRC/openSUSE:Factory/.python-flufl.bounce.new.1895 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-flufl.bounce"
Sat Nov 20 02:39:07 2021 rev:3 rq:932383 version:4.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-flufl.bounce/python-flufl.bounce.changes
2020-01-24 14:12:17.518432387 +0100
+++
/work/SRC/openSUSE:Factory/.python-flufl.bounce.new.1895/python-flufl.bounce.changes
2021-11-20 02:40:15.376559185 +0100
@@ -1,0 +2,17 @@
+Wed Nov 17 09:55:03 UTC 2021 - Andreas Schneider <[email protected]>
+
+- Update to version 4.0
+ - Added another string to the stop looking strings in the yahoo
+ detector.
+ - Detectors are now run in a defined order and stop on the
+ first detection.
+ - Fixed microsoft.py which has been broken forever.
+ - Added recognition for yet another non-complaint Yahoo DSN.
+ - Added recognition for a non-compliant DSN from an unknown
+ MTA.
+ - Added recognition for a non-compliant opensmtpd DSN with
+ Action: error.
+ - Fixed simplmatch.py to not return results that don't resemble
+ email addresses. (LP: #1859011)
+
+-------------------------------------------------------------------
Old:
----
flufl.bounce-3.0.tar.gz
New:
----
flufl.bounce-4.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-flufl.bounce.spec ++++++
--- /var/tmp/diff_new_pack.lqyE4m/_old 2021-11-20 02:40:15.920557390 +0100
+++ /var/tmp/diff_new_pack.lqyE4m/_new 2021-11-20 02:40:15.924557377 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-flufl.bounce
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,9 +17,9 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define skip_python2 1
+%define pythons python3
Name: python-flufl.bounce
-Version: 3.0
+Version: 4.0
Release: 0
Summary: Email bounce detectors
License: Apache-2.0
@@ -28,16 +28,17 @@
Source0:
https://files.pythonhosted.org/packages/source/f/flufl.bounce/flufl.bounce-%{version}.tar.gz
Source1: https://gitlab.com/warsaw/flufl.bounce/raw/master/LICENSE
BuildRequires: %{python_module setuptools}
-BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-atpublic
Requires: python-zope.interface
-BuildArch: noarch
# SECTION test requirements
BuildRequires: %{python_module atpublic}
BuildRequires: %{python_module pytest}
+BuildRequires: %{python_module six}
BuildRequires: %{python_module zope.interface}
# /SECTION
+BuildRequires: fdupes
+BuildArch: noarch
%python_subpackages
%description
++++++ flufl.bounce-3.0.tar.gz -> flufl.bounce-4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/LICENSE new/flufl.bounce-4.0/LICENSE
--- old/flufl.bounce-3.0/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/LICENSE 2020-01-18 03:13:00.000000000 +0100
@@ -0,0 +1,13 @@
+Copyright 2004-2020 Barry Warsaw
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/MANIFEST.in
new/flufl.bounce-4.0/MANIFEST.in
--- old/flufl.bounce-3.0/MANIFEST.in 2017-02-17 23:54:44.000000000 +0100
+++ new/flufl.bounce-4.0/MANIFEST.in 2020-01-18 03:13:00.000000000 +0100
@@ -1,4 +1,4 @@
-include *.py COPYING.LESSER MANIFEST.in
+include *.py LICENSE MANIFEST.in
exclude *.egg
global-include *.rst *.txt *.ini *.cfg
prune build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/PKG-INFO
new/flufl.bounce-4.0/PKG-INFO
--- old/flufl.bounce-3.0/PKG-INFO 2017-02-17 23:59:25.000000000 +0100
+++ new/flufl.bounce-4.0/PKG-INFO 2021-06-17 03:02:39.739049700 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: flufl.bounce
-Version: 3.0
+Version: 4.0
Summary: Email bounce detectors.
Home-page: https://fluflbounce.readthedocs.io/en/latest/
-Author: Barry Warsaw
-Author-email: [email protected]
+Maintainer: Barry Warsaw
+Maintainer-email: [email protected]
License: ASLv2
Download-URL: https://pypi.python.org/pypi/flufl.bounce
Description: UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/README.rst
new/flufl.bounce-4.0/README.rst
--- old/flufl.bounce-3.0/README.rst 2017-02-17 23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/README.rst 2020-01-18 03:13:00.000000000 +0100
@@ -12,11 +12,11 @@
Authors
=======
-`flufl.bounce` is Copyright (C) 2004-2017 Barry Warsaw <[email protected]>
-
-Barry Warsaw <[email protected]>
-Mark Sapiro <[email protected]>
+`flufl.bounce` is Copyright (C) 2004-2020 Barry Warsaw <[email protected]>
+| Barry Warsaw <[email protected]>
+| Mark Sapiro <[email protected]>
+|
Licensed under the terms of the Apache Software License, version 2. See
LICENSE for details.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/NEWS.rst
new/flufl.bounce-4.0/flufl/bounce/NEWS.rst
--- old/flufl.bounce-3.0/flufl/bounce/NEWS.rst 2017-02-17 23:52:25.000000000
+0100
+++ new/flufl.bounce-4.0/flufl/bounce/NEWS.rst 2021-06-17 02:58:36.000000000
+0200
@@ -2,6 +2,28 @@
NEWS for flufl.bounce
=====================
+4.0 (2021-06-16)
+================
+ * Added another string to the ``stop looking`` strings in the yahoo detector.
+ (Closes #13)
+ * Detectors are now run in a defined order and stop on the first detection.
+ (Closes #12)
+
+3.0.2 (2021-02-09)
+==================
+ * Fixed microsoft.py which has been broken forever. (Closes #10)
+ * Added recognition for yet another non-complaint Yahoo DSN.
+ * Added recognition for a non-compliant DSN from an unknown MTA.
+ * Fixed missing () in the groupwise detector.
+
+3.0.1 (2020-01-17)
+==================
+ * Added recognition for a non-compliant opensmtpd DSN with Action: error.
+ * Caught a possible UnicodeEncodeError in simplematch.py. (Closes #8)
+ * Fixed simplmatch.py to not return results that don't resemble email
+ addresses. (LP: #1859011) (Closes #9)
+
+
3.0 (2017-02-17)
================
* Drop Python 2 support.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/README.rst
new/flufl.bounce-4.0/flufl/bounce/README.rst
--- old/flufl.bounce-3.0/flufl/bounce/README.rst 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/README.rst 2021-02-10
00:04:50.000000000 +0100
@@ -43,7 +43,7 @@
Copyright
=========
-Copyright (C) 2004-2017 Barry A. Warsaw
+Copyright (C) 2004-2021 Barry A. Warsaw
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/__init__.py
new/flufl.bounce-4.0/flufl/bounce/__init__.py
--- old/flufl.bounce-3.0/flufl/bounce/__init__.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/__init__.py 2021-06-17
02:58:36.000000000 +0200
@@ -2,7 +2,7 @@
from public import public
-__version__ = '3.0'
+__version__ = '4.0'
public(__version__=__version__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/_detectors/dsn.py
new/flufl.bounce-4.0/flufl/bounce/_detectors/dsn.py
--- old/flufl.bounce-3.0/flufl/bounce/_detectors/dsn.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/_detectors/dsn.py 2020-01-18
03:13:00.000000000 +0100
@@ -40,7 +40,8 @@
# Some MTAs have been observed that put comments on the action.
if action.startswith('delayed'):
address_set = delayed_addresses
- elif action.startswith('fail'):
+ # opensmtpd uses non-compliant Action: error
+ elif action.startswith('fail') or action.startswith('error'):
address_set = failed_addresses
else:
# Some non-permanent failure, so ignore this block.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/_detectors/groupwise.py
new/flufl.bounce-4.0/flufl/bounce/_detectors/groupwise.py
--- old/flufl.bounce-3.0/flufl/bounce/_detectors/groupwise.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/_detectors/groupwise.py 2021-02-10
00:01:13.000000000 +0100
@@ -21,7 +21,7 @@
def find_textplain(msg):
if msg.get_content_type() == 'text/plain':
return msg
- if msg.is_multipart:
+ if msg.is_multipart():
for part in msg.get_payload():
if not isinstance(part, Message):
continue
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/_detectors/microsoft.py
new/flufl.bounce-4.0/flufl/bounce/_detectors/microsoft.py
--- old/flufl.bounce-3.0/flufl/bounce/_detectors/microsoft.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/_detectors/microsoft.py 2020-01-24
22:45:19.000000000 +0100
@@ -3,6 +3,7 @@
import re
from enum import Enum
+from flufl.bounce._detectors.simplematch import VALID
from flufl.bounce.interfaces import (
IBounceDetector, NoFailures, NoTemporaryFailures)
from io import BytesIO
@@ -44,6 +45,6 @@
if scre.search(line):
state = ParseState.tag_seen
elif state is ParseState.tag_seen:
- if '@' in line:
+ if VALID.match(line.strip()):
addresses.add(line.strip())
return NoTemporaryFailures, set(addresses)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/_detectors/simplematch.py
new/flufl.bounce-4.0/flufl/bounce/_detectors/simplematch.py
--- old/flufl.bounce-3.0/flufl/bounce/_detectors/simplematch.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/_detectors/simplematch.py 2020-12-18
19:48:44.000000000 +0100
@@ -28,13 +28,20 @@
#
# For compatibility with Python 3, the API requires byte addresses.
unquoted = re.sub('=[a-fA-F0-9]{2}', _unquote_match, address)
- return unquoted.encode('us-ascii').strip()
+ try:
+ return unquoted.encode('us-ascii').strip()
+ except UnicodeEncodeError:
+ return b''
def _c(pattern):
return re.compile(pattern, re.IGNORECASE)
+# Pattern to match any valid email address and not much more.
+VALID = _c(rb'^[\x21-\x3d\x3f\x41-\x7e]+@[a-z0-9._]+$')
+
+
# This is a list of tuples of the form
#
# (start cre, end cre, address cre)
@@ -46,167 +53,175 @@
# address that bounced.
PATTERNS = [
# sdm.de
- (_c('here is your list of failed recipients'),
- _c('here is your returned mail'),
+ (_c(r'here is your list of failed recipients'),
+ _c(r'here is your returned mail'),
_c(r'<(?P<addr>[^>]*)>')),
# sz-sb.de, corridor.com, nfg.nl
- (_c('the following addresses had'),
- _c('transcript of session follows'),
+ (_c(r'the following addresses had'),
+ _c(r'transcript of session follows'),
_c(r'^ *(\(expanded from: )?<?(?P<addr>[^\s@]+@[^\s@>]+?)>?\)?\s*$')),
# robanal.demon.co.uk
- (_c('this message was created automatically by mail delivery software'),
- _c('original message follows'),
- _c('rcpt to:\s*<(?P<addr>[^>]*)>')),
+ (_c(r'this message was created automatically by mail delivery software'),
+ _c(r'original message follows'),
+ _c(r'rcpt to:\s*<(?P<addr>[^>]*)>')),
# s1.com (InterScan E-Mail VirusWall NT ???)
- (_c('message from interscan e-mail viruswall nt'),
- _c('end of message'),
- _c('rcpt to:\s*<(?P<addr>[^>]*)>')),
+ (_c(r'message from interscan e-mail viruswall nt'),
+ _c(r'end of message'),
+ _c(r'rcpt to:\s*<(?P<addr>[^>]*)>')),
# Smail
- (_c('failed addresses follow:'),
- _c('message text follows:'),
+ (_c(r'failed addresses follow:'),
+ _c(r'message text follows:'),
_c(r'\s*(?P<addr>\S+@\S+)')),
# newmail.ru
- (_c('This is the machine generated message from mail service.'),
- _c('--- Below the next line is a copy of the message.'),
- _c('<(?P<addr>[^>]*)>')),
+ (_c(r'This is the machine generated message from mail service.'),
+ _c(r'--- Below the next line is a copy of the message.'),
+ _c(r'<(?P<addr>[^>]*)>')),
# turbosport.com runs something called `MDaemon 3.5.2' ???
- (_c('The following addresses did NOT receive a copy of your message:'),
- _c('--- Session Transcript ---'),
- _c('[>]\s*(?P<addr>.*)$')),
+ (_c(r'The following addresses did NOT receive a copy of your message:'),
+ _c(r'--- Session Transcript ---'),
+ _c(r'[>]\s*(?P<addr>.*)$')),
# usa.net
- (_c('Intended recipient:\s*(?P<addr>.*)$'),
- _c('--------RETURNED MAIL FOLLOWS--------'),
- _c('Intended recipient:\s*(?P<addr>.*)$')),
+ (_c(r'Intended recipient:\s*(?P<addr>.*)$'),
+ _c(r'--------RETURNED MAIL FOLLOWS--------'),
+ _c(r'Intended recipient:\s*(?P<addr>.*)$')),
# hotpop.com
- (_c('Undeliverable Address:\s*(?P<addr>.*)$'),
- _c('Original message attached'),
- _c('Undeliverable Address:\s*(?P<addr>.*)$')),
+ (_c(r'Undeliverable Address:\s*(?P<addr>.*)$'),
+ _c(r'Original message attached'),
+ _c(r'Undeliverable Address:\s*(?P<addr>.*)$')),
# Another demon.co.uk format
- (_c('This message was created automatically by mail delivery'),
- _c('^---- START OF RETURNED MESSAGE ----'),
- _c("addressed to '(?P<addr>[^']*)'")),
+ (_c(r'This message was created automatically by mail delivery'),
+ _c(r'^---- START OF RETURNED MESSAGE ----'),
+ _c(r"addressed to '(?P<addr>[^']*)'")),
# Prodigy.net full mailbox
(_c("User's mailbox is full:"),
- _c('Unable to deliver mail.'),
- _c("User's mailbox is full:\s*<(?P<addr>[^>]*)>")),
+ _c(r'Unable to deliver mail.'),
+ _c(r"User's mailbox is full:\s*<(?P<addr>[^>]*)>")),
# Microsoft SMTPSVC
- (_c('The email below could not be delivered to the following user:'),
- _c('Old message:'),
- _c('<(?P<addr>[^>]*)>')),
+ (_c(r'The email below could not be delivered to the following user:'),
+ _c(r'Old message:'),
+ _c(r'<(?P<addr>[^>]*)>')),
# Yahoo on behalf of other domains like sbcglobal.net
- (_c('Unable to deliver message to the following address\(es\)\.'),
- _c('--- Original message follows\.'),
- _c('<(?P<addr>[^>]*)>:')),
+ (_c(r'Unable to deliver message to the following address\(es\)\.'),
+ _c(r'--- Original message follows\.'),
+ _c(r'<(?P<addr>[^>]*)>:')),
# googlemail.com
- (_c('Delivery to the following recipient failed'),
- _c('----- Original message -----'),
- _c('^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
+ (_c(r'Delivery to the following recipient failed'),
+ _c(r'----- Original message -----'),
+ _c(r'^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
# kundenserver.de
- (_c('A message that you sent could not be delivered'),
- _c('^---'),
- _c('<(?P<addr>[^>]*)>')),
+ (_c(r'A message that you sent could not be delivered'),
+ _c(r'^---'),
+ _c(r'<(?P<addr>[^>]*)>')),
# another kundenserver.de
- (_c('A message that you sent could not be delivered'),
- _c('^---'),
- _c('^(?P<addr>[^\s@]+@[^\s@:]+):')),
+ (_c(r'A message that you sent could not be delivered'),
+ _c(r'^---'),
+ _c(r'^(?P<addr>[^\s@]+@[^\s@:]+):')),
# thehartford.com / songbird
- (_c('Del(i|e)very to the following recipients (failed|was aborted)'),
+ (_c(r'Del(i|e)very to the following recipients (failed|was aborted)'),
# this one may or may not have the original message, but there's nothing
# unique to stop on, so stop on the first line of at least 3 characters
# that doesn't start with 'D' (to not stop immediately) and has no '@'.
# Also note that simple_30.txt contains an apparent misspelling in the
# MTA's DSN section.
- _c('^[^D][^@]{2,}$'),
- _c('^[\s*]*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^[^D][^@]{2,}$'),
+ _c(r'^[\s*]*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
# and another thehartfod.com/hartfordlife.com
- (_c('^Your message\s*$'),
- _c('^because:'),
- _c('^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
+ (_c(r'^Your message\s*$'),
+ _c(r'^because:'),
+ _c(r'^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
# kviv.be (InterScan NT)
- (_c('^Unable to deliver message to'),
+ (_c(r'^Unable to deliver message to'),
_c(r'\*+\s+End of message\s+\*+'),
- _c('<(?P<addr>[^>]*)>')),
+ _c(r'<(?P<addr>[^>]*)>')),
# earthlink.net supported domains
- (_c('^Sorry, unable to deliver your message to'),
- _c('^A copy of the original message'),
- _c('\s*(?P<addr>[^\s@]+@[^\s@]+)\s+')),
+ (_c(r'^Sorry, unable to deliver your message to'),
+ _c(r'^A copy of the original message'),
+ _c(r'\s*(?P<addr>[^\s@]+@[^\s@]+)\s+')),
# ademe.fr
- (_c('^A message could not be delivered to:'),
- _c('^Subject:'),
- _c('^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
+ (_c(r'^A message could not be delivered to:'),
+ _c(r'^Subject:'),
+ _c(r'^\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
# andrew.ac.jp
- (_c('^Invalid final delivery userid:'),
- _c('^Original message follows.'),
- _c('\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
+ (_c(r'^Invalid final delivery userid:'),
+ _c(r'^Original message follows.'),
+ _c(r'\s*(?P<addr>[^\s@]+@[^\s@]+)\s*$')),
# [email protected]
- (_c('------ Failed Recipients ------'),
- _c('-------- Returned Mail --------'),
- _c('<(?P<addr>[^>]*)>')),
+ (_c(r'------ Failed Recipients ------'),
+ _c(r'-------- Returned Mail --------'),
+ _c(r'<(?P<addr>[^>]*)>')),
# cynergycom.net
- (_c('A message that you sent could not be delivered'),
- _c('^---'),
- _c('(?P<addr>[^\s@]+@[^\s@)]+)')),
+ (_c(r'A message that you sent could not be delivered'),
+ _c(r'^---'),
+ _c(r'(?P<addr>[^\s@]+@[^\s@)]+)')),
# LSMTP for Windows
- (_c('^--> Error description:\s*$'),
- _c('^Error-End:'),
- _c('^Error-for:\s+(?P<addr>[^\s@]+@[^\s@]+)')),
+ (_c(r'^--> Error description:\s*$'),
+ _c(r'^Error-End:'),
+ _c(r'^Error-for:\s+(?P<addr>[^\s@]+@[^\s@]+)')),
# Qmail with a tri-language intro beginning in spanish
- (_c('Your message could not be delivered'),
- _c('^-'),
- _c('<(?P<addr>[^>]*)>:')),
+ (_c(r'Your message could not be delivered'),
+ _c(r'^-'),
+ _c(r'<(?P<addr>[^>]*)>:')),
# socgen.com
- (_c('Your message could not be delivered to'),
- _c('^\s*$'),
- _c('(?P<addr>[^\s@]+@[^\s@]+)')),
+ (_c(r'Your message could not be delivered to'),
+ _c(r'^\s*$'),
+ _c(r'(?P<addr>[^\s@]+@[^\s@]+)')),
# dadoservice.it
- (_c('Your message has encountered delivery problems'),
- _c('Your message reads'),
- _c('addressed to\s*(?P<addr>[^\s@]+@[^\s@)]+)')),
+ (_c(r'Your message has encountered delivery problems'),
+ _c(r'Your message reads'),
+ _c(r'addressed to\s*(?P<addr>[^\s@]+@[^\s@)]+)')),
# gomaps.com
- (_c('Did not reach the following recipient'),
- _c('^\s*$'),
- _c('\s(?P<addr>[^\s@]+@[^\s@]+)')),
+ (_c(r'Did not reach the following recipient'),
+ _c(r'^\s*$'),
+ _c(r'\s(?P<addr>[^\s@]+@[^\s@]+)')),
# EYOU MTA SYSTEM
- (_c('This is the deliver program at'),
- _c('^-'),
- _c('^(?P<addr>[^\s@]+@[^\s@<>]+)')),
+ (_c(r'This is the deliver program at'),
+ _c(r'^-'),
+ _c(r'^(?P<addr>[^\s@]+@[^\s@<>]+)')),
# A non-standard qmail at ieo.it
- (_c('this is the email server at'),
- _c('^-'),
- _c('\s(?P<addr>[^\s@]+@[^\s@]+)[\s,]')),
+ (_c(r'this is the email server at'),
+ _c(r'^-'),
+ _c(r'\s(?P<addr>[^\s@]+@[^\s@]+)[\s,]')),
# pla.net.py (MDaemon.PRO ?)
- (_c('- no such user here'),
- _c('There is no user'),
- _c('^(?P<addr>[^\s@]+@[^\s@]+)\s')),
+ (_c(r'- no such user here'),
+ _c(r'There is no user'),
+ _c(r'^(?P<addr>[^\s@]+@[^\s@]+)\s')),
# mxlogic.net
- (_c('The following address failed:'),
- _c('Included is a copy of the message header'),
- _c('<(?P<addr>[^>]+)>')),
+ (_c(r'The following address failed:'),
+ _c(r'Included is a copy of the message header'),
+ _c(r'<(?P<addr>[^>]+)>')),
# fastdnsservers.com
- (_c('The following recipient\(s\) could not be reached'),
- _c('\s*Error Type'),
- _c('^(?P<addr>[^\s@]+@[^\s@<>]+)')),
+ (_c(r'The following recipient\(s\) could not be reached'),
+ _c(r'\s*Error Type'),
+ _c(r'^(?P<addr>[^\s@]+@[^\s@<>]+)')),
# xxx.com (simple_36.txt)
- (_c('Could not deliver message to the following recipient'),
- _c('\s*-- The header'),
- _c('Failed Recipient: (?P<addr>[^\s@]+@[^\s@<>]+)')),
+ (_c(r'Could not deliver message to the following recipient'),
+ _c(r'\s*-- The header'),
+ _c(r'Failed Recipient: (?P<addr>[^\s@]+@[^\s@<>]+)')),
# mta1.service.uci.edu
- (_c('Message not delivered to the following addresses'),
- _c('Error detail'),
- _c('\s*(?P<addr>[^\s@]+@[^\s@)]+)')),
+ (_c(r'Message not delivered to the following addresses'),
+ _c(r'Error detail'),
+ _c(r'\s*(?P<addr>[^\s@]+@[^\s@)]+)')),
# Dovecot LDA Over quota MDN (bogus - should be DSN).
- (_c('^Your message'),
- _c('^Reporting'),
- _c('Your message to <?(?P<addr>[^\s<@]+@[^\s@>]+)>? was automatically'
+ (_c(r'^Your message'),
+ _c(r'^Reporting'),
+ _c(r'Your message to <?(?P<addr>[^\s<@]+@[^\s@>]+)>? was automatically'
' rejected')),
# mail.ru
- (_c('A message that you sent was rejected'),
- _c('This is a copy of your message'),
- _c('\s(?P<addr>[^\s@]+@[^\s@]+)')),
+ (_c(r'A message that you sent was rejected'),
+ _c(r'This is a copy of your message'),
+ _c(r'\s(?P<addr>[^\s@]+@[^\s@]+)')),
# MailEnable
- (_c('Message could not be delivered to some recipients.'),
- _c('Message headers follow'),
- _c('Recipient: \[SMTP:(?P<addr>[^\s@]+@[^\s@]+)\]')),
+ (_c(r'Message could not be delivered to some recipients.'),
+ _c(r'Message headers follow'),
+ _c(r'Recipient: \[SMTP:(?P<addr>[^\s@]+@[^\s@]+)\]')),
+ # This one is from Yahoo but dosen't fit the yahoo recognizer format
+ (_c(r'wasn\'t able to deliver the following message'),
+ _c(r'---Below this line is a copy of the message.'),
+ _c(r'To: (?P<addr>[^\s@]+@[^\s@]+)')),
+ # From some unknown MTA
+ (_c(r'This is a delivery failure notification message'),
+ _c(r'The problem appears to be'),
+ _c(r'-- (?P<addr>[^\s@]+@[^\s@]+)')),
# Next one goes here...
]
@@ -221,6 +236,7 @@
def process(self, msg):
"""See `IBounceDetector`."""
addresses = set()
+ new_addresses = set()
# MAS: This is a mess. The outer loop used to be over the message
# so we only looped through the message once. Looping through the
# message for each set of patterns is obviously way more work, but
@@ -244,4 +260,7 @@
break
if len(addresses) > 0:
break
- return NoTemporaryFailures, addresses
+ for address in addresses:
+ if VALID.match(address):
+ new_addresses.add(address)
+ return NoTemporaryFailures, new_addresses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/_detectors/yahoo.py
new/flufl.bounce-4.0/flufl/bounce/_detectors/yahoo.py
--- old/flufl.bounce-3.0/flufl/bounce/_detectors/yahoo.py 2017-02-17
23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/_detectors/yahoo.py 2021-06-11
18:11:43.000000000 +0200
@@ -19,6 +19,7 @@
acre = re.compile(r'<(?P<addr>[^>]*)>:')
ecre = (re.compile(r'--- Original message follows'),
re.compile(r'--- Below this line is a copy of the message'),
+ re.compile(r'---------- Forwarded message ----------'),
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/_scan.py
new/flufl.bounce-4.0/flufl/bounce/_scan.py
--- old/flufl.bounce-3.0/flufl/bounce/_scan.py 2017-02-17 23:13:22.000000000
+0100
+++ new/flufl.bounce-4.0/flufl/bounce/_scan.py 2021-06-17 02:58:36.000000000
+0200
@@ -1,29 +1,55 @@
-import os
import logging
-from flufl.bounce.interfaces import IBounceDetector
-from importlib import import_module
-from pkg_resources import resource_listdir
+from flufl.bounce._detectors import (
+ aol,
+ caiwireless,
+ dsn,
+ exchange,
+ exim,
+ groupwise,
+ llnl,
+ microsoft,
+ netscape,
+ postfix,
+ qmail,
+ simplematch,
+ simplewarning,
+ sina,
+ smtp32,
+ yahoo,
+ yale,
+ )
from public import public
log = logging.getLogger('flufl.bounce')
-def _find_detectors(package):
- missing = object()
- for filename in resource_listdir(package, ''):
- basename, extension = os.path.splitext(filename)
- if extension != '.py':
- continue
- module_name = '{}.{}'.format(package, basename)
- module = import_module(module_name)
- for name in getattr(module, '__all__', []):
- component = getattr(module, name, missing)
- if component is missing:
- log.error('skipping missing __all__ entry: {}'.format(name))
- if IBounceDetector.implementedBy(component):
- yield component
+def _find_detectors():
+ """Get all detectors in order of most specific/authoritative to least"""
+ yield from [
+ # RFC compliant DSNs.
+ dsn.DSN,
+ # Detectors for specific providers without heuristics.
+ exim.Exim,
+ sina.Sina,
+ # Provider specific heuristic detectors.
+ yahoo.Yahoo,
+ yale.Yale,
+ smtp32.SMTP32,
+ postfix.Postfix,
+ qmail.Qmail,
+ groupwise.GroupWise,
+ microsoft.Microsoft,
+ caiwireless.Caiwireless,
+ exchange.Exchange,
+ netscape.Netscape,
+ aol.AOL,
+ # Generic and other heuristic detectors.
+ simplematch.SimpleMatch,
+ simplewarning.SimpleWarning,
+ llnl.LLNL,
+ ]
@public
@@ -36,8 +62,7 @@
:rtype: set of strings
"""
permanent_failures = set()
- package = 'flufl.bounce._detectors'
- for detector_class in _find_detectors(package):
+ for detector_class in _find_detectors():
log.info('Running detector: {}'.format(detector_class))
try:
temporary, permanent = detector_class().process(msg)
@@ -45,6 +70,8 @@
log.exception('Exception in detector: {}'.format(detector_class))
raise
permanent_failures.update(permanent)
+ if temporary or permanent:
+ break
return permanent_failures
@@ -59,10 +86,11 @@
"""
temporary_failures = set()
permanent_failures = set()
- package = 'flufl.bounce._detectors'
- for detector_class in _find_detectors(package):
+ for detector_class in _find_detectors():
log.info('Running detector: {}'.format(detector_class))
temporary, permanent = detector_class().process(msg)
temporary_failures.update(temporary)
permanent_failures.update(permanent)
+ if temporary or permanent:
+ break
return temporary_failures, permanent_failures
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/conf.py
new/flufl.bounce-4.0/flufl/bounce/conf.py
--- old/flufl.bounce-3.0/flufl/bounce/conf.py 2017-02-16 00:04:30.000000000
+0100
+++ new/flufl.bounce-4.0/flufl/bounce/conf.py 2021-02-10 00:06:58.000000000
+0100
@@ -39,7 +39,7 @@
# General information about the project.
project = 'flufl.bounce'
-copyright = '2004-2017, Barry A. Warsaw'
+copyright = '2004-2021, Barry A. Warsaw'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/testing/helpers.py
new/flufl.bounce-4.0/flufl/bounce/testing/helpers.py
--- old/flufl.bounce-3.0/flufl/bounce/testing/helpers.py 2017-02-17
23:42:59.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/testing/helpers.py 2021-06-11
17:33:22.000000000 +0200
@@ -78,7 +78,7 @@
self.assertEqual(got, self.expected)
def loadTestsFromTestCase(self, event):
- if event.testCase.__name__ is not 'TestDetectors':
+ if event.testCase.__name__ != 'TestDetectors':
return
for data in DATA:
event.extraTests.append(Detectors.DataTest(data))
@@ -140,8 +140,12 @@
('simplematch', 'simple_38.txt', [b'[email protected]']),
('simplematch', 'simple_39.txt', [b'[email protected]']),
('simplematch', 'simple_41.txt', [b'[email protected]']),
+ ('simplematch', 'simple_42.txt', []),
+ ('simplematch', 'simple_43.txt', []),
+ ('simplematch', 'simple_44.txt', [b'[email protected]']),
('simplematch', 'bounce_02.txt', [b'[email protected]']),
('simplematch', 'bounce_03.txt', [b'[email protected]']),
+ ('simplematch', 'yahoo_12.txt', [b'[email protected]']),
# SimpleWarning
('simplewarning', 'simple_03.txt', [b'[email protected]'], True),
('simplewarning', 'simple_21.txt', [b'[email protected]'], True),
@@ -181,9 +185,12 @@
('dsn', 'dsn_15.txt', [b'[email protected]']),
('dsn', 'dsn_16.txt', [b'[email protected]']),
('dsn', 'dsn_17.txt', [b'[email protected]'], True),
+ ('dsn', 'dsn_18.txt', [b'[email protected]']),
# Microsoft Exchange
('exchange', 'microsoft_01.txt', [b'[email protected]']),
('exchange', 'microsoft_02.txt', [b'[email protected]']),
+ # Microsoft's `SMTPSVC'?
+ ('microsoft', 'microsoft_04.txt', [b'[email protected]']),
# SMTP32
('smtp32', 'smtp32_01.txt', [b'[email protected]']),
('smtp32', 'smtp32_02.txt', [b'[email protected]']),
@@ -235,6 +242,7 @@
b'[email protected]',
b'[email protected]']),
('yahoo', 'yahoo_11.txt', [b'[email protected]']),
+ ('yahoo', 'yahoo_13.txt', [b'[email protected]']),
# sina.com appears to use their own weird SINAEMAIL MTA
('sina', 'sina_01.txt', [b'[email protected]',
b'[email protected]']),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl/bounce/tests/data/dsn_18.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/dsn_18.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/dsn_18.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/dsn_18.txt 2020-01-18
03:13:00.000000000 +0100
@@ -0,0 +1,52 @@
+Return-Path: <>
+X-Original-To: [email protected]
+Delivered-To: [email protected]
+Received: from mx.domain.replaced (mx.domain.replaced [177.XXX.XXX.XXX])
+ by mailhost.domain.replaced (Postfix) with ESMTP id 6D6C71E8A3
+ for <[email protected]>; Thu, 22 Nov 2018 17:56:08
-0200 (BRST)
+Received: from mx.domain.replaced (mx.domain.replaced [local])
+ by mx.domain.replaced (OpenSMTPD) with ESMTPA id cce9bd49
+ for <[email protected]>;
+ Thu, 22 Nov 2018 17:56:08 -0200 (-02)
+Subject: Delivery status notification: error
+From: Mailer Daemon <[email protected]>
+To: [email protected]
+Date: Thu, 22 Nov 2018 17:56:08 -0200 (-02)
+MIME-Version: 1.0
+Content-Type: multipart/mixed;boundary="9950749020440539406/mx.domain.replaced"
+Message-ID: <[email protected]>
+
+This is a MIME-encapsulated message.
+
+--9950749020440539406/mx.domain.replaced
+Content-Description: Notification
+Content-Type: text/plain; charset=us-ascii
+
+ Hi!
+
+ This is the MAILER-DAEMON, please DO NOT REPLY to this email.
+
+ An error has occurred while attempting to deliver a message for
+ the following list of recipients:
+
[email protected]: Domain does not exist
+
+ Below is a copy of the original message:
+
+--9950749020440539406/mx.domain.replaced
+Content-Description: Delivery Report
+Content-Type: message/delivery-status
+
+Reporting-MTA: dns; mx.domain.replaced
+
+Final-Recipient: rfc822; [email protected]
+Action: error
+Status: 5.0.0
+
+--9950749020440539406/mx.domain.replaced
+Content-Description: Message headers
+Content-Type: text/rfc822-headers
+
+[ORIGINAL MESSAGE]
+
+--9950749020440539406/mx.domain.replaced--
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/microsoft_04.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/microsoft_04.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/microsoft_04.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/microsoft_04.txt
2020-01-24 22:45:19.000000000 +0100
@@ -0,0 +1,49 @@
+Return-Path: <MAILER-DAEMON>
+From: System Administrator <[email protected]>
+To: [email protected]
+Subject: Undeliverable: RE: Waiver draft results explained
+Date: Fri, 4 Oct 2002 17:12:35 -0400
+MIME-Version: 1.0
+X-Mailer: Internet Mail Service (5.5.2656.59)
+X-MS-Embedded-Report:
+Content-Type: multipart/mixed;
+ boundary="----_=_NextPart_000_01C26BEA.C2970D56"
+
+This is a contrived message. the microsoft detector was totally untested
+and there was no suitable message for it, so this is reverse engineered
+from the code.
+
+------_=_NextPart_000_01C26BEA.C2970D56
+Content-Type: text/plain;
+ charset="iso-8859-1"
+
+Your message
+
+ To: xxx
+ Subject: RE: Waiver draft results explained
+ Sent: Fri, 4 Oct 2002 17:10:56 -0400
+
+did not reach the following recipient(s):
+
+c=US;a= ;p=IKON;o=Nexus2;dda:[email protected]; on Fri, 4 Oct 2002
+17:12:28 -0400
+ The recipient name is not recognized
+ The MTS-ID of the original message is: c=us;a=
+;p=ikon;l=BKB02-IMS-010210042112TX06SNVK
+ MSEXCH:IMS:IKON:Nexus2:BKB02-IMS-01 0 (000C05A6) Unknown Recipient
+
+ ----- Transcript of session follows -----
+
+bogus line
+
+ [email protected]
+
+
+
+------_=_NextPart_000_01C26BEA.C2970D56
+Content-Type: message/rfc822
+
+Message removed
+
+------_=_NextPart_000_01C26BEA.C2970D56--
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_42.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_42.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_42.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_42.txt 2020-01-18
03:13:00.000000000 +0100
@@ -0,0 +1,54 @@
+From: Mail Delivery System <[email protected]>
+To: [email protected]
+Content-Type: multipart/report; report-type=delivery-status;
boundary=1578513971-eximdsn-503222498
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <[email protected]>
+Date: Wed, 08 Jan 2020 20:06:11 +0000
+
+--1578513971-eximdsn-503222498
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+ [email protected]
+ (generated from python@david...)
+ host gmail-smtp-in.l.google.com [108.177.119.27]
+ SMTP error from remote mail server after end of data:
+ 550-5.7.1 [94.136.40.141 12] Our system has detected that this
message is
+ 550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to
Gmail,
+ 550-5.7.1 this message has been blocked. Please visit
+ 550-5.7.1 https://support.google.com/mail/?p=UnsolicitedMessageError
+ 550 5.7.1 for more information. c11si2772404eds.65 - gsmtp
+
+--1578513971-eximdsn-503222498
+Content-type: message/delivery-status
+
+Reporting-MTA: dns; smtp13.mailcore.me
+
+Action: failed
+Final-Recipient: rfc822;[email protected]
+Status: 5.0.0
+Remote-MTA: dns; gmail-smtp-in.l.google.com
+Diagnostic-Code: smtp; 550-5.7.1 [94.136.40.141 12] Our system has
detected that this message is
+ 550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,
+ 550-5.7.1 this message has been blocked. Please visit
+ 550-5.7.1 https://support.google.com/mail/?p=UnsolicitedMessageError
+ 550 5.7.1 for more information. c11si2772404eds.65 - gsmtp
+
+--1578513971-eximdsn-503222498
+Content-type: text/rfc822-headers
+
+Return-path: <[email protected]>
+Received: from mail.python.org ([188.166.95.178])
+ by smtp13.mailcore.me with esmtp (Exim 4.92.3)
+ (envelope-from <[email protected]>)
+ id 1ipHak-0002Kp-UJ
+ for python@david...; Wed, 08 Jan 2020 20:06:11 +0000
+X-Comment: Remainder removed, not needed for test.
+
+--1578513971-eximdsn-503222498--
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_43.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_43.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_43.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_43.txt 2020-01-18
03:13:00.000000000 +0100
@@ -0,0 +1,344 @@
+From [email protected] Mon Dec 30 19:53:03 2019
+Return-Path: <[email protected]>
+X-Original-To: [email protected]
+Delivered-To: [email protected]
+Received: from mx05.our-domain.de (mx05.our-domain.de [10.0.0.215])
+ by mx09.our-domain.de (Postfix) with ESMTP id F2BEEE9318
+ for <[email protected]>;
+ Mon, 30 Dec 2019 19:48:01 +0100 (CET)
+X-Env-Sender: [email protected]
+From: [email protected]
+To: [email protected]
+Date: Mon, 30 Dec 2019 18:46:14 +0000 (GMT)
+Message-Id: <[email protected]>
+Subject: Mail delivery failed: returning message to sender
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="2458848.14.12"
+
+
+--2458848.14.12
+Content-Type: text/plain; charset=US-ASCII
+
+This message was created automatically by mail delivery software.
+
+A message that you sent could not be delivered to one or more of its
recipients.
+
+One or more of the recipients are not a valid user of the system. Please check
to be sure the email address is correct.
+
+
+
+--2458848.14.12
+Content-Type: message/rfc822
+
+Received: from smtp.some.domain (smtp.some.domain [10.0.0.1])
+ by VMACSEGCCMC02.localdomain (MTA) with ESMTP id 47mmbl5ltRzKm6s
+ for <[email protected]>; Mon, 30 Dec 2019 18:46:11 +0000 (GMT)
+Received: from mx09.our-domain.de (HELO mx09.our-domain.de) (10.0.0.219)
+ by server-28.someother.domain with ECDHE-RSA-AES256-GCM-SHA384 encrypted
SMTP; 30 Dec 2019 18:45:59 -0000
+Received: from mx09.our-domain.de (localhost [127.0.0.1])
+ by mx09.our-domain.de (Postfix) with ESMTP id CC58AAC993;
+ Mon, 30 Dec 2019 19:39:05 +0100 (CET)
+X-Original-To: [email protected]
+Delivered-To: [email protected]
+Received: from mx04.our-domain.de (mx04.our-domain.de [10.0.0.214])
+ by mx09.our-domain.de (Postfix) with ESMTP id 6EFD1A9DA7
+ for <[email protected]>;
+ Mon, 30 Dec 2019 19:18:16 +0100 (CET)
+To: "(Info) Test A"
+ <[email protected]>
+From: List_Owner <[email protected]>
+Message-ID: <[email protected]>
+Date: Mon, 30 Dec 2019 19:17:22 +0100
+User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:68.0) Gecko/20100101
+ Thunderbird/68.3.0
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------80AB81809DF608AE8D353110"
+X-Mailman-Approved-At: Mon, 30 Dec 2019 19:38:57 +0100
+Subject: [Test-A] Subject
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.15
+Precedence: list
+List-Id: Test-A
+ <test-a.listserv.our-domain.de>
+List-Unsubscribe: <https://listserv.our-domain.de/mailman/options/test-a>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <https://listserv.our-domain.de/mailman/private/test-a/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <https://listserv.our-domain.de/mailman/listinfo/test-a>,
+ <mailto:[email protected]?subject=subscribe>
+Reply-To: [email protected]
+Errors-To: [email protected]
+Sender: "Test-A"
+ <[email protected]>
+
+This is a multi-part message in MIME format.
+--------------80AB81809DF608AE8D353110
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
+velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+occaecat cupidatat non proident, sunt in culpa qui officia deserunt
+mollit anim id est laborum.
+
+
+__________________________________________________________________________________________
+Footer
+__________________________________________________________________________________________
+--------------80AB81809DF608AE8D353110
+Content-Type: application/pdf; name=dummy.pdf
+Content-Disposition: attachment; size=13264; filename=dummy.pdf
+Content-Transfer-Encoding: base64
+
+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
+USRuPC6uZTI6hUkHjGBBoU5ADiZ+I8AZj6cuEx8zjpm4eFQITuTkV/uewQl+EA3PcXwkUimfl/nI
+xJJC8fwSnKisjfV4PhV9JKegWvwUQR1YRV8Y650p5QAOFx4uP1w3VjhWPlZnFD+08BCQtofEURqp
+fEihoCMw4wiAwW6K/XQB9N0fycuXiscE4HB0OwLyN17ow6526L8jA6fPOjagSw1I8cGZgMTwAYoR
+xyYdoRmmkM4iJ0OSRSr8P1jbNhMKZW5kc3RyZWFtCmVuZG9iagoKNiAwIG9iagoxMDgyNQplbmRv
+YmoKCjcgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9CQUFBQUErQXJpYWwt
+Qm9sZE1UCi9GbGFncyA0Ci9Gb250QkJveFstNjI3IC0zNzYgMjAwMCAxMDExXS9JdGFsaWNBbmds
+ZSAwCi9Bc2NlbnQgOTA1Ci9EZXNjZW50IDIxMQovQ2FwSGVpZ2h0IDEwMTAKL1N0ZW1WIDgwCi9G
+b250RmlsZTIgNSAwIFI+PgplbmRvYmoKCjggMCBvYmoKPDwvTGVuZ3RoIDI3Mi9GaWx0ZXIvRmxh
+dGVEZWNvZGU+PgpzdHJlYW0KeJxdkc9uhCAQxu88BcftYQNadbuJMdm62cRD/6S2D6AwWpKKBPHg
+2xcG2yY9QH7DzDf5ZmB1c220cuzVzqIFRwelpYVlXq0A2sOoNElSKpVwe4S3mDpDmNe22+JgavQw
+lyVhbz63OLvRw0XOPdwR9mIlWKVHevioWx+3qzFfMIF2lJOqohIG3+epM8/dBAxVx0b6tHLb0Uv+
+Ct43AzTFOIlWxCxhMZ0A2+kRSMl5RcvbrSKg5b9cskv6QXx21pcmvpTzLKs8p8inPPA9cnENnMX3
+c+AcOeWBC+Qc+RT7FIEfohb5HBm1l8h14MfIOZrc3QS7YZ8/a6BitdavAJeOs4eplYbffzGzCSo8
+3zuVhO0KZW5kc3RyZWFtCmVuZG9iagoKOSAwIG9iago8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVl
+VHlwZS9CYXNlRm9udC9CQUFBQUErQXJpYWwtQm9sZE1UCi9GaXJzdENoYXIgMAovTGFzdENoYXIg
+MTEKL1dpZHRoc1s3NTAgNzIyIDYxMCA4ODkgNTU2IDI3NyA2NjYgNjEwIDMzMyAyNzcgMjc3IDU1
+NiBdCi9Gb250RGVzY3JpcHRvciA3IDAgUgovVG9Vbmljb2RlIDggMCBSCj4+CmVuZG9iagoKMTAg
+MCBvYmoKPDwKL0YxIDkgMCBSCj4+CmVuZG9iagoKMTEgMCBvYmoKPDwvRm9udCAxMCAwIFIKL1By
+b2NTZXRbL1BERi9UZXh0XT4+CmVuZG9iagoKMSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDQg
+MCBSL1Jlc291cmNlcyAxMSAwIFIvTWVkaWFCb3hbMCAwIDU5NSA4NDJdL0dyb3VwPDwvUy9UcmFu
+c3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDIgMCBSPj4KZW5kb2JqCgox
+MiAwIG9iago8PC9Db3VudCAxL0ZpcnN0IDEzIDAgUi9MYXN0IDEzIDAgUgo+PgplbmRvYmoKCjEz
+IDAgb2JqCjw8L1RpdGxlPEZFRkYwMDQ0MDA3NTAwNkQwMDZEMDA3OTAwMjAwMDUwMDA0NDAwNDYw
+MDIwMDA2NjAwNjkwMDZDMDA2NT4KL0Rlc3RbMSAwIFIvWFlaIDU2LjcgNzczLjMgMF0vUGFyZW50
+IDEyIDAgUj4+CmVuZG9iagoKNCAwIG9iago8PC9UeXBlL1BhZ2VzCi9SZXNvdXJjZXMgMTEgMCBS
+Ci9NZWRpYUJveFsgMCAwIDU5NSA4NDIgXQovS2lkc1sgMSAwIFIgXQovQ291bnQgMT4+CmVuZG9i
+agoKMTQgMCBvYmoKPDwvVHlwZS9DYXRhbG9nL1BhZ2VzIDQgMCBSCi9PdXRsaW5lcyAxMiAwIFIK
+Pj4KZW5kb2JqCgoxNSAwIG9iago8PC9BdXRob3I8RkVGRjAwNDUwMDc2MDA2MTAwNkUwMDY3MDA2
+NTAwNkMwMDZGMDA3MzAwMjAwMDU2MDA2QzAwNjEwMDYzMDA2ODAwNkYwMDY3MDA2OTAwNjEwMDZF
+MDA2RTAwNjkwMDczPgovQ3JlYXRvcjxGRUZGMDA1NzAwNzIwMDY5MDA3NDAwNjUwMDcyPgovUHJv
+ZHVjZXI8RkVGRjAwNEYwMDcwMDA2NTAwNkUwMDRGMDA2NjAwNjYwMDY5MDA2MzAwNjUwMDJFMDA2
+RjAwNzIwMDY3MDAyMDAwMzIwMDJFMDAzMT4KL0NyZWF0aW9uRGF0ZShEOjIwMDcwMjIzMTc1NjM3
+KzAyJzAwJyk+PgplbmRvYmoKCnhyZWYKMCAxNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMTE5
+OTcgMDAwMDAgbiAKMDAwMDAwMDAxOSAwMDAwMCBuIAowMDAwMDAwMjI0IDAwMDAwIG4gCjAwMDAw
+MTIzMzAgMDAwMDAgbiAKMDAwMDAwMDI0NCAwMDAwMCBuIAowMDAwMDExMTU0IDAwMDAwIG4gCjAw
+MDAwMTExNzYgMDAwMDAgbiAKMDAwMDAxMTM2OCAwMDAwMCBuIAowMDAwMDExNzA5IDAwMDAwIG4g
+CjAwMDAwMTE5MTAgMDAwMDAgbiAKMDAwMDAxMTk0MyAwMDAwMCBuIAowMDAwMDEyMTQwIDAwMDAw
+IG4gCjAwMDAwMTIxOTYgMDAwMDAgbiAKMDAwMDAxMjQyOSAwMDAwMCBuIAowMDAwMDEyNDk0IDAw
+MDAwIG4gCnRyYWlsZXIKPDwvU2l6ZSAxNi9Sb290IDE0IDAgUgovSW5mbyAxNSAwIFIKL0lEIFsg
+PEY3RDc3QjNEMjJCOUY5MjgyOUQ0OUZGNUQ3OEI4RjI4Pgo8RjdENzdCM0QyMkI5RjkyODI5RDQ5
+RkY1RDc4QjhGMjg+IF0KPj4Kc3RhcnR4cmVmCjEyNzg3CiUlRU9GCg==
+--------------80AB81809DF608AE8D353110
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+_______________________________________________
+Test-A mailing list
[email protected]
+subscribe or unsubscribe newsletter
+https://listserv.our-domain.de/mailman/listinfo/test-a
+
+--------------80AB81809DF608AE8D353110--
+
+--2458848.14.12--
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_44.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_44.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/simple_44.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/simple_44.txt 2020-12-18
19:27:23.000000000 +0100
@@ -0,0 +1,28 @@
+Subject: [Postmaster] Email Delivery Failure
+Message-Id: <[email protected]>
+Date: Fri, 18 Dec 2020 09:24:01 +0200
+From: "Mail Delivery System" <[email protected]>
+To: "dns-operations" <[email protected]>
+X-Mimecast-Originator: <>
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+X-MIME-Autoconverted: from quoted-printable to 8bit by example.net id
0BI7O1sk026573
+
+This is a delivery failure notification message indicating that
+an email [email protected] addressed to email address :
+-- [email protected]
+
+With subject Re: [dns-operations] Monitoring for impending expiration of
domains? sent on the Mon, 14 Dec 2020 11:30:37 +0100 (CET)
+could not be delivered. The problem appears to be :
+-- Recipient server unavailable or busy
+
+Additional information follows :
+-- 4.4.4 Temporary server error. Please try again later ATTR5
[VE1EUR02FT049.eop-EUR02.prod.protection.outlook.com]
+
+This condition occurred after 30 attempt(s) to deliver over
+a period of 92 hour(s) and 52 minute(s).
+
+If you sent the email to multiple recipients, you will receive one
+of these messages for each one which failed delivery, otherwise
+they have been sent.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/yahoo_12.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/yahoo_12.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/yahoo_12.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/yahoo_12.txt 2020-04-24
23:52:51.000000000 +0200
@@ -0,0 +1,18 @@
+From: [email protected]
+To: [email protected]
+Message-ID:
<1724157855.37526491587724620658.javamail.ya...@mpq204.consmr.mail.bf2.yahoo.com>
+MIME-Version: 1.0
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: 7bit
+Message-ID-Hash: NMFBS7K2KRA44XW6KCW6CW6NNKCXESHM
+X-Message-ID-Hash: NMFBS7K2KRA44XW6KCW6CW6NNKCXESHM
+X-MailFrom: [email protected]
+
+I'm afraid I wasn't able to deliver the following message.
+This is a permanent error; I've given up. Sorry it didn't work out.
+
+Subject: [List] Re: Name for MP3 Folder
+To: [email protected]
+
+---Below this line is a copy of the message.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/data/yahoo_13.txt
new/flufl.bounce-4.0/flufl/bounce/tests/data/yahoo_13.txt
--- old/flufl.bounce-3.0/flufl/bounce/tests/data/yahoo_13.txt 1970-01-01
01:00:00.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/data/yahoo_13.txt 2021-06-11
17:55:07.000000000 +0200
@@ -0,0 +1,51 @@
+Return-Path: <>
+Received: from sonic.gate.mail.ne1.yahoo.com by
sonic303.consmr.mail.ne1.yahoo.com with HTTP; Fri, 11 Jun 2021 13:59:55 +0000
+Date: Fri, 11 Jun 2021 13:59:55 +0000
+From: [email protected]
+To: [email protected]
+Message-ID:
+ <278929949.490718.1623419995...@sonic303.consmr.mail.ne1.yahoo.com>
+Subject: Failure Notice
+Content-Type: multipart/report; report-type=delivery-status;
+ boundary="-=Part.77cde.7cbe8eccd6310fd8.179fb5f46a7.49c125a19f0a1035=-"
+Content-Length: 5236
+
+---=Part.77cde.7cbe8eccd6310fd8.179fb5f46a7.49c125a19f0a1035=-
+Content-Type: text/plain; charset=UTF-8
+
+Sorry, we were unable to deliver your message to the following address.
+
+<[email protected]>:
+550: 5.1.1 <[email protected]>: Recipient address rejected: User
unknown in local recipient table
+
+---------- Forwarded message ----------
+
+---=Part.77cde.7cbe8eccd6310fd8.179fb5f46a7.49c125a19f0a1035=-
+Content-Type: message/rfc822
+
+X-Sonic-MF: <[email protected]>
+Received: from sonic.gate.mail.ne1.yahoo.com by
sonic303.consmr.mail.ne1.yahoo.com with HTTP; Fri, 11 Jun 2021 13:59:55 +0000
+Received: by kubenode558.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP
Server) with ESMTPA ID 007ece6be172ed81332d038abbd95120;
+ Fri, 11 Jun 2021 13:57:53 +0000 (UTC)
+To: [email protected]
+From: Some User <[email protected]>
+Subject: bounce me
+Message-ID: <[email protected]>
+Date: Fri, 11 Jun 2021 06:57:50 -0700
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0)
+ Gecko/20100101 Thunderbird/78.11.0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Language: en-US
+Content-Transfer-Encoding: 7bit
+References: <[email protected]>
+X-Mailer: WebService/1.1.18368
mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo
+Content-Length: 163
+
+this should bounce.
+
+This is somewhat bogus and contrived to test the separator.
+--
+<[email protected]>: My sig
+
+---=Part.77cde.7cbe8eccd6310fd8.179fb5f46a7.49c125a19f0a1035=---
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flufl.bounce-3.0/flufl/bounce/tests/test_detectors.py
new/flufl.bounce-4.0/flufl/bounce/tests/test_detectors.py
--- old/flufl.bounce-3.0/flufl/bounce/tests/test_detectors.py 2017-02-17
23:42:59.000000000 +0100
+++ new/flufl.bounce-4.0/flufl/bounce/tests/test_detectors.py 2021-06-17
02:58:36.000000000 +0200
@@ -7,7 +7,7 @@
from flufl.bounce._detectors.caiwireless import Caiwireless
from flufl.bounce._detectors.microsoft import Microsoft
from flufl.bounce._detectors.smtp32 import SMTP32
-from flufl.bounce._scan import scan_message
+from flufl.bounce._scan import all_failures, scan_message
from pkg_resources import resource_stream
@@ -61,6 +61,36 @@
self.assertEqual(scan_message(msg), set([b'[email protected]']))
+class TestScanAllDetectors(unittest.TestCase):
+ # Ensure that _scan runs detectors.
+ def test_llnl(self):
+ with closing(resource_stream('flufl.bounce.tests.data',
+ 'llnl_01.txt')) as fp:
+ msg = parse(fp)
+ self.assertEqual(scan_message(msg), set([b'[email protected]']))
+ temporary, permanent = all_failures(msg)
+ self.assertEqual(temporary, set())
+ self.assertEqual(permanent, set([b'[email protected]']))
+
+ def test_unrecognized(self):
+ with closing(resource_stream('flufl.bounce.tests.data',
+ 'dumbass_01.txt')) as fp:
+ msg = parse(fp)
+ self.assertEqual(scan_message(msg), set())
+ temporary, permanent = all_failures(msg)
+ self.assertEqual(temporary, set())
+ self.assertEqual(permanent, set())
+
+ def test_warning(self):
+ with closing(resource_stream('flufl.bounce.tests.data',
+ 'simple_03.txt')) as fp:
+ msg = parse(fp)
+ self.assertEqual(scan_message(msg), set())
+ temporary, permanent = all_failures(msg)
+ self.assertEqual(temporary, set([b'[email protected]']))
+ self.assertEqual(permanent, set())
+
+
class TestDetectors(unittest.TestCase):
# This is a pure placeholder for the nose2 plugin in
# flufl.bounce.testing.helpers.Detectors.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl.bounce.egg-info/PKG-INFO
new/flufl.bounce-4.0/flufl.bounce.egg-info/PKG-INFO
--- old/flufl.bounce-3.0/flufl.bounce.egg-info/PKG-INFO 2017-02-17
23:59:25.000000000 +0100
+++ new/flufl.bounce-4.0/flufl.bounce.egg-info/PKG-INFO 2021-06-17
03:02:38.000000000 +0200
@@ -1,10 +1,10 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: flufl.bounce
-Version: 3.0
+Version: 4.0
Summary: Email bounce detectors.
Home-page: https://fluflbounce.readthedocs.io/en/latest/
-Author: Barry Warsaw
-Author-email: [email protected]
+Maintainer: Barry Warsaw
+Maintainer-email: [email protected]
License: ASLv2
Download-URL: https://pypi.python.org/pypi/flufl.bounce
Description: UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/flufl.bounce.egg-info/SOURCES.txt
new/flufl.bounce-4.0/flufl.bounce.egg-info/SOURCES.txt
--- old/flufl.bounce-3.0/flufl.bounce.egg-info/SOURCES.txt 2017-02-17
23:59:25.000000000 +0100
+++ new/flufl.bounce-4.0/flufl.bounce.egg-info/SOURCES.txt 2021-06-17
03:02:39.000000000 +0200
@@ -1,3 +1,4 @@
+LICENSE
MANIFEST.in
README.rst
coverage.ini
@@ -66,6 +67,7 @@
flufl/bounce/tests/data/dsn_15.txt
flufl/bounce/tests/data/dsn_16.txt
flufl/bounce/tests/data/dsn_17.txt
+flufl/bounce/tests/data/dsn_18.txt
flufl/bounce/tests/data/dumbass_01.txt
flufl/bounce/tests/data/exim_01.txt
flufl/bounce/tests/data/groupwise_01.txt
@@ -76,6 +78,7 @@
flufl/bounce/tests/data/microsoft_01.txt
flufl/bounce/tests/data/microsoft_02.txt
flufl/bounce/tests/data/microsoft_03.txt
+flufl/bounce/tests/data/microsoft_04.txt
flufl/bounce/tests/data/netscape_01.txt
flufl/bounce/tests/data/newmailru_01.txt
flufl/bounce/tests/data/postfix_01.txt
@@ -133,6 +136,9 @@
flufl/bounce/tests/data/simple_39.txt
flufl/bounce/tests/data/simple_40.txt
flufl/bounce/tests/data/simple_41.txt
+flufl/bounce/tests/data/simple_42.txt
+flufl/bounce/tests/data/simple_43.txt
+flufl/bounce/tests/data/simple_44.txt
flufl/bounce/tests/data/sina_01.txt
flufl/bounce/tests/data/smtp32_01.txt
flufl/bounce/tests/data/smtp32_02.txt
@@ -152,4 +158,6 @@
flufl/bounce/tests/data/yahoo_09.txt
flufl/bounce/tests/data/yahoo_10.txt
flufl/bounce/tests/data/yahoo_11.txt
+flufl/bounce/tests/data/yahoo_12.txt
+flufl/bounce/tests/data/yahoo_13.txt
flufl/bounce/tests/data/yale_01.txt
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/setup.cfg
new/flufl.bounce-4.0/setup.cfg
--- old/flufl.bounce-3.0/setup.cfg 2017-02-17 23:59:25.000000000 +0100
+++ new/flufl.bounce-4.0/setup.cfg 2021-06-17 03:02:39.739791900 +0200
@@ -5,7 +5,6 @@
upload_dir = build/sphinx/html
[egg_info]
-tag_svn_revision = 0
-tag_date = 0
tag_build =
+tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flufl.bounce-3.0/tox.ini new/flufl.bounce-4.0/tox.ini
--- old/flufl.bounce-3.0/tox.ini 2017-02-17 23:13:22.000000000 +0100
+++ new/flufl.bounce-4.0/tox.ini 2020-11-15 00:43:32.000000000 +0100
@@ -1,5 +1,5 @@
[tox]
-envlist = {py34,py35,py36}-{cov,nocov,diffcov},qa,docs
+envlist = {py35,py36,py37,py38,py39}-{cov,nocov,diffcov},qa,docs
recreate = True
skip_missing_interpreters = True