From 78ccdd75b296a27e9b49c810e6ae889fb2e60d73 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 7 Dec 2009 12:05:20 -0700 Subject: [PATCH] Download latest version of recipes from the calibre server automatically. This allows recipe fixes to propagate to users without the need to update calibre --- src/calibre/manual/news_recipe.rst | 8 ++++++++ src/calibre/web/feeds/input.py | 21 ++++++++++++++++++++- src/calibre/web/feeds/news.py | 3 +++ src/calibre/web/feeds/recipes/collection.py | 21 ++++++++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/calibre/manual/news_recipe.rst b/src/calibre/manual/news_recipe.rst index 0fb94d4a69..8f39cee387 100644 --- a/src/calibre/manual/news_recipe.rst +++ b/src/calibre/manual/news_recipe.rst @@ -109,6 +109,8 @@ Pre/post processing of downloaded HTML .. automember:: BasicNewsRecipe.template_css +.. automember:: BasicNewsRecipe.remove_javascript + .. automethod:: BasicNewsRecipe.preprocess_html .. automethod:: BasicNewsRecipe.postprocess_html @@ -128,6 +130,12 @@ Convenience methods .. automethod:: BasicNewsRecipe.tag_to_string +Miscellaneous +~~~~~~~~~~~~~~~~~~ + +.. automember:: BasicNewsRecipe.requires_version + + CustomIndexRecipe --------------------- diff --git a/src/calibre/web/feeds/input.py b/src/calibre/web/feeds/input.py index adad69f885..ea65511506 100644 --- a/src/calibre/web/feeds/input.py +++ b/src/calibre/web/feeds/input.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' import os from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation +from calibre.constants import numeric_version class RecipeInput(InputFormatPlugin): @@ -51,7 +52,25 @@ class RecipeInput(InputFormatPlugin): else: title = getattr(opts, 'original_recipe_input_arg', recipe_or_file) title = os.path.basename(title).rpartition('.')[0] - recipe = compile_recipe(get_builtin_recipe_by_title(title, log)) + raw = get_builtin_recipe_by_title(title, log=log, download_recipe=True) + builtin = False + try: + recipe = compile_recipe(raw) + if recipe.requires_version > numeric_version: + log.warn( + 'Downloaded recipe needs calibre version at least: %s' % \ + recipe.requires_version) + builtin = True + except: + log.exception('Failed to compile downloaded recipe. Falling ' + 'back to builtin one') + builtin = True + if builtin: + raw = get_builtin_recipe_by_title(title, log=log, + download_recipe=False) + recipe = compile_recipe(raw) + + if recipe is None: raise ValueError('%r is not a valid recipe file or builtin recipe' % diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 6ff0424162..b2d0d4d2ce 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -46,6 +46,9 @@ class BasicNewsRecipe(Recipe): #: The author of this recipe __author__ = __appname__ + #: Minimum calibre version needed to use this recipe + requires_version = (0, 6, 0) + #: The language that the news is in. Must be an ISO-639 code either #: two or three characters long language = 'und' diff --git a/src/calibre/web/feeds/recipes/collection.py b/src/calibre/web/feeds/recipes/collection.py index eac18428f7..c90bf82842 100644 --- a/src/calibre/web/feeds/recipes/collection.py +++ b/src/calibre/web/feeds/recipes/collection.py @@ -14,6 +14,8 @@ from lxml import etree from lxml.builder import ElementMaker from dateutil import parser +from calibre import browser + NS = 'http://calibre-ebook.com/recipe_collection' E = ElementMaker(namespace=NS, nsmap={None:NS}) @@ -88,10 +90,27 @@ def get_custom_recipe_collection(db): def get_builtin_recipe_titles(): return [r.get('title') for r in get_builtin_recipe_collection()] -def get_builtin_recipe_by_title(title, log=None): +def download_builtin_recipe(urn): + br = browser() + return br.open('http://status.calibre-ebook.com/recipe/'+urn).read() + + +def get_builtin_recipe_by_title(title, log=None, download_recipe=False): for x in get_builtin_recipe_collection(): if x.get('title') == title: urn = x.get('id')[8:] + if download_recipe: + try: + if log is not None: + log('Trying to get latest version of recipe:', urn) + return download_builtin_recipe(urn) + except: + if log is None: + import traceback + traceback.print_exc() + else: + log.exception( + 'Failed to download recipe, using builtin version') return P('recipes/%s.recipe'%urn, data=True) class SchedulerConfig(object):