Commit 95931b05 authored by Vincent A's avatar Vincent A

weboob.capabilties.recipe: use a single "picture" field instead of urls

Reuse weboob.capabilities.image.BaseImage to contain the image and its
thumbnail.

TODO: image data should be fetched by modules by fillobj means
parent 9af4ffac
......@@ -20,9 +20,10 @@
from weboob.capabilities.recipe import Recipe, Comment
from weboob.capabilities.base import NotAvailable
from weboob.capabilities.image import BaseImage, Thumbnail
from weboob.browser.pages import HTMLPage, pagination
from weboob.browser.elements import ItemElement, ListElement, method
from weboob.browser.filters.standard import CleanText, Regexp, Env, CleanDecimal
from weboob.browser.filters.standard import CleanText, Regexp, Env, CleanDecimal, Eval
from weboob.browser.filters.json import Dict, NotFound
from datetime import datetime, date, time
from dateutil.parser import parse as parse_date
......@@ -59,7 +60,12 @@ class ResultsPage(HTMLPage):
obj_id = Regexp(CleanText('./div/h2/a/@href'),
'/(.*).htm')
obj_title = CleanText('./div/h2/a')
obj_thumbnail_url = CleanText('./div/img/@src')
class obj_picture(ItemElement):
klass = BaseImage
obj_thumbnail = Eval(Thumbnail, CleanText('./div/img/@src'))
obj_short_description = CleanText('./div/p')
......@@ -98,5 +104,12 @@ class RecipePage(HTMLPage):
return [CleanDecimal(Dict('recipeYield'), default=0)(self)]
obj_instructions = Dict('recipeInstructions')
obj_picture_url = Dict('image', default='')
obj_author = Dict('author/name', default=NotAvailable)
def obj_picture(self):
img = BaseImage()
try:
img.url = self.el['image']
except KeyError:
return
return img
......@@ -43,7 +43,7 @@ class AllrecipesModule(Module, CapRecipe):
return self.browser.iter_recipes(quote_plus(pattern.encode('utf-8')))
def fill_recipe(self, recipe, fields):
if 'nb_person' in fields or 'instructions' in fields or 'thumbnail_url' in fields:
if 'nb_person' in fields or 'instructions' in fields or 'picture' in fields:
recipe = self.browser.get_recipe(recipe.id, recipe)
return recipe
......
......@@ -22,7 +22,8 @@ from weboob.browser.pages import HTMLPage, JsonPage, pagination
from weboob.browser.elements import ItemElement, DictElement, method
from weboob.capabilities.recipe import Recipe, Comment
from weboob.capabilities.base import NotAvailable
from weboob.browser.filters.standard import Env, Format, Join
from weboob.capabilities.image import BaseImage, Thumbnail
from weboob.browser.filters.standard import Env, Format, Join, Eval
from weboob.browser.filters.json import Dict
......@@ -76,8 +77,11 @@ class RecipePage(JsonPage):
ins = [Dict('displayValue')(el) for el in Dict('directions')(self)]
return Join('\n * ', ins, addBefore=' * ', addAfter='\n')(self)
obj_thumbnail_url = Dict('photo/photoDetailUrl')
obj_picture_url = Dict('photo/photoDetailUrl')
class obj_picture(ItemElement):
klass = BaseImage
obj_url = Dict('photo/photoDetailUrl')
obj_thumbnail = Eval(Thumbnail, obj_url)
@method
class get_comments(DictElement):
......
......@@ -20,9 +20,12 @@
from weboob.capabilities.recipe import Recipe, Comment
from weboob.capabilities.base import NotAvailable
from weboob.capabilities.image import BaseImage, Thumbnail
from weboob.browser.pages import HTMLPage, pagination
from weboob.browser.elements import ItemElement, method, ListElement
from weboob.browser.filters.standard import CleanText, Regexp, Env, Time, Join, Format
from weboob.browser.filters.standard import (
CleanText, Regexp, Env, Time, Join, Format, Eval,
)
from weboob.browser.filters.html import XPath
import re
......@@ -62,8 +65,15 @@ class ResultsPage(HTMLPage):
'/recettes/(.*).aspx')
obj_title = CleanText('./div/h2/a')
obj_thumbnail_url = Format('http:%s', CleanText('./div[has-class("searchImg")]/span/img[@data-src!=""]/@data-src|./div[has-class("searchImg")]/div/span/img[@src!=""]/@src',
default=None))
class obj_picture(ItemElement):
klass = BaseImage
url = CleanText('./div[has-class("searchImg")]/span/img[@data-src!=""]/@data-src|./div[has-class("searchImg")]/div/span/img[@src!=""]/@src',
default=None)
obj_thumbnail = Eval(Thumbnail, Format('http:%s', url))
def validate(self, obj):
return obj.thumbnail.url != 'http:'
obj_short_description = CleanText('./div[has-class("show-for-medium")]')
......@@ -78,11 +88,15 @@ class RecipePage(HTMLPage):
obj_id = Env('_id')
obj_title = CleanText('//h1')
obj_picture_url = Format('http:%s',
CleanText('//img[@id="shareimg" and @src!=""]/@src', default=None))
class obj_picture(ItemElement):
klass = BaseImage
obj_url = Format('http:%s',
CleanText('//img[@id="shareimg" and @src!=""]/@src', default=None))
obj_thumbnail = Eval(Thumbnail, obj_url)
obj_thumbnail_url = Format('http:%s',
CleanText('//img[@id="shareimg" and @src!=""]/@src', default=None))
def validate(self, obj):
return obj.url != 'http:'
def obj_preparation_time(self):
_prep = CuisineazDuration(CleanText('//span[@id="ContentPlaceHolder_LblRecetteTempsPrepa"]'))(self)
......
......@@ -22,13 +22,14 @@ from __future__ import unicode_literals
from weboob.browser.elements import ItemElement, ListElement, method
from weboob.browser.filters.standard import (
CleanText, CleanDecimal, Env, Regexp
CleanText, CleanDecimal, Env, Regexp, Eval,
)
from weboob.browser.filters.html import Attr, Link, XPath
from weboob.browser.pages import HTMLPage
from weboob.capabilities.base import NotAvailable
from weboob.capabilities.recipe import Comment, Recipe
from weboob.capabilities.image import BaseImage, Thumbnail
class SearchPage(HTMLPage):
......@@ -57,14 +58,18 @@ class SearchPage(HTMLPage):
obj_author = NotAvailable
obj_ingredients = NotAvailable
def obj_thumbnail_url(self):
style = Attr(
'.//a[has-class("bu_cuisine_recette_img")]/span',
'style'
)(self)
return style.replace("background-image:url(", "").rstrip(");")
class obj_picture(ItemElement):
klass = BaseImage
obj_url = NotAvailable
def obj_thumbnail(self):
style = Attr(
'.//a[has-class("bu_cuisine_recette_img")]/span',
'style'
)(self)
return Thumbnail(style.replace("background-image:url(", "").rstrip(");"))
obj_picture_url = NotAvailable
obj_instructions = NotAvailable
obj_preparation_time = CleanDecimal(
'(.//span[has-class("bu_cuisine_recette_carnet_duree")])[1]'
......@@ -105,12 +110,15 @@ class RecipePage(HTMLPage):
for ingredients_item in ingredients_items
]
obj_thumbnail_url = Attr(
'//article[has-class("bu_cuisine_main_recipe")]'
'//img[has-class("bu_cuisine_img_noborder")]',
'src'
)
obj_picture_url = obj_thumbnail_url
class obj_picture(ItemElement):
klass = BaseImage
obj_url = Attr(
'//article[has-class("bu_cuisine_main_recipe")]'
'//img[has-class("bu_cuisine_img_noborder")]',
'src'
)
obj_thumbnail = Eval(Thumbnail, obj_url)
def obj_instructions(self):
instructions = ''
......
......@@ -34,7 +34,7 @@ class JournaldesfemmesTest(BackendTest):
self.assertTrue(recipe.id)
self.assertTrue(recipe.url)
self.assertTrue(recipe.title)
self.assertTrue(recipe.thumbnail_url)
self.assertTrue(recipe.picture.thumbnail.url)
self.assertTrue(recipe.preparation_time)
self.assertGreaterEqual(recipe.cooking_time, 0)
......@@ -44,8 +44,8 @@ class JournaldesfemmesTest(BackendTest):
self.assertTrue(full_recipe.short_description)
self.assertTrue(full_recipe.author)
self.assertTrue(full_recipe.ingredients)
self.assertTrue(full_recipe.thumbnail_url)
self.assertTrue(full_recipe.picture_url)
self.assertTrue(full_recipe.picture.thumbnail.url)
self.assertTrue(full_recipe.picture.url)
self.assertTrue(full_recipe.preparation_time)
self.assertGreaterEqual(full_recipe.cooking_time, 0)
self.assertTrue(full_recipe.instructions)
......
......@@ -43,7 +43,7 @@ class MarmitonModule(Module, CapRecipe):
return self.browser.iter_recipes(quote_plus(pattern.encode('utf-8')))
def fill_recipe(self, recipe, fields):
if 'nb_person' in fields or 'instructions' in fields or 'thumbnail_url' in fields:
if 'nb_person' in fields or 'instructions' in fields or 'picture' in fields:
recipe = self.browser.get_recipe(recipe.id, recipe)
return recipe
......
......@@ -22,6 +22,7 @@ from weboob.browser.elements import ItemElement, ListElement, method
from weboob.browser.filters.standard import Regexp, CleanText, Format, Env, CleanDecimal, Eval
from weboob.browser.filters.json import Dict
from weboob.capabilities.recipe import Recipe, Comment
from weboob.capabilities.image import BaseImage, Thumbnail
from weboob.tools.json import json
import re
......@@ -66,8 +67,11 @@ class RecipePage(HTMLPage):
obj_title = Dict('name')
obj_ingredients = Dict('recipeIngredient')
obj_thumbnail_url = Dict('image')
obj_picture_url = Dict('image')
class obj_picture(ItemElement):
klass = BaseImage
obj_url = Dict('image')
obj_thumbnail = Eval(Thumbnail, obj_url)
def obj_instructions(self):
str = Dict('recipeInstructions')(self)
......
......@@ -43,7 +43,7 @@ class SupertoinetteModule(Module, CapRecipe):
def fill_recipe(self, recipe, fields):
if 'nb_person' in fields or 'instructions' in fields:
rec = self.get_recipe(recipe.id)
recipe.picture_url = rec.picture_url
recipe.picture = rec.picture
recipe.instructions = rec.instructions
recipe.ingredients = rec.ingredients
recipe.comments = rec.comments
......
......@@ -19,9 +19,12 @@
from weboob.capabilities.recipe import Recipe
from weboob.capabilities.base import NotAvailable
from weboob.capabilities.image import BaseImage, Thumbnail
from weboob.browser.elements import ItemElement, ListElement, method
from weboob.browser.pages import HTMLPage
from weboob.browser.filters.standard import CleanText, Env, Regexp, Type, Join
from weboob.browser.filters.standard import (
CleanText, Env, Regexp, Type, Join, Eval,
)
from weboob.browser.filters.html import XPath
......@@ -74,5 +77,8 @@ class RecipePage(HTMLPage):
obj_instructions = Join(u'\n- ', '//div[@class="recipe-prepa"]/ol/li', newline=True, addBefore='- ')
obj_thumbnail_url = CleanText('//div[has-class("toprecipeImage")]/img/@src', default=NotAvailable)
obj_picture_url = CleanText('//div[has-class("toprecipeImage")]/img/@src', default=NotAvailable)
class obj_picture(ItemElement):
klass = BaseImage
obj_url = CleanText('//div[has-class("toprecipeImage")]/img/@src', default=NotAvailable)
obj_thumbnail = Eval(Thumbnail, obj_url)
......@@ -63,8 +63,13 @@ class MiniRecipe(QFrame):
@Slot()
def gotThumbnail(self):
if not empty(self.recipe.thumbnail_url):
data = requests.get(self.recipe.thumbnail_url).content
try:
url = self.recipe.picture.thumbnail.url
except AttributeError:
return
if not empty(url):
data = requests.get(url).content
img = QImage.fromData(data)
self.ui.imageLabel.setPixmap(QPixmap.fromImage(img).scaledToHeight(100,Qt.SmoothTransformation))
......
......@@ -87,8 +87,13 @@ class Recipe(QFrame):
self.ui.verticalLayout_2.setAlignment(Qt.AlignTop)
def gotThumbnail(self):
if self.recipe.picture_url and not empty(self.recipe.picture_url):
data = requests.get(self.recipe.picture_url).content
try:
url = self.recipe.picture.url
except AttributeError:
return
if not empty(url):
data = requests.get(url).content
img = QImage.fromData(data)
self.ui.imageLabel.setPixmap(QPixmap.fromImage(img).scaledToWidth(250, Qt.SmoothTransformation))
......
......@@ -19,6 +19,7 @@
from .base import Capability, BaseObject, StringField, IntField, Field
from .image import BaseImage
__all__ = ['CapRecipe', 'Recipe', 'Comment']
......@@ -46,8 +47,7 @@ class Recipe(BaseObject):
"""
title = StringField('Title of the recipe')
author = StringField('Author name of the recipe')
thumbnail_url = StringField('Direct url to recipe thumbnail')
picture_url = StringField('Direct url to recipe picture')
picture = Field('Picture of the dish', BaseImage)
short_description = StringField('Short description of a recipe')
nb_person = Field('The recipe was made for this amount of persons', list)
preparation_time = IntField('Preparation time of the recipe in minutes')
......
......@@ -70,8 +70,8 @@ def recipe_to_krecipes_xml(recipe, author=None):
if not empty(recipe.preparation_time):
preptime = ET.SubElement(desc, 'preparation-time')
preptime.text = '%02d:%02d' % (recipe.preparation_time / 60, recipe.preparation_time % 60)
if not empty(recipe.picture_url) and recipe.picture_url != '':
data = requests.get(recipe.picture_url).content
if recipe.picture and recipe.picture.url:
data = requests.get(recipe.picture.url).content
datab64 = base64.encodestring(data)[:-1]
pictures = ET.SubElement(desc, 'pictures')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment