diff --git a/modules/750g/pages.py b/modules/750g/pages.py index e5ce1fb76f9334ee4f04f8643ef13841675d5b9e..510177a52179a9f3d93cf81fcf75e332fb73120f 100644 --- a/modules/750g/pages.py +++ b/modules/750g/pages.py @@ -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 @@ def condition(self): 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 @@ def obj_nb_person(self): 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 diff --git a/modules/allrecipes/module.py b/modules/allrecipes/module.py index 22e6374d9429ffa29799acf1dd78d6cccb4aaaf3..49e99504a527b09b995f8e213c59f66b34c1a7fd 100644 --- a/modules/allrecipes/module.py +++ b/modules/allrecipes/module.py @@ -43,7 +43,7 @@ def iter_recipes(self, pattern): 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 diff --git a/modules/allrecipes/pages.py b/modules/allrecipes/pages.py index 1cb28252b26f4118479f065dba2ef1f4bed39999..b1c0679b8c240333f868019b7071087ead61bf52 100644 --- a/modules/allrecipes/pages.py +++ b/modules/allrecipes/pages.py @@ -22,7 +22,8 @@ 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 @@ def obj_instructions(self): 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): diff --git a/modules/cuisineaz/pages.py b/modules/cuisineaz/pages.py index 9c5e044f7409686ea5b60816dcd327f2b306d4d4..871904246822b92e3d846671c670d2ed110496a6 100644 --- a/modules/cuisineaz/pages.py +++ b/modules/cuisineaz/pages.py @@ -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 @@ def condition(self): '/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 get_recipe(ItemElement): 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) diff --git a/modules/journaldesfemmes/pages.py b/modules/journaldesfemmes/pages.py index 5187090286cb4436606ea9b58a86342c8682bacc..c61a058534a4a9c5fdee533cd35e1a2fc9126970 100644 --- a/modules/journaldesfemmes/pages.py +++ b/modules/journaldesfemmes/pages.py @@ -22,13 +22,14 @@ 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 item(ItemElement): 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 @@ def obj_ingredients(self): 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 = '' diff --git a/modules/journaldesfemmes/test.py b/modules/journaldesfemmes/test.py index 0144ec7da3461dda7f9b181718e5dde32c1549a4..6036a0e911112546c4e6ae0a11f23ef09197406a 100644 --- a/modules/journaldesfemmes/test.py +++ b/modules/journaldesfemmes/test.py @@ -34,7 +34,7 @@ def test_recipe(self): 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 @@ def test_recipe(self): 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) diff --git a/modules/marmiton/module.py b/modules/marmiton/module.py index d79d5510a3330de1e5444acf78fa3f73134f182f..d830ee54f824ff9309546ffcdddf88a419e0c785 100644 --- a/modules/marmiton/module.py +++ b/modules/marmiton/module.py @@ -43,7 +43,7 @@ def iter_recipes(self, pattern): 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 diff --git a/modules/marmiton/pages.py b/modules/marmiton/pages.py index a3ca87ace89510a4270a47c97abe66f6c7695d70..1f78bb46b8b8e13d9191a9630a737509336d34e0 100644 --- a/modules/marmiton/pages.py +++ b/modules/marmiton/pages.py @@ -22,6 +22,7 @@ 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 @@ def parse(self, el): 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) diff --git a/modules/supertoinette/module.py b/modules/supertoinette/module.py index 692be3f8fe0a00129aa73883a0e8725bb4b7746b..1ad0294cb88ce439bfa2d1bbfd8eea94dfd2a1da 100644 --- a/modules/supertoinette/module.py +++ b/modules/supertoinette/module.py @@ -43,7 +43,7 @@ def iter_recipes(self, pattern): 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 diff --git a/modules/supertoinette/pages.py b/modules/supertoinette/pages.py index f064c66d33816551e8c7da77ca9596f85f363b60..3017e8d375c065f0eac11c8e9eae331a7b0d2029 100644 --- a/modules/supertoinette/pages.py +++ b/modules/supertoinette/pages.py @@ -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 @@ def obj_ingredients(self): 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) diff --git a/weboob/applications/qcookboob/minirecipe.py b/weboob/applications/qcookboob/minirecipe.py index 0318e7aea0b64c680ed19bfa40d180f46183b098..79a234a75b789707e3e880318c2bf5dfca9b2118 100644 --- a/weboob/applications/qcookboob/minirecipe.py +++ b/weboob/applications/qcookboob/minirecipe.py @@ -63,8 +63,13 @@ def __init__(self, weboob, backend, recipe, parent=None): @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)) diff --git a/weboob/applications/qcookboob/recipe.py b/weboob/applications/qcookboob/recipe.py index c6f09d0076146afb15a59b8e853f72c04e49d731..37890763a4445c1108fa571f283ddc4ddc38aee7 100644 --- a/weboob/applications/qcookboob/recipe.py +++ b/weboob/applications/qcookboob/recipe.py @@ -87,8 +87,13 @@ def __init__(self, recipe, backend, parent=None): 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)) diff --git a/weboob/capabilities/recipe.py b/weboob/capabilities/recipe.py index c54e6df32508814c2251f61ae03bd665e2212ea7..d7b25243a0f57c5af9ef4a1be30e61abfcc27524 100644 --- a/weboob/capabilities/recipe.py +++ b/weboob/capabilities/recipe.py @@ -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') diff --git a/weboob/tools/capabilities/recipe.py b/weboob/tools/capabilities/recipe.py index 986d486107276e430a7f936d2bbd349a3adcd9fa..f87ca68ea649d4a6c9a1b648c60e50fc7baeaabe 100644 --- a/weboob/tools/capabilities/recipe.py +++ b/weboob/tools/capabilities/recipe.py @@ -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')