From cbb5488f978ae592914fa56a2378cd54aa1bd00c Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 8 Apr 2014 09:52:05 +0200 Subject: [PATCH] [ADD] t-call-assets bzr revid: fme@openerp.com-20140408075205-9v8fxg786jj0fj77 --- openerp/addons/base/ir/ir_qweb.py | 40 +++++++++++++++++++++++++++ openerp/http.py | 46 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index 3c195c93c6c..391dbf610e9 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -8,12 +8,14 @@ import math import re import sys import xml # FIXME use lxml and etree +import lxml import babel import babel.dates import werkzeug.utils from PIL import Image +import openerp.http import openerp.tools from openerp.tools.safe_eval import safe_eval as eval from openerp.osv import osv, orm, fields @@ -385,6 +387,44 @@ class QWeb(orm.AbstractModel): return self.render(cr, uid, self.eval_format(template_attributes["call"], d), d) + def render_tag_call_assets(self, element, template_attributes, generated_attributes, qwebcontext): + template_attributes['call'] = template_attributes['call-assets'] + content = self.render_tag_call(element, template_attributes, generated_attributes, qwebcontext) + html = lxml.html.fragment_fromstring('%s' % content) # avoid this hack if possible + + tags = dict() + current_style = None + current_script = None + + for el in html: + if el.tag == 'link' and el.attrib.get('rel') == 'stylesheet': + cssfile = el.attrib.get('href') + if current_style is None: + current_style = el + tags[current_style] = [] + el.attrib['href'] = '/web/css/' + else: + html.remove(el) + tags[current_style].append(cssfile) + if el.tag == 'script': + if 'src' not in el.attrib: + current_script = None + else: + jsfile = el.attrib['src'] + if current_script is None: + current_script = el + tags[current_script] = [] + el.attrib['src'] = '/web/js/' + else: + html.remove(el) + tags[current_script].append(jsfile) + + for tag, files in tags.items(): + attr = 'href' if 'href' in tag.attrib else 'src' + tag.attrib[attr] += openerp.http.pathlist_to_base64(files) + r = lxml.html.tostring(html)[3:-4] # avoid this hack if possible + return r + def render_tag_set(self, element, template_attributes, generated_attributes, qwebcontext): if "value" in template_attributes: qwebcontext[template_attributes["set"]] = self.eval_object(template_attributes["value"], qwebcontext) diff --git a/openerp/http.py b/openerp/http.py index 2e21d27528a..ccff43ed271 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -3,6 +3,7 @@ # OpenERP HTTP layer #---------------------------------------------------------- import ast +import base64 import collections import contextlib import errno @@ -137,6 +138,51 @@ def redirect_with_hash(url, code=303): return werkzeug.utils.redirect(url, code) return "" % url +def pathlist_to_base64(files): + """ Serialize a path list to an url-safe string trying to avoid path + duplication while keeping files order. + """ + seen = [] + concat = [] + current_path = None + for f in files: + if f in seen: + continue + seen.append(f) + path, fname = os.path.split(f) + if not path: + path = '/' + if path != current_path: + current_path = path + concat.append(path) + concat.append(fname) + r = '|'.join(concat) + return base64.urlsafe_b64encode(r.encode('zlib')) + +def base64_to_pathlist(s, fspath=False): + """ Deserialize a string generated by filelist_to_base64 + + :param fspath: returns tuple(filesystem path, url path) if True + """ + files = [] + decoded = base64.urlsafe_b64decode(str(s)).decode('zlib') + items = decoded.split('|') + current_path = '/' + while items: + item = items.pop(0) + if item.startswith('/'): + current_path = item + else: + path = current_path + '/' + item + if fspath: + module = filter(bool, path.split('/'))[0] + mpath = addons_manifest[module]['addons_path'] + fs_path = mpath + path.replace('/', os.path.sep) + files.append((fs_path, path)) + else: + files.append(path) + return files + class WebRequest(object): """ Parent class for all OpenERP Web request types, mostly deals with initialization and setup of the request object (the dispatching itself has