-
-
Notifications
You must be signed in to change notification settings - Fork 698
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[9.0][website_blog_excerpt_img] Migrate, LGPL.
Relicensed, migrated, new tests.
- Loading branch information
Showing
14 changed files
with
270 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import blog_post |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
import json | ||
from openerp import models | ||
|
||
|
||
class BlogPost(models.Model): | ||
_inherit = "blog.post" | ||
|
||
def main_image(self): | ||
"""Get blog's main image URL.""" | ||
Converter = self.env['ir.fields.converter'] | ||
html = self.content | ||
# Get a dictionary of properties, avoiding possible malformed ones | ||
try: | ||
properties = json.loads(self.cover_properties) | ||
except (TypeError, ValueError): | ||
properties = dict() | ||
# Prepend cover image to post content, if there is one | ||
cover = properties.pop("background-image", "none") | ||
if cover and cover != "none": | ||
html = u"<div style={q}background-image:{}{q}/>{}".format( | ||
cover, | ||
html, | ||
q='"' if '"' not in cover else "'", | ||
) | ||
# Return the first found image URL or None | ||
try: | ||
return next(Converter.imgs_from_html(html, 1)) | ||
except StopIteration: | ||
return None | ||
|
||
def content_excerpt(self, length=80): | ||
"""Get the blog post content excerpt.""" | ||
return self.env['ir.fields.converter'].text_from_html( | ||
self.content, | ||
length, | ||
) |
10 changes: 0 additions & 10 deletions
10
website_blog_excerpt_img/static/src/css/website_blog_excerpt_img.css
This file was deleted.
Oops, something went wrong.
7 changes: 0 additions & 7 deletions
7
website_blog_excerpt_img/static/src/css/website_blog_excerpt_img.css.map
This file was deleted.
Oops, something went wrong.
5 changes: 2 additions & 3 deletions
5
website_blog_excerpt_img/static/src/css/website_blog_excerpt_img.sass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
@charset "utf-8" | ||
/* © 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis | ||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
/* Copyright 2016 Jairo Llopis <[email protected]> | ||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ | ||
|
||
.website_blog | ||
.excerpt-img .img | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- © 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis | ||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). --> | ||
|
||
<odoo> | ||
|
||
<template id="assets_frontend" inherit_id="website_blog.assets_frontend"> | ||
<xpath expr="."> | ||
<link | ||
rel="stylesheet" | ||
href="/website_blog_excerpt_img/static/src/css/website_blog_excerpt_img.sass"/> | ||
</xpath> | ||
</template> | ||
|
||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- © 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis | ||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). --> | ||
|
||
<odoo> | ||
|
||
<template id="blog_post_short" | ||
inherit_id="website_blog.blog_post_short"> | ||
<!-- Entries are Bootstrap rows --> | ||
<xpath expr="//div[@t-as='blog_post']" position="attributes"> | ||
<attribute name="class">mb32 row</attribute> | ||
</xpath> | ||
<xpath expr="//h2/.." position="attributes"> | ||
<attribute name="class">col-xs-10</attribute> | ||
</xpath> | ||
<xpath expr="//div[@name='blog_post_data']/.." position="attributes"> | ||
<attribute name="class">text-muted col-xs-12 mb16</attribute> | ||
</xpath> | ||
|
||
<!-- Excerpt, image, read more button --> | ||
<xpath expr="//div[@name='blog_post_data']/.." position="after"> | ||
<t t-set="image_url" t-value="blog_post.main_image()"/> | ||
|
||
<div t-attf-class="excerpt-txt col-sm-#{7 if image_url else 12}"> | ||
<p t-esc="blog_post.content_excerpt()"/> | ||
<p> | ||
<a t-attf-href="/blog/#{slug(blog_post.blog_id)}/post/#{slug(blog_post)}" | ||
class="btn btn-primary"> | ||
Read more | ||
</a> | ||
</p> | ||
</div> | ||
<div t-if="image_url" class="col-sm-5 text-center excerpt-img"> | ||
<!-- Use cover image if available --> | ||
<img class="img img-responsive img-thumbnail" | ||
t-att-src="image_url"/> | ||
</div> | ||
</xpath> | ||
</template> | ||
|
||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
from . import test_html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). | ||
|
||
import json | ||
from lxml import html | ||
from openerp.tests.common import HttpCase | ||
|
||
|
||
class HTMLCase(HttpCase): | ||
def setUp(self): | ||
super(HTMLCase, self).setUp() | ||
with self.cursor() as cr: | ||
env = self.env(cr) | ||
self.blog_id = env["blog.blog"].create({ | ||
"name": "Test blog", | ||
}).id | ||
Post = env["blog.post"] | ||
# Create a post with cover image but no image in content | ||
Post.create({ | ||
"name": "Post 1", | ||
"content": "A covered post", | ||
"cover_properties": | ||
json.dumps({"background-image": "url(/post-1)"}), | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post like the previous one, but url is double-quoted | ||
Post.create({ | ||
"name": "Post 2", | ||
"content": "A covered post", | ||
"cover_properties": | ||
json.dumps({"background-image": 'url("/post-2")'}), | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post like the previous one, but url is single-quoted | ||
Post.create({ | ||
"name": "Post 3", | ||
"content": "A covered post", | ||
"cover_properties": | ||
json.dumps({"background-image": "url('/post-3')"}), | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post with malformed cover_properties and no cover, but | ||
# with background image in content | ||
Post.create({ | ||
"name": "Post 4", | ||
"content": | ||
"<div style='background-image:url(/post-4)'>Badly</div>", | ||
"cover_properties": "malformed", | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post with default cover_properties and <img> in content | ||
Post.create({ | ||
"name": "Post 5", | ||
"content": "Cool post with image <img src='/post-5'/>", | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post with no images | ||
Post.create({ | ||
"name": "Post 6", | ||
"content": "Really boring", | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
# Create a post with lots of words | ||
Post.create({ | ||
"name": "Post 7", | ||
"content": "Lots of words " * 80, | ||
"website_published": True, | ||
"blog_id": self.blog_id | ||
}) | ||
|
||
# Open the blog index and store its HTML content | ||
self.html = html.document_fromstring( | ||
self.url_open( | ||
"/blog/test-blog-%d" % self.blog_id, | ||
timeout=30).read()) | ||
|
||
def container(self, post_title): | ||
"""Find the container of a blog post with given title.""" | ||
query = u""" | ||
.//div[@id='main_column']/div | ||
[.//h2[contains(text(), "{}")]] | ||
""" | ||
return self.html.xpath(query.format(post_title))[0] | ||
|
||
def image(self, container): | ||
"""Find the extracted image URL in a given container.""" | ||
query = ".//div[contains(@class, 'excerpt-img')]/img" | ||
return container.xpath(query)[0].attrib["src"] | ||
|
||
def text(self, container): | ||
"""Find the text excerpt in a given container.""" | ||
query = ".//div[contains(@class, 'excerpt-txt')]/p[1]" | ||
return container.xpath(query)[0].text_content().strip() | ||
|
||
def test_cover_bg_unquoted(self): | ||
"""Cover image without quotes.""" | ||
container = self.container("Post 1") | ||
self.assertEqual(self.text(container), "A covered post") | ||
self.assertEqual(self.image(container), "/post-1") | ||
|
||
def test_cover_bg_double_quoted(self): | ||
"""Cover image with double quotes.""" | ||
container = self.container("Post 2") | ||
self.assertEqual(self.text(container), "A covered post") | ||
self.assertEqual(self.image(container), "/post-2") | ||
|
||
def test_cover_bg_single_quoted(self): | ||
"""Cover image with single quotes.""" | ||
container = self.container("Post 3") | ||
self.assertEqual(self.text(container), "A covered post") | ||
self.assertEqual(self.image(container), "/post-3") | ||
|
||
def test_cover_malformed(self): | ||
"""Cover image malformed properties and background in content.""" | ||
container = self.container("Post 4") | ||
self.assertEqual(self.text(container), "Badly") | ||
self.assertEqual(self.image(container), "/post-4") | ||
|
||
def test_content_img(self): | ||
"""No cover image, <img> element in content.""" | ||
container = self.container("Post 5") | ||
self.assertEqual(self.text(container), "Cool post with image") | ||
self.assertEqual(self.image(container), "/post-5") | ||
|
||
def test_no_img(self): | ||
"""No image anywhere.""" | ||
container = self.container("Post 6") | ||
self.assertEqual(self.text(container), "Really boring") | ||
with self.assertRaises(IndexError): | ||
self.image(container) | ||
|
||
def test_text_excerpt(self): | ||
"""Lots of words get truncated.""" | ||
container = self.container("Post 7") | ||
text = self.text(container) | ||
self.assertEqual(len(text.split()), 80) | ||
self.assertTrue( | ||
text.endswith(u"…"), | ||
u"'{}' should end with '…'".format(text)) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.