From fc513a2a1fdd0dd28b296ee55209e325d7c466a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 11:34:20 +0200 Subject: [PATCH 01/11] [IMP] website: publish management 'Edit' using a wrench is removed, replaced by an entry in the options menu. The button text size is also increased, because currently in xsmall it is not matching the website look. Also re-indented the template. bzr revid: tde@openerp.com-20131024093420-3vye9g2j11b3y602 --- addons/website/views/website_templates.xml | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index e1b79446451..430ed49e08b 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -226,23 +226,24 @@ From b702a9887ce12d46f7e5f86ce46103c478d76588 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Oct 2013 12:34:01 +0200 Subject: [PATCH 02/11] [IMP] remove /website/attachment, make attachments go through /website/image bzr revid: xmo@openerp.com-20131024103401-yik03je9qm1ge0tp --- addons/website/controllers/main.py | 44 ++++++++++++++---------------- addons/website/models/ir_qweb.py | 8 ++++-- addons/website/models/website.py | 11 ++++++-- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 083f9f3aef7..30f384a606b 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -218,8 +218,7 @@ class Website(openerp.addons.web.controllers.main.Home): irt._get_source.clear_cache(irt) # FIXME: find why ir.translation does not invalidate return True - # # FIXME: auth, anybody can upload an attachment if URL known/found - @website.route('/website/attach', type='http', auth='admin') + @website.route('/website/attach', type='http', auth='user') def attach(self, func, upload): req = request.httprequest if req.method != 'POST': @@ -229,12 +228,18 @@ class Website(openerp.addons.web.controllers.main.Home): try: attachment_id = request.registry['ir.attachment'].create(request.cr, request.uid, { 'name': upload.filename, - 'datas': base64.encodestring(upload.read()), + 'datas': upload.read().encode('base64'), 'datas_fname': upload.filename, 'res_model': 'ir.ui.view', }, request.context) - # FIXME: auth=user... no good. - url = '/website/attachment/%d' % attachment_id + + url = website.urlplus('/website/image', { + 'model': 'ir.attachment', + 'id': attachment_id, + 'field': 'datas', + 'max_height': MAX_IMAGE_HEIGHT, + 'max_width': MAX_IMAGE_WIDTH, + }) except Exception, e: logger.exception("Failed to upload image to attachment") message = str(e) @@ -283,7 +288,7 @@ class Images(http.Controller): return response.make_conditional(request.httprequest) @website.route('/website/image', auth="public") - def image(self, model, id, field): + def image(self, model, id, field, max_width=maxint, max_height=maxint): Model = request.registry[model] response = werkzeug.wrappers.Response() @@ -291,7 +296,7 @@ class Images(http.Controller): id = int(id) ids = Model.search(request.cr, request.uid, - [('id', '=', id)], context=request.context)\ + [('id', '=', id)], context=request.context) \ or Model.search(request.cr, openerp.SUPERUSER_ID, [('id', '=', id), ('website_published', '=', True)], context=request.context) @@ -312,8 +317,8 @@ class Images(http.Controller): response.last_modified = datetime.datetime.strptime( record[concurrency], server_format) + # Field does not exist on model or field set to False if not record.get(field): - # Field does not exist on model or field set to False # FIXME: maybe a field which does not exist should be a 404? return self.placeholder(response) @@ -324,19 +329,9 @@ class Images(http.Controller): if response.status_code == 304: return response - return self.set_image_data(response, record[field].decode('base64')) - - # FIXME: auth - # FIXME: delegate to image? - @website.route('/website/attachment/', auth='admin') - def attachment(self, id): - attachment = request.registry['ir.attachment'].browse( - request.cr, request.uid, id, request.context) - return self.set_image_data( - werkzeug.wrappers.Response(), - attachment.datas.decode('base64'), - fit=IMAGE_LIMITS,) + response, record[field].decode('base64'), + fit=(int(max_width), int(max_height))) def set_image_data(self, response, data, fit=(maxint, maxint)): """ Sets an inferred mime type on the response object, and puts the @@ -356,10 +351,13 @@ class Images(http.Controller): if w < max_w and h < max_h: response.set_data(data) - return response + else: + image.thumbnail(fit, Image.ANTIALIAS) + image.save(response.stream, image.format) + # invalidate content-length computed by make_conditional as writing + # to response.stream does not do it (as of werkzeug 0.9.3) + del response.headers['Content-Length'] - image.thumbnail(fit, Image.ANTIALIAS) - image.save(response.stream, image.format) return response diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py index d6bd6a524c3..d7bd704b895 100644 --- a/addons/website/models/ir_qweb.py +++ b/addons/website/models/ir_qweb.py @@ -12,6 +12,7 @@ import itertools import logging import re import urllib2 +import urlparse import werkzeug.utils from dateutil import parser @@ -199,10 +200,11 @@ class Image(orm.AbstractModel): def from_html(self, cr, uid, model, column, element, context=None): url = element.find('img').get('src') - m = re.match(r'^/website/attachment/(\d+)$', url) - if m: + url_object = urlparse.urlsplit(url) + query = urlparse.parse_qs(url_object.query) + if url_object.path == '/website/image' and query['model'] == 'ir.attachment': attachment = self.pool['ir.attachment'].browse( - cr, uid, int(m.group(1)), context=context) + cr, uid, int(query['id']), context=context) return attachment.datas # remote URL? diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 6d8d5f520a2..d7f47c01b25 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -364,13 +364,18 @@ class website(osv.osv): class ir_attachment(osv.osv): _inherit = "ir.attachment" def _website_url_get(self, cr, uid, ids, name, arg, context=None): - context = context or {} result = {} for attach in self.browse(cr, uid, ids, context=context): - if attach.type=='url': + if attach.type == 'url': result[attach.id] = attach.url else: - result[attach.id] = "/website/attachment/"+str(attach.id) + result[attach.id] = urlplus('/website/image', { + 'model': 'ir.attachment', + 'field': 'datas', + 'id': attach.id, + 'max_width': 1024, + 'max_height': 768, + }) return result _columns = { 'website_url': fields.function(_website_url_get, string="Attachment URL", type='char') From 258846a6975571d50886b1b9fc48f7887033aee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 12:55:24 +0200 Subject: [PATCH 03/11] [FIX] [WIP] website_sale: Tries to fix method that does things not commented on things that do not necessarily exist. Does it hurt you to put some docstrings ? bzr revid: tde@openerp.com-20131024105524-eattmf2s52ekztn3 --- addons/website_sale/models/product.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index e74dcda7ee4..9b4c388e929 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -35,10 +35,17 @@ class product_template(osv.Model): _name = 'product.template' def _website_url(self, cr, uid, ids, field_name, arg, context=None): - res = {} + """ TDE-NOTE: as someone wrote this method without any clue on about what it + does, fixing bugs about product_variant_ids not existing will be done + based on the weather, the sun and Lilo's feelings about pigs. + + If you see this comment in trunk, this means that the website branch has + been merged without any review, which is quite questionable. """ + res = dict.fromkeys(ids, '') base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') - for prod in self.browse(cr, uid, ids, context=context): - res[prod.id] = "%s/shop/product/%s/" % (base_url, prod.product_variant_ids[0].id) + for product in self.browse(cr, uid, ids, context=context): + if product.product_variant_ids: + res[product.id] = "%s/shop/product/%s/" % (base_url, product.product_variant_ids[0].id) return res _columns = { @@ -48,7 +55,7 @@ class product_template(osv.Model): 'suggested_product_ids': fields.one2many('product.template', 'suggested_product_id', 'Suggested Products'), 'website_size_x': fields.integer('Size X'), 'website_size_y': fields.integer('Size Y'), - 'website_style_ids' : fields.many2many('website.product.style','product_website_style_rel', 'product_id', 'style_id', 'Styles'), + 'website_style_ids': fields.many2many('website.product.style', 'product_website_style_rel', 'product_id', 'style_id', 'Styles'), 'website_sequence': fields.integer('Sequence', help="Determine the display order in the Website E-commerce"), 'website_url': fields.function(_website_url, string="Website url"), } From 0467c8a5abdeabacb90354a0a8ef936c317ba0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 13:04:53 +0200 Subject: [PATCH 04/11] [FIX] [WIP] website_sale: fix crash when having product templates without variant. probably it should not be displayed, but as there does not seem to exist any clue about what the controller / view should do, I added some protections. [DOC] added some comments because some methods seems quite weird. bzr revid: tde@openerp.com-20131024110453-uj4xnrtwst0fdcrb --- addons/website_sale/__openerp__.py | 2 +- addons/website_sale/controllers/main.py | 6 +++++- addons/website_sale/views/website_sale.xml | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/addons/website_sale/__openerp__.py b/addons/website_sale/__openerp__.py index 634078fe149..276bd11b0ff 100644 --- a/addons/website_sale/__openerp__.py +++ b/addons/website_sale/__openerp__.py @@ -18,7 +18,7 @@ OpenERP E-Commerce 'security/website_sale.xml', ], 'demo': [ - 'website_sale_demo.xml', + # 'website_sale_demo.xml', ], 'qweb': ['static/src/xml/*.xml'], 'installable': True, diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 8de0a0bb578..193bb079191 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -113,7 +113,7 @@ class Ecommerce(http.Controller): request.context['pricelist'] = self.get_pricelist() # search for checking of access rules and keep order - product_ids = [id for id in product_ids if id in product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context)] + product_ids = product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context) size_ids = {} style_ids = style_obj.search(request.cr, SUPERUSER_ID, [('html_class', 'like', 'size_%')], context=request.context) @@ -212,6 +212,7 @@ class Ecommerce(http.Controller): col += 1 line += 1 + print bin_packing_list return bin_packing_list def get_products(self, product_ids): @@ -272,6 +273,9 @@ class Ecommerce(http.Controller): @website.route(['/shop/', '/shop/page//'], type='http', auth="public", multilang=True) def category(self, category=0, attributes="", page=0, **post): + # TDE-NOTE: shouldn't we do somethign about product_template without variants ??? + # TDE-NOTE: is there a reason to call a method category when the route is + # basically a shop without category_id speceified ? if 'promo' in post: self.change_pricelist(post.get('promo')) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 26a484d247c..eb4c5fcf561 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -43,7 +43,7 @@ -
+
-
+

