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):