[IMP] base: fallback on 'email_re' when getadresses fails

When 'getadresses' fails at parsing some input and give us a result like
'gmail.com' (see previous commit adding test cases) we fallback on using
'email_re' which is better at finding email addresses in a global string.
We use it only in this specific case as fallback mechanism to rely on
'getadresses' when possible.

Task-3572208

X-original-commit: odoo/odoo@8e61a3b690
Part-of: odoo/odoo#141856
This commit is contained in:
Thibault Delavallée
2023-11-17 16:11:51 +00:00
parent d5b39338ff
commit a03ae3765e
2 changed files with 60 additions and 20 deletions
+46 -18
View File
@@ -520,7 +520,7 @@ class TestEmailTools(BaseCase):
'deboulonneur@example.com',
'deboulonneur@example.comdéboulonneur',
False,
'@example.com', # funny
False, # need fix over 'getadresses'
'deboulonneur.😊@example.com',
'déboulonneur@examplé.com',
'DéBoulonneur@examplé.com',
@@ -530,7 +530,7 @@ class TestEmailTools(BaseCase):
f'"{format_name}" <deboulonneur@example.com>',
f'"{format_name}" <deboulonneur@example.comdéboulonneur>',
f'"{format_name}" <@>',
f'"{format_name}" <@example.com>',
f'"{format_name}" <@>',
f'"{format_name}" <deboulonneur.😊@example.com>',
f'"{format_name}" <déboulonneur@examplé.com>',
f'"{format_name}" <DéBoulonneur@examplé.com>',
@@ -540,7 +540,7 @@ class TestEmailTools(BaseCase):
f'{format_name_ascii} <deboulonneur@example.com>',
f'{format_name_ascii} <deboulonneur@example.xn--comdboulonneur-ekb>',
f'{format_name_ascii} <@>',
f'{format_name_ascii} <@example.com>',
f'{format_name_ascii} <@>',
f'{format_name_ascii} <deboulonneur.😊@example.com>',
f'{format_name_ascii} <déboulonneur@xn--exampl-gva.com>',
f'{format_name_ascii} <DéBoulonneur@xn--exampl-gva.com>',
@@ -594,24 +594,52 @@ class TestEmailTools(BaseCase):
('"john@gmail.com"<johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting
('"<jg>" <johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting with brackets
('@gmail.com', ['@gmail.com']), # no left-part
# TFR cases
# '@domain' corner cases -- all those return a '@gmail.com' (or equivalent)
# email address when going through 'getaddresses'
# - multi @
('fr@ncois.th@notgmail.com', ['@notgmail.com']),
('f@r@nc.gz,ois@notgmail.com', ['@nc.gz', 'ois@notgmail.com']),
('@notgmail.com esteban_gnole@coldmail.com@notgmail.com', ['@notgmail.com']),
('fr@ncois.th@notgmail.com', ['fr@ncois.th']),
('f@r@nc.gz,ois@notgmail.com', ['r@nc.gz', 'ois@notgmail.com']), # still failing, but differently from 'getaddresses' alone
('@notgmail.com esteban_gnole@coldmail.com@notgmail.com', ['esteban_gnole@coldmail.com']),
# - multi emails (with invalid)
('Ivan@dezotos.com Cc iv.an@notgmail.com', ['@notgmail.com']),
('ivan-dredi@coldmail.com ivan.dredi@notgmail.com', ['@notgmail.com']),
('@notgmail.com ivan@coincoin.com.ar jeanine@coincoin.com.ar', ['@coincoin.com.ar']),
('@notgmail.com whoareyou@youhou.com. ivan.dezotos@notgmail.com', ['@notgmail.com']),
('francois@nc.gz CC: ois@notgmail.com ivan@dezotos.com', ['francois@nc.gzCC', '@dezotos.com']),
('francois@nc.gz CC: ois@notgmail.com,ivan@dezotos.com', ['francois@nc.gzCC', 'ois@notgmail.com', 'ivan@dezotos.com']),
(
'Ivan@dezotos.com Cc iv.an@notgmail.com',
['Ivan@dezotos.com', 'iv.an@notgmail.com']
),
(
'ivan-dredi@coldmail.com ivan.dredi@notgmail.com',
['ivan-dredi@coldmail.com', 'ivan.dredi@notgmail.com']
),
(
'@notgmail.com ivan@coincoin.com.ar jeanine@coincoin.com.ar',
['ivan@coincoin.com.ar', 'jeanine@coincoin.com.ar']
),
(
'@notgmail.com whoareyou@youhou.com. ivan.dezotos@notgmail.com',
['whoareyou@youhou.com', 'ivan.dezotos@notgmail.com']
),
(
'francois@nc.gz CC: ois@notgmail.com ivan@dezotos.com',
['francois@nc.gz', 'ois@notgmail.com', 'ivan@dezotos.com']
),
(
'francois@nc.gz CC: ois@notgmail.com,ivan@dezotos.com',
['francois@nc.gzCC', 'ois@notgmail.com', 'ivan@dezotos.com']
),
# - separated with '/''
('ivan.plein@dezotos.com / ivan.plu@notgmail.com', ['@notgmail.com']),
('@notgmail.com ivan.parfois@notgmail.com/ ivan.souvent@notgmail.com', ['@notgmail.com']),
(
'ivan.plein@dezotos.com / ivan.plu@notgmail.com',
['ivan.plein@dezotos.com', 'ivan.plu@notgmail.com']
),
(
'@notgmail.com ivan.parfois@notgmail.com/ ivan.souvent@notgmail.com',
['ivan.parfois@notgmail.com', 'ivan.souvent@notgmail.com']
),
# - separated with '-''
('ivan@dezotos.com - ivan.dezotos@notgmail.com', ['@notgmail.com']),
('car.pool@notgmail.com - co (TAMBO) Registration car.warsh@notgmail.com', ['@notgmail.com']),
('ivan@dezotos.com - ivan.dezotos@notgmail.com', ['ivan@dezotos.com', 'ivan.dezotos@notgmail.com']),
(
'car.pool@notgmail.com - co (TAMBO) Registration car.warsh@notgmail.com',
['car.pool@notgmail.com', 'car.warsh@notgmail.com']
),
]
for source, expected in cases:
with self.subTest(source=source):
@@ -649,7 +677,7 @@ class TestEmailTools(BaseCase):
# multi
['deboulonneur@example.com'],
['deboulonneur@example.com', 'deboulonneur2@example.com'],
['@example.com'], # funny one
['deboulonneur@example.com', 'deboulonneur2@example.com'], # need fix over 'getadresses'
# format / misc
['deboulonneur@example.com'],
['"Super Déboulonneur" <deboulonneur@example.com>', '"Super Déboulonneur 2" <deboulonneur2@example.com>'],
+14 -2
View File
@@ -549,13 +549,25 @@ def email_split_tuples(text):
if not text:
return []
return list(map(_parse_based_on_spaces, [
# found valid pairs, filtering out failed parsing
valid_pairs = [
(addr[0], addr[1]) for addr in getaddresses([text])
# getaddresses() returns '' when email parsing fails, and
# sometimes returns emails without at least '@'. The '@'
# is strictly required in RFC2822's `addr-spec`.
if addr[1] and '@' in addr[1]
]))
]
# corner case: returning '@gmail.com'-like email (see test_email_split)
if any(pair[1].startswith('@') for pair in valid_pairs):
filtered = [
found_email for found_email in email_re.findall(text)
if found_email and not found_email.startswith('@')
]
if filtered:
valid_pairs = [('', found_email) for found_email in filtered]
return list(map(_parse_based_on_spaces, valid_pairs))
def email_split(text):
""" Return a list of the email addresses found in ``text`` """