# -*- coding: utf-8 -*- import base64 import logging import re from urllib import urlencode from urlparse import urljoin from openerp import tools from openerp import SUPERUSER_ID from openerp.addons.base.ir.ir_mail_server import MailDeliveryException from openerp.osv import fields, osv from openerp.tools.translate import _ _logger = logging.getLogger(__name__) class mail_mail(osv.Model): _inherit = "mail.mail" def send(self, cr, uid, ids, auto_commit=False, raise_exception=False, context=None): """ Sends the selected emails immediately, ignoring their current state (mails that have already been sent should not be passed unless they should actually be re-sent). Emails successfully delivered are marked as 'sent', and those that fail to be deliver are marked as 'exception', and the corresponding error mail is output in the server logs. :param bool auto_commit: whether to force a commit of the mail status after sending each mail (meant only for scheduler processing); should never be True during normal transactions (default: False) :param bool raise_exception: whether to raise an exception if the email sending process has failed :return: True """ catchall_alias = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.catchall.alias", context=context) catchall_domain = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.catchall.domain", context=context) correct_email_from = '@%s>?\s*$'%catchall_domain default_email_from = '%s@%s' % (catchall_alias, catchall_domain) ir_mail_server = self.pool.get('ir.mail_server') for mail in self.browse(cr, SUPERUSER_ID, ids, context=context): try: # handle attachments attachments = [] for attach in mail.attachment_ids: attachments.append((attach.datas_fname, base64.b64decode(attach.datas))) # specific behavior to customize the send email for notified partners email_list = [] if mail.email_to: email_list.append(self.send_get_email_dict(cr, uid, mail, context=context)) for partner in mail.recipient_ids: email_list.append(self.send_get_email_dict(cr, uid, mail, partner=partner, context=context)) # headers headers = {} bounce_alias = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.bounce.alias", context=context) catchall_domain = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.catchall.domain", context=context) if bounce_alias and catchall_domain: if mail.model and mail.res_id: headers['Return-Path'] = '%s-%d-%s-%d@%s' % (bounce_alias, mail.id, mail.model, mail.res_id, catchall_domain) else: headers['Return-Path'] = '%s-%d@%s' % (bounce_alias, mail.id, catchall_domain) # build an RFC2822 email.message.Message object and send it without queuing res = None for email in email_list: email_from = mail.email_from reply_to = mail.reply_to if re.search(correct_email_from, email_from) is None: email_from = default_email_from else: reply_to = email_from msg = ir_mail_server.build_email( email_from=email_from, email_to=email.get('email_to'), subject=email.get('subject'), body=email.get('body'), body_alternative=email.get('body_alternative'), email_cc=tools.email_split(mail.email_cc), reply_to=reply_to, attachments=attachments, message_id=mail.message_id, references=mail.references, object_id=mail.res_id and ('%s-%s' % (mail.res_id, mail.model)), subtype='html', subtype_alternative='plain', headers=headers) res = ir_mail_server.send_email(cr, uid, msg, mail_server_id=mail.mail_server_id.id, context=context) if res: mail.write({'state': 'sent', 'message_id': res}) mail_sent = True else: mail.write({'state': 'exception'}) mail_sent = False # /!\ can't use mail.state here, as mail.refresh() will cause an error # see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1 if mail_sent: self._postprocess_sent_message(cr, uid, mail, context=context) except Exception as e: _logger.exception('failed sending mail.mail %s', mail.id) mail.write({'state': 'exception'}) if raise_exception: if isinstance(e, AssertionError): # get the args of the original error, wrap into a value and throw a MailDeliveryException # that is an except_orm, with name and value as arguments value = '. '.join(e.args) raise MailDeliveryException(_("Mail Delivery Failed"), value) raise if auto_commit == True: cr.commit() return True