summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-02-05 13:42:10 +0100
committerChristophe Simonis <chs@odoo.com>2018-02-05 13:42:10 +0100
commit2dbc1edef92c22a9d6070778f0f1128ef78a6040 (patch)
treea89bb1f511c2b8f98f521b1fa0d7c072af5d82bc /addons
parent3d18214637fe7f85952daed2f957f44046eb6450 (diff)
parentb503e79722ab8b9f3ba2149a2b603f0e0e28eec2 (diff)
[MERGE] forward port branch saas-16 up to b503e79722a
Diffstat (limited to 'addons')
-rw-r--r--addons/calendar/views/calendar_views.xml2
-rw-r--r--addons/pad/models/pad.py31
-rw-r--r--addons/pad/py_etherpad/__init__.py14
-rw-r--r--addons/product/models/product_attribute.py7
-rw-r--r--addons/product/tests/test_variants.py37
-rw-r--r--addons/website_forum/views/website_forum.xml2
6 files changed, 74 insertions, 19 deletions
diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml
index 791b9cee72e..8531e314f78 100644
--- a/addons/calendar/views/calendar_views.xml
+++ b/addons/calendar/views/calendar_views.xml
@@ -75,7 +75,7 @@
<field name="partner_ids"/>
<field name="location"/>
<field name="state" invisible="True"/>
- <field name="duration"/>
+ <field name="duration" widget="float_time"/>
<field name="message_needaction" invisible="1"/>
</tree>
</field>
diff --git a/addons/pad/models/pad.py b/addons/pad/models/pad.py
index aebcff24918..a1e31bf485a 100644
--- a/addons/pad/models/pad.py
+++ b/addons/pad/models/pad.py
@@ -10,7 +10,6 @@ import requests
from odoo import api, models, _
from odoo.exceptions import UserError
-from odoo.tools import html2plaintext
from ..py_etherpad import EtherpadLiteClient
@@ -65,9 +64,7 @@ class PadCommon(models.AbstractModel):
# get content of the real field
for record in model.browse([self.env.context["object_id"]]):
if record[real_field]:
- myPad.setText(path, (html2plaintext(record[real_field]).encode('utf-8')))
- # Etherpad for html not functional
- # myPad.setHTML(path, record[real_field])
+ myPad.setHtmlFallbackText(path, record[real_field])
return {
"server": pad["server"],
@@ -77,17 +74,25 @@ class PadCommon(models.AbstractModel):
@api.model
def pad_get_content(self, url):
+ company = self.env.user.sudo().company_id
+ myPad = EtherpadLiteClient(company.pad_key, company.pad_server + '/api')
content = ''
if url:
+ split_url = url.split('/p/')
+ path = len(split_url) == 2 and split_url[1]
try:
- r = requests.get('%s/export/html' % url)
- r.raise_for_status()
- except:
- _logger.warning("No url found '%s'.", url)
- else:
- mo = re.search('<body>(.*)</body>', r.content.decode(), re.DOTALL)
- if mo:
- content = mo.group(1)
+ content = myPad.getHtml(path).get('html', '')
+ except IOError:
+ _logger.warning('Http Error: the credentials might be absent for url: "%s". Falling back.' % url)
+ try:
+ r = requests.get('%s/export/html' % url)
+ r.raise_for_status()
+ except Exception:
+ _logger.warning("No pad found with url '%s'.", url)
+ else:
+ mo = re.search('<body>(.*)</body>', r.content.decode(), re.DOTALL)
+ if mo:
+ content = mo.group(1)
return content
@@ -128,7 +133,7 @@ class PadCommon(models.AbstractModel):
company = self.env.user.sudo().company_id
myPad = EtherpadLiteClient(company.pad_key, company.pad_server + '/api')
path = self[k].split('/p/')[1]
- myPad.setText(path, (html2plaintext(vals[field.pad_content_field]).encode('utf-8')))
+ myPad.setHtmlFallbackText(path, vals[field.pad_content_field])
# Update the `pad_content_field` if the pad is modified
for k, v in list(vals.items()):
diff --git a/addons/pad/py_etherpad/__init__.py b/addons/pad/py_etherpad/__init__.py
index fc9721eb9c8..2d4872f3bb9 100644
--- a/addons/pad/py_etherpad/__init__.py
+++ b/addons/pad/py_etherpad/__init__.py
@@ -1,5 +1,10 @@
"""Module to talk to EtherpadLite API."""
import requests
+import logging
+
+from odoo.tools import html2plaintext
+
+_logger = logging.getLogger(__name__)
class EtherpadLiteClient:
@@ -171,6 +176,15 @@ class EtherpadLiteClient:
"text": text
})
+ def setHtmlFallbackText(self, padID, html):
+ try:
+ # Prevents malformed HTML errors
+ html_wellformed = '<html><body>' + html + '</body></html>'
+ return self.setHtml(padID, html_wellformed)
+ except Exception:
+ _logger.exception('Falling back to setText. SetHtml failed with message:')
+ return self.setText(padID, html2plaintext(html).encode('UTF-8'))
+
def setHtml(self, padID, html):
"""sets the text of a pad from html"""
return self.call("setHTML", {
diff --git a/addons/product/models/product_attribute.py b/addons/product/models/product_attribute.py
index cffefbbda13..e47297da52f 100644
--- a/addons/product/models/product_attribute.py
+++ b/addons/product/models/product_attribute.py
@@ -107,7 +107,6 @@ class ProductAttributeLine(models.Model):
# search on a m2o and one on a m2m, probably this will quickly become
# difficult to compute - check if performance optimization is required
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
- new_args = ['|', ('attribute_id', operator, name), ('value_ids', operator, name)]
- else:
- new_args = args
- return super(ProductAttributeLine, self).name_search(name=name, args=new_args, operator=operator, limit=limit)
+ args = ['|', ('attribute_id', operator, name), ('value_ids', operator, name)]
+ return self.search(args, limit=limit).name_get()
+ return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit)
diff --git a/addons/product/tests/test_variants.py b/addons/product/tests/test_variants.py
index fbf3073377d..813f5f9e28d 100644
--- a/addons/product/tests/test_variants.py
+++ b/addons/product/tests/test_variants.py
@@ -2,6 +2,43 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import common
+from odoo.tests.common import TransactionCase
+
+class TestVariants(TransactionCase):
+
+ def setUp(self):
+ res = super(TestVariants, self).setUp()
+ self.size_attr = self.env['product.attribute'].create({'name': 'Size'})
+ self.size_attr_value_s = self.env['product.attribute.value'].create({'name': 'S', 'attribute_id': self.size_attr.id})
+ self.size_attr_value_m = self.env['product.attribute.value'].create({'name': 'M', 'attribute_id': self.size_attr.id})
+ self.size_attr_value_l = self.env['product.attribute.value'].create({'name': 'L', 'attribute_id': self.size_attr.id})
+ self.product_shirt_template = self.env['product.template'].create({
+ 'name': 'Shirt',
+ 'attribute_line_ids': [(0, 0, {
+ 'attribute_id': self.size_attr.id,
+ 'value_ids': [(6, 0, [self.size_attr_value_l.id])],
+ })]
+ })
+ return res
+
+ def test_attribute_line_search(self):
+ search_not_to_be_found = self.env['product.template'].search(
+ [('attribute_line_ids', '=', 'M')]
+ )
+ self.assertNotIn(self.product_shirt_template, search_not_to_be_found,
+ 'Shirt should not be found searching M')
+
+ search_attribute = self.env['product.template'].search(
+ [('attribute_line_ids', '=', 'Size')]
+ )
+ self.assertIn(self.product_shirt_template, search_attribute,
+ 'Shirt should be found searching Size')
+
+ search_value = self.env['product.template'].search(
+ [('attribute_line_ids', '=', 'L')]
+ )
+ self.assertIn(self.product_shirt_template, search_value,
+ 'Shirt should be found searching L')
class TestVariants(common.TestProductCommon):
diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml
index 3d2315db252..049d5dd1835 100644
--- a/addons/website_forum/views/website_forum.xml
+++ b/addons/website_forum/views/website_forum.xml
@@ -685,7 +685,7 @@
<!-- Edition: post a reply -->
<template id="post_reply">
- <div class="css_editable_mode_hidden" groups="base.group_user">
+ <div class="css_editable_mode_hidden">
<form t-attf-id="reply#{ object._name.replace('.','') + '-' + str(object.id) }" class="collapse js_website_submit_form"
t-attf-action="/forum/#{ slug(forum) }/#{slug(object)}/reply" method="post" role="form">
<h3 class="mt8">Your Reply</h3>