From 36f2ff879a8726a86c7bab87ceec4657dbbf93b6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 7 Mar 2014 16:14:31 +0100 Subject: [PATCH 1/9] [FIX] web: use jinja2.FileSystemLoader instead of PackageLoader on windows bzr revid: chs@openerp.com-20140307151431-5k24u6lnlypv1s64 --- addons/web/controllers/main.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index a9f56a2099c..43b109560a8 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -14,6 +14,7 @@ import hashlib import os import re import simplejson +import sys import time import urllib2 import zlib @@ -37,10 +38,14 @@ from openerp.http import request, serialize_exception as _serialize_exception _logger = logging.getLogger(__name__) -env = jinja2.Environment( - loader=jinja2.PackageLoader('openerp.addons.web', "views"), - autoescape=True -) +if hasattr(sys, 'frozen'): + # When running on compiled windows binary, we don't have access to package loader. + path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views')) + loader = jinja2.FileSystemLoader(path) +else: + loader = jinja2.PackageLoader('openerp.addons.web', "views") + +env = jinja2.Environment(loader=loader, autoescape=True) env.filters["json"] = simplejson.dumps #---------------------------------------------------------- From f147ea8eede5663cba466eb9d06dcadd7b826345 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 7 Mar 2014 21:00:55 +0100 Subject: [PATCH 2/9] [FIX] wsgi deployement with openerp-wsgi.py bzr revid: al@openerp.com-20140307200055-vbf9tub4gl9edig0 --- openerp-wsgi.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openerp-wsgi.py b/openerp-wsgi.py index 90f43ddab21..4a3f34d5764 100644 --- a/openerp-wsgi.py +++ b/openerp-wsgi.py @@ -40,6 +40,8 @@ conf['addons_path'] = '../../addons/trunk,../../web/trunk/addons' #---------------------------------------------------------- application = openerp.service.wsgi_server.application +openerp.service.server.load_server_wide_modules() + #---------------------------------------------------------- # Gunicorn #---------------------------------------------------------- From b73cef90074fce8a2d1082bb58f422b1cbf35b5e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Mar 2014 09:32:04 +0100 Subject: [PATCH 3/9] [FIX] don't fail installation entirely if pyPdf isn't available should print an error message though bzr revid: xmo@openerp.com-20140310083204-9akr4ucwqzbv3oxu --- addons/report/controllers/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py index f71d4ea7d8b..1a839fc2c1f 100644 --- a/addons/report/controllers/main.py +++ b/addons/report/controllers/main.py @@ -42,7 +42,6 @@ import os from distutils.version import LooseVersion -from pyPdf import PdfFileWriter, PdfFileReader from werkzeug import exceptions from werkzeug.test import Client from werkzeug.wrappers import BaseResponse @@ -51,7 +50,10 @@ from reportlab.graphics.barcode import createBarcodeDrawing _logger = logging.getLogger(__name__) - +try: + from pyPdf import PdfFileWriter, PdfFileReader +except ImportError: + PdfFileWriter = PdfFileReader = None class Report(http.Controller): From d16bcfb981ea859266e2a16544a386d287d1a20d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Mar 2014 10:59:18 +0100 Subject: [PATCH 4/9] [FIX] nonsensical import? bzr revid: xmo@openerp.com-20140310095918-khwzn6oqx77w0pyc --- openerp/addons/base/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openerp/addons/base/__init__.py b/openerp/addons/base/__init__.py index 26b39de74ad..237e3a22cba 100644 --- a/openerp/addons/base/__init__.py +++ b/openerp/addons/base/__init__.py @@ -24,7 +24,6 @@ import workflow import module import res import report -import test import tests # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From b3de4ca481c6b5fd6f9df178270473fd8efb97c1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Mar 2014 11:15:54 +0100 Subject: [PATCH 5/9] [IMP] readability of phantomjs timeouts bzr revid: xmo@openerp.com-20140310101554-6imrb3hnd95q1wgu --- openerp/tests/common.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 75207841454..4dcd2938ffe 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -16,6 +16,8 @@ import unittest2 import urllib2 import xmlrpclib +from datetime import datetime, timedelta + import openerp _logger = logging.getLogger(__name__) @@ -194,11 +196,12 @@ class HttpCase(TransactionCase): Other lines are relayed to the test log. """ - t0 = time.time() + t0 = datetime.now() + td = timedelta(seconds=timeout) buf = bytearray() while True: # timeout - self.assertLess(time.time(), t0 + timeout, + self.assertLess(datetime.now() - t0, td, "PhantomJS tests should take less than %s seconds" % timeout) # read a byte From bcbe89fbdcbe3b736e3ef8887e6a1099e61e642b Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Mar 2014 12:24:01 +0100 Subject: [PATCH 6/9] [IMP] phantomjs waitloop * simplify waitFor itself * log a "waiting for" message if the expression evaluates but is *false* bzr revid: xmo@openerp.com-20140310112401-khvy0zcvwaaxa5om --- openerp/tests/phantomtest.js | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/openerp/tests/phantomtest.js b/openerp/tests/phantomtest.js index 1cdfeabce76..bfd6fa4d0b2 100644 --- a/openerp/tests/phantomtest.js +++ b/openerp/tests/phantomtest.js @@ -2,22 +2,17 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) { timeout = timeout || 10000; - var start = new Date().getTime(); - var condition = ready(); - var interval = setInterval(function() { - if ((new Date().getTime() - start < timeout) && !condition ) { - condition = ready(); + var start = new Date; + + (function waitLoop() { + if(new Date - start > timeout) { + error(timeoutMessageCallback ? timeoutMessageCallback() : "Timeout after "+timeout+" ms"); + } else if (ready()) { + callback(); } else { - if(!condition) { - var message = timeoutMessageCallback ? timeoutMessageCallback() : "Timeout after "+timeout+" ms"; - console.log("Waiting for " + ready); - error(message); - } else { - clearInterval(interval); - callback(); - } + setTimeout(waitLoop, 250); } - }, 250); + }()); } function error(message) { @@ -118,13 +113,12 @@ function PhantomTest() { console.log('loaded', url, status); // process ready waitFor(function() { - return self.page.evaluate(function (ready) { + return self.page.evaluate(function (ready) { + console.log("waiting for", ready); var r = false; try { r = !!eval(ready); - } catch(ex) { - console.log("waiting for " + ready); - } + } catch(ex) { } return r; }, ready); // run test From aaa80e957548418c94e7a8841cd844c5135af62e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Mar 2014 12:53:34 +0100 Subject: [PATCH 7/9] [IMP] phantomjs driver cleanups bzr revid: xmo@openerp.com-20140310115334-vjh7gx5oizdm6s67 --- openerp/tests/phantomtest.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openerp/tests/phantomtest.js b/openerp/tests/phantomtest.js index bfd6fa4d0b2..8099de54bab 100644 --- a/openerp/tests/phantomtest.js +++ b/openerp/tests/phantomtest.js @@ -96,14 +96,17 @@ function PhantomTest() { // ---------------------------------------------------- // run test // ---------------------------------------------------- - this.run = function(url_path, code, ready) { + this.run = function() { + var url_path = this.options.url_path, + code = this.options.code, + ready = this.options.ready; if(self.options.login) { - qp = []; + var qp = []; qp.push('db=' + self.options.db); qp.push('login=' + self.options.login); qp.push('key=' + self.options.password); qp.push('redirect=' + encodeURIComponent(url_path)); - var url_path = "/login?" + qp.join('&'); + url_path = "/login?" + qp.join('&'); } var url = self.origin + url_path; self.page.open(url, function(status) { @@ -132,8 +135,7 @@ function PhantomTest() { // js mode or jsfile mode if(phantom.args.length === 1) { - pt = new PhantomTest(); - pt.run(pt.options.url_path, pt.options.code, pt.options.ready); + new PhantomTest().run(); } // vim:et: From 35d87dd19bc47751a3825f595952f9180f6f3cbe Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 10 Mar 2014 14:03:49 +0100 Subject: [PATCH 8/9] [IMP] ir.http: provide current rule to argument postprocessing bzr revid: fme@openerp.com-20140310130349-x4qxpcmyrcejywlz --- openerp/addons/base/ir/ir_http.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/ir/ir_http.py b/openerp/addons/base/ir/ir_http.py index 8cc24c88cce..ae04dcf5853 100644 --- a/openerp/addons/base/ir/ir_http.py +++ b/openerp/addons/base/ir/ir_http.py @@ -53,8 +53,8 @@ class ir_http(osv.AbstractModel): def _get_converters(self): return {'model': ModelConverter, 'models': ModelsConverter} - def _find_handler(self): - return self.routing_map().bind_to_environ(request.httprequest.environ).match() + def _find_handler(self, return_rule=False): + return self.routing_map().bind_to_environ(request.httprequest.environ).match(return_rule=return_rule) def _auth_method_user(self): request.uid = request.session.uid @@ -89,7 +89,8 @@ class ir_http(osv.AbstractModel): def _dispatch(self): # locate the controller method try: - func, arguments = self._find_handler() + rule, arguments = self._find_handler(return_rule=True) + func = rule.endpoint except werkzeug.exceptions.NotFound, e: return self._handle_exception(e) @@ -102,7 +103,7 @@ class ir_http(osv.AbstractModel): convert_exception_to( werkzeug.exceptions.Forbidden)) - processing = self._postprocess_args(arguments) + processing = self._postprocess_args(arguments, rule) if processing: return processing @@ -118,7 +119,7 @@ class ir_http(osv.AbstractModel): return result - def _postprocess_args(self, arguments): + def _postprocess_args(self, arguments, rule): """ post process arg to set uid on browse records """ for arg in arguments.itervalues(): if isinstance(arg, orm.browse_record) and arg._uid is UID_PLACEHOLDER: From 5e036bbf7c1e79dc1fe91b9be04c329aad7db995 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 10 Mar 2014 14:05:30 +0100 Subject: [PATCH 9/9] [FIX] Properly redirect in case of invalid url slugs Use werkzeug's api instead of doing hackish url replacement bzr revid: fme@openerp.com-20140310130530-e86cdwhdca9cs9g3 --- addons/website/models/ir_http.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 46b9efc15a8..f73138313ab 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -78,21 +78,18 @@ class ir_http(orm.AbstractModel): return self._dispatch() - def _postprocess_args(self, arguments): - url = request.httprequest.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 != request.httprequest.url: - werkzeug.exceptions.abort(werkzeug.utils.redirect(url)) + def _postprocess_args(self, 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 path != request.httprequest.path: + return werkzeug.utils.redirect(path) def _handle_exception(self, exception=None, code=500): if isinstance(exception, werkzeug.exceptions.HTTPException) and hasattr(exception, 'response') and exception.response: