# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models, tools, _ from odoo.exceptions import UserError class MailBlackList(models.Model): """ Model of blacklisted email addresses to stop sending emails.""" _name = 'mail.blacklist' _inherit = ['mail.thread'] _description = 'Mail Blacklist' _rec_name = 'email' email = fields.Char(string='Email Address', required=True, index='trigram', help='This field is case insensitive.', tracking=1) active = fields.Boolean(default=True, tracking=2) _sql_constraints = [ ('unique_email', 'unique (email)', 'Email address already exists!') ] @api.model_create_multi def create(self, values): # First of all, extract values to ensure emails are really unique (and don't modify values in place) new_values = [] all_emails = [] for value in values: email = tools.email_normalize(value.get('email')) if not email: raise UserError(_('Invalid email address %r', value['email'])) if email in all_emails: continue all_emails.append(email) new_value = dict(value, email=email) new_values.append(new_value) """ To avoid crash during import due to unique email, return the existing records if any """ to_create = [] bl_entries = {} if new_values: sql = '''SELECT email, id FROM mail_blacklist WHERE email = ANY(%s)''' emails = [v['email'] for v in new_values] self._cr.execute(sql, (emails,)) bl_entries = dict(self._cr.fetchall()) to_create = [v for v in new_values if v['email'] not in bl_entries] # TODO DBE Fixme : reorder ids according to incoming ids. results = super(MailBlackList, self).create(to_create) return self.env['mail.blacklist'].browse(bl_entries.values()) | results def write(self, values): if 'email' in values: values['email'] = tools.email_normalize(values['email']) return super(MailBlackList, self).write(values) def _search(self, domain, offset=0, limit=None, order=None, access_rights_uid=None): """ Override _search in order to grep search on email field and make it lower-case and sanitized """ def normalize(arg): if isinstance(arg, (list, tuple)) and arg[0] == 'email' and isinstance(arg[2], str): normalized = tools.email_normalize(arg[2]) if normalized: return (arg[0], arg[1], normalized) return arg domain = [normalize(item) for item in domain] return super()._search(domain, offset, limit, order, access_rights_uid) def _add(self, email, message=None): normalized = tools.email_normalize(email) record = self.env["mail.blacklist"].with_context(active_test=False).search([('email', '=', normalized)]) if len(record) > 0: if message: record._track_set_log_message(message) record.action_unarchive() else: record = self.create({'email': email}) if message: record.with_context(mail_create_nosubscribe=True).message_post( body=message, subtype_xmlid='mail.mt_note', ) return record def _remove(self, email, message=None): normalized = tools.email_normalize(email) record = self.env["mail.blacklist"].with_context(active_test=False).search([('email', '=', normalized)]) if len(record) > 0: if message: record._track_set_log_message(message) record.action_archive() else: record = record.create({'email': email, 'active': False}) if message: record.with_context(mail_create_nosubscribe=True).message_post( body=message, subtype_xmlid='mail.mt_note', ) return record def mail_action_blacklist_remove(self): return { 'name': _('Are you sure you want to unblacklist this Email Address?'), 'type': 'ir.actions.act_window', 'view_mode': 'form', 'res_model': 'mail.blacklist.remove', 'target': 'new', } def action_add(self): self._add(self.email)