def _parse_partner_name(self, text): """ Parse partner name (given by text) in order to find a name and an email. Supported syntax: * Raoul <*****@*****.**> * "Raoul le Grand" <*****@*****.**> * Raoul [email protected] (strange fault tolerant support from df40926d2a57c101a3e2d221ecfd08fbb4fea30e) Otherwise: default, everything is set as the name. Starting from 13.3 returned email will be normalized to have a coherent encoding. """ name, email = '', '' split_results = tools.email_split_tuples(text) if split_results: name, email = split_results[0] if email and not name: fallback_emails = tools.email_split(text.replace(' ', ',')) if fallback_emails: email = fallback_emails[0] name = text[:text.index(email)].replace('"', '').replace('<', '').strip() if email: email = tools.email_normalize(email) else: name, email = text, '' return name, email
def _mail_cc_sanitized_raw_dict(self, cc_string): '''return a dict of sanitize_email:raw_email from a string of cc''' if not cc_string: return {} return { tools.email_normalize(email): formataddr( (name, tools.email_normalize(email))) for (name, email) in tools.email_split_tuples(cc_string) }
def test_tools_email_split_tuples(self): expected = [ # single email [('', '*****@*****.**')], [('', '*****@*****.**')], [('Fredo The Great', '*****@*****.**')], [('Fredo The Great', '*****@*****.**')], [('Fredo The Great', '*****@*****.**')], # multiple emails [('', '*****@*****.**'), ('', '*****@*****.**')], [('Fredo The Great', '*****@*****.**'), ('Evelyne The Goat', '*****@*****.**')], [('Fredo The Great', '*****@*****.**'), ('', '*****@*****.**')], [('Fredo The Great', '*****@*****.**'), ('', '*****@*****.**')], # text containing email -> probably not designed for that [('', 'Hello [email protected]?')], [('', 'Hello [email protected]')], # text containing emails -> probably not designed for that [('Hello Fredo', '*****@*****.**'), ('', '*****@*****.**')], [('Hello Fredo', '*****@*****.**'), ('', 'and [email protected]')], # falsy -> probably not designed for that [], [('', "j'adore écrire [email protected]"), ('', '@gmail.com')], [], ] for src, exp in zip(self.sources, expected): res = tools.email_split_tuples(src) self.assertEqual( res, exp, 'Seems email_split_tuples is broken with %s (expected %r, received %r)' % (src, exp, res))
def action_import(self): """Import each lines of "contact_list" as a new contact.""" self.ensure_one() contacts = tools.email_split_tuples(self.contact_list) if not contacts: return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': _('No valid email address found.'), 'next': {'type': 'ir.actions.act_window_close'}, 'sticky': False, 'type': 'warning', } } if len(contacts) > 5000: return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': _('You have to much emails, please upload a file.'), 'type': 'warning', 'sticky': False, 'next': self.action_open_base_import(), } } all_emails = list({values[1].lower() for values in contacts}) existing_contacts = self.env['mailing.contact'].search([ ('email_normalized', 'in', all_emails), ('list_ids', 'in', self.mailing_list_ids.ids), ]) existing_contacts = { contact.email_normalized: contact for contact in existing_contacts } # Remove duplicated record, keep only the first non-empty name for each email address unique_contacts = {} for name, email in contacts: email = email.lower() if unique_contacts.get(email, {}).get('name'): continue if email in existing_contacts and not self.mailing_list_ids < existing_contacts[email].list_ids: existing_contacts[email].list_ids |= self.mailing_list_ids if email not in existing_contacts: unique_contacts[email] = { 'name': name, 'list_ids': self.mailing_list_ids.ids, } if not unique_contacts: return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': _('No contacts were imported. All email addresses are already in the mailing list.'), 'next': {'type': 'ir.actions.act_window_close'}, 'sticky': False, 'type': 'warning', } } new_contacts = self.env['mailing.contact'].with_context(clean_context(self.env.context)).create([ { 'email': email, **values, } for email, values in unique_contacts.items() ]) ignored = len(contacts) - len(unique_contacts) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': ( _('%i Contacts have been imported.', len(unique_contacts)) + (_(' %i duplicates have been ignored.', ignored) if ignored else '') ), 'type': 'success', 'sticky': False, 'next': { 'context': self.env.context, 'domain': [('id', 'in', new_contacts.ids)], 'name': _('New contacts imported'), 'res_model': 'mailing.contact', 'type': 'ir.actions.act_window', 'view_mode': 'list', 'views': [[False, 'list'], [False, 'form']], }, } }
def _mail_cc_sanitized_raw_dict(self, cc_string): '''return a dict of sanitize_email:raw_email from a string of cc''' if not cc_string: return {} return {tools.email_normalize(email): formataddr((name, tools.email_normalize(email))) for (name, email) in tools.email_split_tuples(cc_string)}