diff --git a/addons/web/common/http.py b/addons/web/common/http.py
index 620e3a548dc..4bdd87a6764 100644
--- a/addons/web/common/http.py
+++ b/addons/web/common/http.py
@@ -6,12 +6,12 @@ import ast
import contextlib
import functools
import logging
-import urllib
import os
import pprint
import sys
import threading
import traceback
+import urllib
import uuid
import xmlrpclib
@@ -137,20 +137,19 @@ class JsonRequest(WebRequest):
:returns: an utf8 encoded JSON-RPC2 or JSONP reply
"""
- method = self.httprequest.method
args = self.httprequest.args
jsonp = args.get('jsonp', False)
requestf = None
request = None
- if jsonp and method == 'POST':
+ if jsonp and self.httprequest.method == 'POST':
# jsonp 2 steps step1 POST: save call
self.init(args)
req.session.jsonp_requests[args.get('id')] = self.httprequest.form['r']
headers=[('Content-Type', 'text/plain; charset=utf-8')]
r = werkzeug.wrappers.Response(request_id, headers=headers)
return r
- elif args['jsonp'] and args.get('id'):
+ elif jsonp and args.get('id'):
# jsonp 2 steps step2 GET: run and return result
self.init(args)
request = self.session.jsonp_requests.pop(args.get(id), "")
@@ -195,6 +194,8 @@ class JsonRequest(WebRequest):
}
}
except Exception:
+ logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\
+ ("An error occured while handling a json request")
error = {
'code': 300,
'message': "OpenERP WebClient Error",
@@ -205,9 +206,9 @@ class JsonRequest(WebRequest):
}
if error:
response["error"] = error
- _logger.error("[%s] <--\n%s", rid, pprint.pformat(response))
- elif _logger.isEnabledFor(logging.DEBUG):
- _logger.debug("[%s] <--\n%s", rid, pprint.pformat(response))
+
+ if _logger.isEnabledFor(logging.DEBUG):
+ _logger.debug("<--\n%s", pprint.pformat(response))
if jsonp:
mime = 'application/javascript'
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index e745020c594..9c6edcf378a 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -10,6 +10,7 @@ import os
import re
import simplejson
import time
+import urllib2
import xmlrpclib
import zlib
from xml.etree import ElementTree
@@ -245,7 +246,7 @@ class WebClient(openerpweb.Controller):
class Proxy(openerpweb.Controller):
_cp_path = '/web/proxy'
- @jsonrequest
+ @openerpweb.jsonrequest
def load(self, req, path):
#req.config.socket_port
#if not re.match('^/[^/]+/static/.*', path):
@@ -254,7 +255,7 @@ class Proxy(openerpweb.Controller):
env = req.httprequest.environ
port = env['SERVER_PORT']
- o = urllib.urlopen('http://127.0.0.1:%s%s' % (port, path))
+ o = urllib2.urlopen('http://127.0.0.1:%s%s' % (port, path))
return o.read()
class Database(openerpweb.Controller):
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 70beb7ecc34..cbf475af44e 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -1004,20 +1004,12 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this.header.on_logout.add(this.login.on_logout);
this.header.on_action.add(this.on_menu_action);
- this.session.on_session_invalid.add(this.login.do_ask_login);
- this.session.on_session_valid.add_last(this.header.do_update);
- this.session.on_session_invalid.add_last(this.header.do_update);
- this.session.on_session_valid.add_last(this.on_logged);
- this.session.on_session_invalid.add_last(this.on_logged_out);
-
-
this._current_state = null;
-
},
start: function() {
this._super.apply(this, arguments);
var self = this;
- openerp.connection.bind("",function() {
+ this.session.bind().then(function() {
var params = {};
if (jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.$element.addClass("kitten-mode-activated");
@@ -1026,17 +1018,25 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
});
}
self.$element.html(QWeb.render("Interface", params));
- openerp.connection.session_restore();
-
self.menu = new openerp.web.Menu(self, "oe_menu", "oe_secondary_menu");
self.menu.on_action.add(self.on_menu_action);
-
self.notification.prependTo(self.$element);
self.loading.appendTo($('#oe_loading'));
self.header.appendTo($("#oe_header"));
self.login.appendTo($('#oe_login'));
self.menu.start();
+ self.login.on_login_invalid();
+ });
+ this.session.ready.then(function() {
+ self.login.on_login_valid();
+ self.header.do_update();
+ self.menu.do_reload();
+ if(self.action_manager)
+ self.action_manager.stop();
+ self.action_manager = new openerp.web.ActionManager(this);
+ self.action_manager.appendTo($("#oe_app"));
+ self.bind_hashchange();
});
},
do_reload: function() {
@@ -1050,24 +1050,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
var n = this.notification;
n.warn.apply(n, arguments);
},
- on_logged: function() {
- this.menu.do_reload();
- if(this.action_manager)
- this.action_manager.stop();
- this.action_manager = new openerp.web.ActionManager(this);
- this.action_manager.appendTo($("#oe_app"));
-
- if (openerp._modules_loaded) { // TODO: find better option than this
- this.bind_hashchange();
- } else {
- this.session.on_modules_loaded.add({ // XXX what about a $.Deferred ?
- callback: $.proxy(this, 'bind_hashchange'),
- unique: true,
- position: 'last'
- })
- }
- },
- on_logged_out: function() {
+ on_loggued_out: function() {
+ this.header.do_update();
$(window).unbind('hashchange', this.on_hashchange);
this.do_push_state({});
if(this.action_manager)
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index 55bce373330..f28d0adfc03 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -352,11 +352,11 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
*/
init: function() {
this._super();
- // TODO: session should have an optional name indicating that they'll
- // be saved to (and revived from) cookies
+ // TODO: session store in cookie should be optional
this.name = openerp._session_id;
},
bind: function(host, protocol) {
+ var self = this;
this.host = (host == undefined) ? location.host : host;
this.protocol = (protocol == undefined) ? location.protocol : protocol;
this.prefix = this.protocol + '//' + this.host;
@@ -368,13 +368,13 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
this.username = false;
this.user_context= {};
this.db = false;
- this.module_loading = $.Deferred();
this.module_list = [];
this.module_loaded = {"web": true};
this.context = {};
this.shortcuts = [];
this.active_id = null;
- this.do_load_qweb(['/web/webclient/qweb'], continuation);
+ this.ready = $.Deferred();
+ return this.session_restore();
},
/**
* Executes an RPC call, registering the provided callbacks.
@@ -522,74 +522,52 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
},
on_rpc_error: function(error) {
},
+ /**
+ * Init a session, reloads from cookie, if it exists
+ */
+ session_restore: function () {
+ var self = this;
+ // TODO: session store in cookie should be optional
+ this.session_id = this.get_cookie('session_id');
+ return this.rpc("/web/session/get_session_info", {}).pipe(function(result) {
+ // If immediately follows a login (triggered by trying to restore
+ // an invalid session or no session at all), refresh session data
+ // (should not change, but just in case...)
+ _.extend(self, {
+ db: result.db,
+ username: result.login,
+ uid: result.uid,
+ user_context: result.context
+ });
+ var deferred = self.do_load_qweb(['/web/webclient/qweb']);
+ if(self.uid) {
+ return deferred.then(self.load_modules());
+ }
+ return deferred;
+ });
+ },
/**
* The session is validated either by login or by restoration of a previous session
*/
- on_session_valid: function(continuation) {
- this.load_modules().then(function() { continuation() } );
- },
- on_session_invalid: function(continuation) {
- },
- session_is_valid: function() {
- return this.uid;
- },
- session_authenticate: function(db, login, password, success_callback) {
+ session_authenticate: function(db, login, password) {
var self = this;
var base_location = document.location.protocol + '//' + document.location.host;
var params = { db: db, login: login, password: password, base_location: base_location };
- return this.rpc("/web/session/authenticate", params, function(result) {
+ return this.rpc("/web/session/authenticate", params).pipe(function(result) {
_.extend(self, {
session_id: result.session_id,
- uid: result.uid,
- user_context: result.context,
db: result.db,
- username: result.login
+ username: result.login,
+ uid: result.uid,
+ user_context: result.context
});
- self.session_save();
- self.on_session_valid(success_callback);
- return true;
+ // TODO: session store in cookie should be optional
+ self.set_cookie('session_id', this.session_id);
+ return self.load_modules();
});
},
- /**
- * Reloads uid and session_id from local storage, if they exist
- */
- session_restore: function (continuation) {
- var self = this;
- this.session_id = this.get_cookie('session_id');
- return this.rpc("/web/session/get_session_info", {}).then(function(result) {
- // If immediately follows a login (triggered by trying to restore
- // an invalid session or no session at all), refresh session data
- // (should not change, but just in case...) but should not call
- // on_session_valid again as it triggers reloading the menu
- var already_logged = self.uid;
- _.extend(self, {
- uid: result.uid,
- user_context: result.context,
- db: result.db,
- username: result.login
- });
- if (!already_logged) {
- if (self.uid) {
- self.on_session_valid(continuation);
- } else {
- self.on_session_invalid(continuation);
- }
- }
- }, function() {
- self.on_session_invalid(continuation);
- });
- },
- /**
- * Saves the session id and uid locally
- */
- session_save: function () {
- this.set_cookie('session_id', this.session_id);
- },
- logout: function() {
+ session_logout: function() {
this.set_cookie('session_id', '');
- this.reload_client();
- },
- reload_client: function() {
window.location.reload();
},
/**
@@ -640,19 +618,21 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
self.module_list = result;
var lang = self.user_context.lang;
var params = { mods: ["web"].concat(result), lang: lang};
- self.rpc('/web/webclient/translations',params).then(function(transs) {
+ self.rpc('/web/webclient/translations',params).pipe(function(transs) {
openerp.web._t.database.set_bundle(transs);
var modules = self.module_list.join(',');
var file_list = ["/web/static/lib/datejs/globalization/" +
self.user_context.lang.replace("_", "-") + ".js"
];
return $.when(
- self.rpc('/web/webclient/qweblist', {mods: modules}, self.do_load_qweb),
self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css),
- self.rpc('/web/webclient/jslist', {mods: modules}, function(files) {
+ self.rpc('/web/webclient/qweblist', {mods: modules}).pipe(self.do_load_qweb),
+ self.rpc('/web/webclient/jslist', {mods: modules}).pipe(function(files) {
self.do_load_js(file_list.concat(files));
})
- );
+ ).then(function() {
+ self.ready.resolve();
+ });
});
});
},
@@ -660,7 +640,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
var self = this;
_.each(files, function (file) {
$('head').append($('', {
- 'href': self.get_absolute_url(file),
+ 'href': self.get_url(file),
'rel': 'stylesheet',
'type': 'text/css'
}));
@@ -668,32 +648,39 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
},
do_load_js: function(files) {
var self = this;
+ var d = $.Deferred();
if(files.length != 0) {
var file = files.shift();
var tag = document.createElement('script');
tag.type = 'text/javascript';
- tag.src = self.get_absolute_url(file);
+ tag.src = self.get_url(file);
tag.onload = tag.onreadystatechange = function() {
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
return;
tag.onload_done = true;
- self.do_load_js(files, callback);
+ self.do_load_js(files).then(function () {
+ d.resolve();
+ });
};
var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(tag);
} else {
self.on_modules_loaded();
+ d.resolve();
}
+ return d;
},
do_load_qweb: function(files) {
var self = this;
if (files.length != 0) {
var file = files.shift();
- self.rpc('/web/proxy/load', {path: file}, function(xml) {
+ return self.rpc('/web/proxy/load', {path: file}).pipe(function(xml) {
openerp.web.qweb.add_template(_.str.trim(xml));
- self.do_load_qweb(files, callback);
+ return self.do_load_qweb(files);
});
- }
+ } else {
+ return $.when();
+ }
},
on_modules_loaded: function() {
for(var j=0; j