€ From 2cc18c153ea55894cac10a5953b53be1b960265d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 13:14:53 +0200 Subject: [PATCH 05/11] [REV] Reverted a change in _openerp__.py in website_sale, because this was just for local tests. bzr revid: tde@openerp.com-20131024111453-tqjx4st6js5qnoz4 --- addons/website_sale/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/__openerp__.py b/addons/website_sale/__openerp__.py index 276bd11b0ff..634078fe149 100644 --- a/addons/website_sale/__openerp__.py +++ b/addons/website_sale/__openerp__.py @@ -18,7 +18,7 @@ OpenERP E-Commerce 'security/website_sale.xml', ], 'demo': [ - # 'website_sale_demo.xml', + 'website_sale_demo.xml', ], 'qweb': ['static/src/xml/*.xml'], 'installable': True, From 9f0dcae234865a0d35c7095f0c9d8d881d9d06f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 13:35:39 +0200 Subject: [PATCH 06/11] [FIX] website_blog: read_more link was wrong, leading to a 404. The website_blog route is blog/, nothing related to category anymore. bzr revid: tde@openerp.com-20131024113539-v3e7oi9j67vp27sx --- addons/website_blog/models/website_blog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 9ecfe6cafee..a8e81552ee2 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -79,7 +79,7 @@ class BlogPost(osv.Model): 'oe_expand_container_tag': 'div', 'oe_expand_container_class': 'oe_mail_expand text-center', 'oe_expand_container_content': '', - 'oe_expand_a_href': '/blog/%d/%d' % (page.category_id.id, page.id), + 'oe_expand_a_href': '/blog/%d/' % page.id, 'oe_expand_a_class': 'oe_mail_expand btn btn-info', 'oe_expand_separator_node': 'br', }, From 980ec4bc9ee99232087058526fc82dd4949c951c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 24 Oct 2013 14:14:30 +0200 Subject: [PATCH 07/11] [FIX] website_blog: contact us button in blog leading to website.contactus page instead of doing nothing. bzr revid: tde@openerp.com-20131024121430-ab84qfdulomukkf4 --- addons/website_blog/views/website_blog_templates.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index 1ce018221c4..efbf22814d0 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -256,7 +256,7 @@ through your blog entries, referenced in Google.

- +
From c38f7295430ae18cf61a0cf9c3c9afacab7bdb45 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Oct 2013 13:17:10 +0200 Subject: [PATCH 08/11] [FIX] auth of pagenew bzr revid: xmo@openerp.com-20131024111710-5ghadng4we3p2cgg --- addons/website/controllers/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 30f384a606b..60d20f54c40 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -51,8 +51,7 @@ class Website(openerp.addons.web.controllers.main.Home): def index(self, **kw): return self.page("website.homepage") - # FIXME: auth, if /pagenew known anybody can create new empty page - @website.route('/pagenew/', type='http', auth="admin") + @website.route('/pagenew/', type='http', auth="user") def pagenew(self, path, noredirect=NOPE): module = 'website' # completely arbitrary max_length From 39fb50d43d4f3f0adba2c37ee345c3ac44cc84d4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Oct 2013 15:16:13 +0200 Subject: [PATCH 09/11] [REM] explicit cache clearing, fixing ir.translation instead bzr revid: xmo@openerp.com-20131024131613-6hebrxi5dbbs82ph --- addons/website/controllers/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 60d20f54c40..64357e1a443 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -214,7 +214,6 @@ class Website(openerp.addons.web.controllers.main.Home): 'value': new_content, } irt.create(request.cr, request.uid, new_trans) - irt._get_source.clear_cache(irt) # FIXME: find why ir.translation does not invalidate return True @website.route('/website/attach', type='http', auth='user') From a2a3f46d7281217d5958ffdaceab0f290b0065d1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Oct 2013 15:57:30 +0200 Subject: [PATCH 10/11] [FIX] 'inline' set_image_data bzr revid: xmo@openerp.com-20131024135730-321532upt3aq5esw --- addons/website/controllers/main.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 64357e1a443..69da43a3549 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -327,21 +327,14 @@ class Images(http.Controller): if response.status_code == 304: return response - return self.set_image_data( - response, record[field].decode('base64'), - fit=(int(max_width), int(max_height))) + data = record[field].decode('base64') + fit = int(max_width), int(max_height) - def set_image_data(self, response, data, fit=(maxint, maxint)): - """ Sets an inferred mime type on the response object, and puts the - provided image's data in it, possibly after resizing if requested - - Returns the response object after setting its mime and content, so - the result of ``get_final_image`` can be returned directly. - """ buf = cStringIO.StringIO(data) # FIXME: unknown format or not an image image = Image.open(buf) + image.load() response.mimetype = Image.MIME[image.format] w, h = image.size From c8dd901b047a351eb50056667a5af9d99f52438d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Oct 2013 16:10:24 +0200 Subject: [PATCH 11/11] [FIX] todo/notes bzr revid: xmo@openerp.com-20131024141024-3kdx3jfcsn8vzsyg --- addons/website/controllers/main.py | 1 - addons/website/static/src/js/website.snippets.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 69da43a3549..417fca99b27 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -332,7 +332,6 @@ class Images(http.Controller): buf = cStringIO.StringIO(data) - # FIXME: unknown format or not an image image = Image.open(buf) image.load() response.mimetype = Image.MIME[image.format] diff --git a/addons/website/static/src/js/website.snippets.js b/addons/website/static/src/js/website.snippets.js index 0b1ab4e13cd..c29325c8de8 100644 --- a/addons/website/static/src/js/website.snippets.js +++ b/addons/website/static/src/js/website.snippets.js @@ -25,8 +25,8 @@ save: function () { this.snippets.make_active(false); - // TODO TOFIX: call clean_for_save on all snippets of the page, not only modified ones - // important for banner of parallax that changes data automatically. + // FIXME: call clean_for_save on all snippets of the page, not only modified ones + // important for banner of parallax that changes data automatically. this.snippets.clean_for_save(); remove_added_snippet_id(); this._super();