diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 295783dd384..53bf142f5ef 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1409,7 +1409,7 @@ class Binary(http.Controller): if filename_field: fields.append(filename_field) if data: - res = { field: data } + res = {field: data, filename_field: jdata.get('filename', None)} elif id: res = Model.read([int(id)], fields, context)[0] else: diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index f5db72de3fa..d6ba058d356 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5300,14 +5300,17 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. } else { instance.web.blockUI(); var c = instance.webclient.crashmanager; + var filename_fieldname = this.node.attrs.filename; + var filename_field = this.view.fields && this.view.fields[filename_fieldname]; this.session.get_file({ url: '/web/binary/saveas_ajax', data: {data: JSON.stringify({ model: this.view.dataset.model, id: (this.view.datarecord.id || ''), field: this.name, - filename_field: (this.node.attrs.filename || ''), + filename_field: (filename_fieldname || ''), data: instance.web.form.is_bin_size(value) ? null : value, + filename: filename_field ? filename_field.get('value') : null, context: this.view.dataset.get_context() })}, complete: instance.web.unblockUI, diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 73eb0f74119..789515e7574 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -363,6 +363,27 @@ class ir_mail_server(osv.osv): msg.attach(part) return msg + def _get_default_bounce_address(self, cr, uid, context=None): + '''Compute the default bounce address. + + The default bounce address is used to set the envelop address if no + envelop address is provided in the message. It is formed by properly + joining the parameters "mail.catchall.alias" and + "mail.catchall.domain". + + If "mail.catchall.alias" is not set it defaults to "postmaster-odoo". + + If "mail.catchall.domain" is not set, return None. + + ''' + get_param = self.pool['ir.config_parameter'].get_param + postmaster = get_param(cr, uid, 'mail.bounce.alias', + default='postmaster-odoo', + context=context,) + domain = get_param(cr, uid, 'mail.catchall.domain', context=context) + if postmaster and domain: + return '%s@%s' % (postmaster, domain) + def send_email(self, cr, uid, message, mail_server_id=None, smtp_server=None, smtp_port=None, smtp_user=None, smtp_password=None, smtp_encryption=None, smtp_debug=False, context=None): @@ -378,8 +399,9 @@ class ir_mail_server(osv.osv): and fails if not found. :param message: the email.message.Message to send. The envelope sender will be extracted from the - ``Return-Path`` or ``From`` headers. The envelope recipients will be - extracted from the combined list of ``To``, ``CC`` and ``BCC`` headers. + ``Return-Path`` (if present), or will be set to the default bounce address. + The envelope recipients will be extracted from the combined list of ``To``, + ``CC`` and ``BCC`` headers. :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments. :param smtp_server: optional hostname of SMTP server to use :param smtp_encryption: optional TLS mode, one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation) @@ -390,7 +412,14 @@ class ir_mail_server(osv.osv): :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises MailDeliveryException and logs root cause. """ - smtp_from = message['Return-Path'] or message['From'] + # Use the default bounce address **only if** no Return-Path was + # provided by caller. Caller may be using Variable Envelope Return + # Path (VERP) to detect no-longer valid email addresses. + smtp_from = message['Return-Path'] + if not smtp_from: + smtp_from = self._get_default_bounce_address(cr, uid, context=context) + if not smtp_from: + smtp_from = message['From'] assert smtp_from, "The Return-Path or From header is required for any outbound email" # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters. diff --git a/openerp/tools/safe_eval.py b/openerp/tools/safe_eval.py index a274de8468a..0094881e325 100644 --- a/openerp/tools/safe_eval.py +++ b/openerp/tools/safe_eval.py @@ -32,6 +32,7 @@ condition/math builtins. # - safe_eval in tryton http://hg.tryton.org/hgwebdir.cgi/trytond/rev/bbb5f73319ad from opcode import HAVE_ARGUMENT, opmap, opname +from psycopg2 import OperationalError from types import CodeType import logging @@ -321,6 +322,10 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal raise except openerp.exceptions.AccessError: raise + except OperationalError: + # Do not hide PostgreSQL low-level exceptions, to let the auto-replay + # of serialized transactions work its magic + raise except Exception, e: import sys exc_info = sys.exc_info()