Browse Source

more radical solution

pull/1/head
Ivan Yelizariev 11 years ago
parent
commit
27eb42fd28
  1. 109
      mail_fix_553.py

109
mail_fix_553.py

@ -1,23 +1,114 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import base64
import logging
import re import re
from openerp.osv import osv, fields
from urllib import urlencode
from urlparse import urljoin
from openerp import tools
from openerp import SUPERUSER_ID 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): class mail_mail(osv.Model):
_inherit = "mail.mail" _inherit = "mail.mail"
def send(self, cr, uid, ids, context=None, **kwargs):
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_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) catchall_domain = self.pool['ir.config_parameter'].get_param(cr, uid, "mail.catchall.domain", context=context)
fix_ids = []
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): for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
if re.search('@%s>?\s*$'%catchall_domain, mail.email_from) is None:
fix_ids.append(mail.id)
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
if re.search(correct_email_from, email_from) is None:
email_from = default_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=mail.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)
email_from = '%s@%s' % (catchall_alias, catchall_domain)
if res:
mail.write({'state': 'sent', 'message_id': res})
mail_sent = True
else:
mail.write({'state': 'exception'})
mail_sent = False
if fix_ids:
self.write(cr, uid, fix_ids, {'email_from': email_from}, context=context)
# /!\ 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
return super(mail_mail, self).send(cr, uid, ids, context=context, **kwargs)
if auto_commit == True:
cr.commit()
return True
Loading…
Cancel
Save