summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
authorniv-openerp <nicolas.vanhoren@openerp.com>2013-06-10 17:45:14 +0200
committerniv-openerp <nicolas.vanhoren@openerp.com>2013-06-10 17:45:14 +0200
commita94bbf8e5e3aafb236a059f82b855d16dc033d9e (patch)
tree0b3f2cfa795a23150a10d561996052a023fd48f5 /addons/web
parent901ba0cba5ea8413ea5cb64974ce8fc973093105 (diff)
parent02aa3f211471a55fd956027a84b6baca1272ffa1 (diff)
[FIX] Merge fix in saas1 for the problem that made the server crash when install a db
bzr revid: nicolas.vanhoren@openerp.com-20130610144915-0nj8vpk7n84ocj3f bzr revid: nicolas.vanhoren@openerp.com-20130610150657-3xddn91gm0iq0ubp bzr revid: nicolas.vanhoren@openerp.com-20130610154514-oee6s4f9g17bx63z
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/__openerp__.py4
-rw-r--r--addons/web/controllers/main.py32
-rw-r--r--addons/web/http.py21
-rw-r--r--addons/web/static/src/js/chrome.js43
-rw-r--r--addons/web/static/src/js/corelib.js3
-rw-r--r--addons/web/static/src/js/view_form.js19
-rw-r--r--addons/web/static/src/js/views.js9
7 files changed, 104 insertions, 27 deletions
diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py
index 269aa13d58e..48903312b44 100644
--- a/addons/web/__openerp__.py
+++ b/addons/web/__openerp__.py
@@ -1,7 +1,7 @@
{
'name': 'Web',
'category': 'Hidden',
- 'version': '7.0.1.0',
+ 'version': '1.0',
'description':
"""
OpenERP Web core module.
@@ -13,6 +13,7 @@ This module provides the core of the OpenERP Web Client.
'auto_install': True,
'post_load': 'wsgi_postload',
'js' : [
+ "static/src/fixbind.js",
"static/lib/datejs/globalization/en-US.js",
"static/lib/datejs/core.js",
"static/lib/datejs/parser.js",
@@ -76,6 +77,7 @@ This module provides the core of the OpenERP Web Client.
"static/test/class.js",
"static/test/registry.js",
"static/test/form.js",
+ "static/test/data.js",
"static/test/list-utils.js",
"static/test/formats.js",
"static/test/rpc.js",
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index b7071eff9e2..8683ef177bc 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -310,7 +310,7 @@ def fs2web(path):
"""convert FS path into web path"""
return '/'.join(path.split(os.path.sep))
-def manifest_glob(extension, addons=None, db=None):
+def manifest_glob(extension, addons=None, db=None, include_remotes=False):
if addons is None:
addons = module_boot(db=db)
else:
@@ -324,8 +324,12 @@ def manifest_glob(extension, addons=None, db=None):
addons_path = os.path.join(manifest['addons_path'], '')[:-1]
globlist = manifest.get(extension, [])
for pattern in globlist:
- for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))):
- r.append((path, fs2web(path[len(addons_path):])))
+ if pattern.startswith(('http://', 'https://', '//')):
+ if include_remotes:
+ r.append((None, pattern))
+ else:
+ for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))):
+ r.append((path, fs2web(path[len(addons_path):])))
return r
def manifest_list(extension, mods=None, db=None):
@@ -333,14 +337,16 @@ def manifest_list(extension, mods=None, db=None):
mods: a comma separated string listing modules
db: a database name (return all installed modules in that database)
"""
+ files = manifest_glob(extension, addons=mods, db=db, include_remotes=True)
if not req.debug:
path = '/web/webclient/' + extension
if mods is not None:
path += '?' + urllib.urlencode({'mods': mods})
elif db:
path += '?' + urllib.urlencode({'db': db})
- return [path]
- files = manifest_glob(extension, addons=mods, db=db)
+
+ remotes = [wp for fp, wp in files if fp is None]
+ return [path] + remotes
return [wp for _fp, wp in files]
def get_last_modified(files):
@@ -1204,19 +1210,19 @@ class Binary(openerpweb.Controller):
headers = [('Content-Type', 'image/png')]
etag = req.httprequest.headers.get('If-None-Match')
hashed_session = hashlib.md5(req.session_id).hexdigest()
+ retag = hashed_session
id = None if not id else simplejson.loads(id)
if type(id) is list:
id = id[0] # m2o
- if etag:
- if not id and hashed_session == etag:
- return werkzeug.wrappers.Response(status=304)
- else:
- date = Model.read([id], [last_update], req.context)[0].get(last_update)
- if hashlib.md5(date).hexdigest() == etag:
+ try:
+ if etag:
+ if not id and hashed_session == etag:
return werkzeug.wrappers.Response(status=304)
+ else:
+ date = Model.read([id], [last_update], req.context)[0].get(last_update)
+ if hashlib.md5(date).hexdigest() == etag:
+ return werkzeug.wrappers.Response(status=304)
- retag = hashed_session
- try:
if not id:
res = Model.default_get([field], req.context).get(field)
image_base64 = res
diff --git a/addons/web/http.py b/addons/web/http.py
index 67d71ac7d37..2dc41c8cad9 100644
--- a/addons/web/http.py
+++ b/addons/web/http.py
@@ -121,6 +121,13 @@ class WebRequest(object):
# we use _ as seprator where RFC2616 uses '-'
self.lang = lang.replace('-', '_')
+ @contextlib.contextmanager
+ def registry_cr(self):
+ dbname = self.session._db or openerp.addons.web.controllers.main.db_monodb(self)
+ registry = openerp.modules.registry.RegistryManager.get(dbname.lower())
+ with registry.cursor() as cr:
+ yield (registry, cr)
+
def reject_nonliteral(dct):
if '__ref' in dct:
raise ValueError(
@@ -298,6 +305,8 @@ class HttpRequest(WebRequest):
#_logger.debug("%s --> %s.%s %r", self.httprequest.method, method.im_class.__name__, method.__name__, akw)
try:
r = method(**self.params)
+ except werkzeug.exceptions.HTTPException, e:
+ r = e
except Exception, e:
_logger.exception("An exception occured during an http request")
se = serialize_exception(e)
@@ -307,11 +316,13 @@ class HttpRequest(WebRequest):
'data': se
}
r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps(error)))
- if self.debug or 1:
- if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
- _logger.debug('<-- %s', r)
- else:
- _logger.debug("<-- size: %s", len(r))
+ else:
+ if not r:
+ r = werkzeug.wrappers.Response(status=204) # no content
+ if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
+ _logger.debug('<-- %s', r)
+ else:
+ _logger.debug("<-- size: %s", len(r))
return r
def make_response(self, data, headers=None, cookies=None):
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index f357f6ac2e6..884dc41a9f9 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -913,9 +913,7 @@ instance.web.Menu = instance.web.Widget.extend({
self.reflow();
// launch the fetch of needaction counters, asynchronous
if (!_.isEmpty(menu_data.all_menu_ids)) {
- this.rpc("/web/menu/load_needaction", {menu_ids: menu_data.all_menu_ids}).done(function(r) {
- self.on_needaction_loaded(r);
- });
+ this.do_load_needaction(menu_data.all_menu_ids);
}
});
var lazyreflow = _.debounce(this.reflow.bind(this), 200);
@@ -941,7 +939,7 @@ instance.web.Menu = instance.web.Widget.extend({
this.data = {data: data};
this.renderElement();
this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this }));
- this.$el.on('click', 'a[data-menu]', this.on_menu_click);
+ this.$el.on('click', 'a[data-menu]', this.on_top_menu_click);
// Hide second level submenus
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide();
if (self.current_menu) {
@@ -950,6 +948,16 @@ instance.web.Menu = instance.web.Widget.extend({
this.trigger('menu_loaded', data);
this.has_been_loaded.resolve();
},
+ do_load_needaction: function (menu_ids) {
+ var self = this;
+ menu_ids = _.reject(menu_ids, _.isEmpty);
+ if (_.isEmpty(menu_ids)) {
+ return $.when();
+ }
+ return this.rpc("/web/menu/load_needaction", {'menu_ids': menu_ids}).done(function(r) {
+ self.on_needaction_loaded(r);
+ });
+ },
on_needaction_loaded: function(data) {
var self = this;
this.needaction_data = data;
@@ -1081,11 +1089,38 @@ instance.web.Menu = instance.web.Widget.extend({
}
this.open_menu(id);
},
+ do_reload_needaction: function () {
+ var self = this;
+ if (self.current_menu) {
+ self.do_load_needaction([self.current_menu]).then(function () {
+ self.trigger("need_action_reloaded");
+ });
+ }
+ },
/**
* Jquery event handler for menu click
*
* @param {Event} ev the jquery event
*/
+ on_top_menu_click: function(ev) {
+ var self = this;
+ var id = $(ev.currentTarget).data('menu');
+ var menu_ids = [id];
+ var menu = _.filter(this.data.data.children, function (menu) {return menu.id == id;})[0];
+ function add_menu_ids (menu) {
+ if (menu.children) {
+ _.each(menu.children, function (menu) {
+ menu_ids.push(menu.id);
+ add_menu_ids(menu);
+ });
+ }
+ };
+ add_menu_ids(menu);
+ self.do_load_needaction(menu_ids).then(function () {
+ self.trigger("need_action_reloaded");
+ });
+ this.on_menu_click(ev);
+ },
on_menu_click: function(ev) {
ev.preventDefault();
var needaction = $(ev.target).is('div.oe_menu_counter');
diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js
index c4bb81117f8..116ddf2e8c2 100644
--- a/addons/web/static/src/js/corelib.js
+++ b/addons/web/static/src/js/corelib.js
@@ -1144,7 +1144,8 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, {
}
qs = '?' + $.param(params);
}
- return this.prefix + path + qs;
+ var prefix = _.any(['http://', 'https://', '//'], _.bind(_.str.startsWith, null, path)) ? '' : this.prefix;
+ return prefix + path + qs;
},
});
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 6a1dc019f95..32e86d69bed 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -91,6 +91,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
init: function(parent, dataset, view_id, options) {
var self = this;
this._super(parent);
+ this.ViewManager = parent;
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
@@ -720,6 +721,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return this.save().done(function(result) {
self.trigger("save", result);
self.to_view_mode();
+ }).then(function(result) {
+ self.ViewManager.ActionManager.__parentedParent.menu.do_reload_needaction();
});
},
on_button_cancel: function(event) {
@@ -2901,7 +2904,7 @@ instance.web.form.FieldRadio = instance.web.form.AbstractField.extend(instance.w
var domain = instance.web.pyeval.eval('domain', this.build_domain()) || [];
if (! _.isEqual(self.domain, domain)) {
self.domain = domain;
- var ds = new instance.web.DataSet(self, self.field.relation);
+ var ds = new instance.web.DataSetStatic(self, self.field.relation, self.build_context());
ds.call('search', [self.domain])
.then(function (records) {
ds.name_get(records).then(function (records) {
@@ -3151,6 +3154,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
instance.web.form.CompletionFieldMixin.init.call(this);
this.set({'value': false});
this.display_value = {};
+ this.display_value_backup = {};
this.last_search = [];
this.floating = false;
this.current_display = null;
@@ -3234,6 +3238,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
);
pop.on('write_completed', self, function(){
self.display_value = {};
+ self.display_value_backup = {};
self.render_value();
self.focus();
});
@@ -3284,6 +3289,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
if (self.last_search.length > 0) {
if (self.last_search[0][0] != self.get("value")) {
self.display_value = {};
+ self.display_value_backup = {};
self.display_value["" + self.last_search[0][0]] = self.last_search[0][1];
self.reinit_value(self.last_search[0][0]);
} else {
@@ -3349,6 +3355,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
var item = ui.item;
if (item.id) {
self.display_value = {};
+ self.display_value_backup = {};
self.display_value["" + item.id] = item.name;
self.reinit_value(item.id);
} else if (item.action) {
@@ -3394,6 +3401,11 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
this.alive(dataset.name_get([self.get("value")])).done(function(data) {
self.display_value["" + self.get("value")] = data[0][1];
self.render_value(true);
+ }).fail( function (data, event) {
+ // avoid displaying crash errors as many2One should be name_get compliant
+ event.preventDefault();
+ self.display_value["" + self.get("value")] = self.display_value_backup["" + self.get("value")];
+ self.render_value(true);
});
}
},
@@ -3437,9 +3449,13 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
var self = this;
if (value_ instanceof Array) {
this.display_value = {};
+ this.display_value_backup = {}
if (! this.options.always_reload) {
this.display_value["" + value_[0]] = value_[1];
}
+ else {
+ this.display_value_backup["" + value_[0]] = value_[1];
+ }
value_ = value_[0];
}
value_ = value_ || false;
@@ -3450,6 +3466,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
},
add_id: function(id) {
this.display_value = {};
+ this.display_value_backup = {};
this.reinit_value(id);
},
is_false: function() {
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 0737281e199..fdb2eeee329 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -522,6 +522,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
return x;
}
});
+ this.ActionManager = parent;
this.views = {};
this.flags = flags || {};
this.registry = instance.web.views;
@@ -1253,6 +1254,7 @@ instance.web.View = instance.web.Widget.extend({
view_type: undefined,
init: function(parent, dataset, view_id, options) {
this._super(parent);
+ this.ViewManager = parent;
this.dataset = dataset;
this.view_id = view_id;
this.set_default_options(options);
@@ -1324,7 +1326,6 @@ instance.web.View = instance.web.Widget.extend({
}
};
var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {});
-
var handler = function (action) {
if (action && action.constructor == Object) {
var ncontext = new instance.web.CompoundContext(context);
@@ -1361,7 +1362,11 @@ instance.web.View = instance.web.Widget.extend({
}
}
args.push(context);
- return dataset.call_button(action_data.name, args).then(handler);
+ return dataset.call_button(action_data.name, args).then(handler).then(function () {
+ if (self.ViewManager.ActionManager) {
+ self.ViewManager.ActionManager.__parentedParent.menu.do_reload_needaction();
+ }
+ });
} else if (action_data.type=="action") {
return this.rpc('/web/action/load', {
action_id: action_data.name,