[MERGE] Forward-port latest saas-3 bugfixes, up to 30f43da
authorOlivier Dony <odo@openerp.com>
Tue, 27 May 2014 15:18:43 +0000 (17:18 +0200)
committerOlivier Dony <odo@openerp.com>
Tue, 27 May 2014 15:18:43 +0000 (17:18 +0200)
12 files changed:
1  2 
addons/account/account_invoice_view.xml
addons/account/report/account_aged_partner_balance.py
addons/account_analytic_analysis/account_analytic_analysis.py
addons/hr_recruitment/hr_recruitment.py
addons/mail/static/src/js/mail.js
addons/purchase/purchase.py
addons/web/static/src/js/view_form.js
addons/website/models/ir_http.py
addons/website_sale/controllers/main.py
addons/website_sale/models/product.py
openerp/http.py
openerp/report/render/rml2pdf/trml2pdf.py

Simple merge
Simple merge
Simple merge
@@@ -79,102 -78,70 +79,102 @@@ class ir_http(orm.AbstractModel)
  
          return self._dispatch()
  
 -    def _postprocess_args(self, arguments):
 -        if hasattr(request, 'rerouting'):
 -            url = request.rerouting[0]
 -        else:
 -            url = request.httprequest.url
 -        original_url = url
 -        for arg in arguments.itervalues():
 -            if isinstance(arg, orm.browse_record) and isinstance(arg._uid, RequestUID):
 -                placeholder = arg._uid
 -                arg._uid = request.uid
 -                try:
 -                    good_slug = slug(arg)
 -                    if str(arg.id) != placeholder.value and placeholder.value != good_slug:
 -                        # TODO: properly recompose the url instead of using replace()
 -                        url = url.replace(placeholder.value, good_slug)
 -                except KeyError:
 -                    return self._handle_exception(werkzeug.exceptions.NotFound())
 -        if url != original_url:
 -            werkzeug.exceptions.abort(werkzeug.utils.redirect(url))
 +    def _postprocess_args(self, arguments, rule):
 +        if not getattr(request, 'website_enabled', False):
 +            return super(ir_http, self)._postprocess_args(arguments, rule)
 +
 +        for arg, val in arguments.items():
 +            # Replace uid placeholder by the current request.uid
 +            if isinstance(val, orm.browse_record) and isinstance(val._uid, RequestUID):
 +                val._uid = request.uid
 +        try:
 +            _, path = rule.build(arguments)
 +            assert path is not None
 +        except Exception:
 +            return self._handle_exception(werkzeug.exceptions.NotFound())
 +
 +        if request.httprequest.method in ('GET', 'HEAD'):
 +            generated_path = werkzeug.url_unquote_plus(path)
 +            current_path = werkzeug.url_unquote_plus(request.httprequest.path)
 +            if generated_path != current_path:
 +                if request.lang != request.website.default_lang_code:
 +                    path = '/' + request.lang + path
 +                return werkzeug.utils.redirect(path)
 +
 +    def _serve_attachment(self):
 +        domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
 +        attach = self.pool['ir.attachment'].search_read(request.cr, openerp.SUPERUSER_ID, domain, ['__last_update', 'datas', 'mimetype'], context=request.context)
 +        if attach:
 +            wdate = attach[0]['__last_update']
 +            datas = attach[0]['datas']
 +            response = werkzeug.wrappers.Response()
 +            server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
 +            try:
 +                response.last_modified = datetime.datetime.strptime(wdate, server_format + '.%f')
 +            except ValueError:
 +                # just in case we have a timestamp without microseconds
 +                response.last_modified = datetime.datetime.strptime(wdate, server_format)
 +
 +            response.set_etag(hashlib.sha1(datas).hexdigest())
 +            response.make_conditional(request.httprequest)
 +
 +            if response.status_code == 304:
 +                return response
 +
 +            response.mimetype = attach[0]['mimetype']
 +            response.data = datas.decode('base64')
 +            return response
  
      def _handle_exception(self, exception=None, code=500):
-         res = super(ir_http, self)._handle_exception(exception)
-         if isinstance(exception, werkzeug.exceptions.HTTPException) and hasattr(exception, 'response') and exception.response:
-             return exception.response
+         try:
+             return super(ir_http, self)._handle_exception(exception)
+         except Exception:
 +
 +        attach = self._serve_attachment()
 +        if attach:
 +            return attach
 +
-         if getattr(request, 'website_enabled', False) and request.website:
-             values = dict(
-                 exception=exception,
-                 traceback=traceback.format_exc(exception),
-             )
-             if exception:
-                 code = getattr(exception, 'code', code)
-                 if isinstance(exception, ir_qweb.QWebException):
-                     values.update(qweb_exception=exception)
-                     if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
-                         code = 403
-             if code == 500:
-                 logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
-                 if 'qweb_exception' in values:
-                     view = request.registry.get("ir.ui.view")
-                     views = view._views_get(request.cr, request.uid, exception.qweb['template'], request.context)
-                     to_reset = [v for v in views if v.model_data_id.noupdate is True]
-                     values['views'] = to_reset
-             elif code == 403:
-                 logger.warn("403 Forbidden:\n\n%s", values['traceback'])
-             values.update(
-                 status_message=werkzeug.http.HTTP_STATUS_CODES[code],
-                 status_code=code,
-             )
-             if not request.uid:
-                 self._auth_method_public()
-             try:
-                 html = request.website._render('website.%s' % code, values)
-             except Exception:
-                 html = request.website._render('website.http_error', values)
-             return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
-         return res
+             if getattr(request, 'website_enabled', False) and request.website:
+                 values = dict(
+                     exception=exception,
+                     traceback=traceback.format_exc(exception),
+                 )
+                 if exception:
+                     code = getattr(exception, 'code', code)
+                     if isinstance(exception, ir_qweb.QWebException):
+                         values.update(qweb_exception=exception)
+                         if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
+                             code = 403
+                 if code == 500:
+                     logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
+                     if 'qweb_exception' in values:
+                         view = request.registry.get("ir.ui.view")
+                         views = view._views_get(request.cr, request.uid, exception.qweb['template'], request.context)
+                         to_reset = [v for v in views if v.model_data_id.noupdate is True]
+                         values['views'] = to_reset
+                 elif code == 403:
+                     logger.warn("403 Forbidden:\n\n%s", values['traceback'])
+                 values.update(
+                     status_message=werkzeug.http.HTTP_STATUS_CODES[code],
+                     status_code=code,
+                 )
+                 if not request.uid:
+                     self._auth_method_public()
+                 try:
+                     html = request.website._render('website.%s' % code, values)
+                 except Exception:
+                     html = request.website._render('website.http_error', values)
+                 return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
+             raise
  
  class ModelConverter(ir.ir_http.ModelConverter):
 -    def __init__(self, url_map, model=False):
 +    def __init__(self, url_map, model=False, domain='[]'):
          super(ModelConverter, self).__init__(url_map, model)
 +        self.domain = domain
          self.regex = r'(?:[A-Za-z0-9-_]+?-)?(\d+)(?=$|/)'
  
      def to_url(self, value):
Simple merge
diff --cc openerp/http.py
Simple merge