From 3cd9ffcec6c14cada79b989fbfa92df49db5100c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 11 Jan 2011 15:08:15 -0700 Subject: [PATCH] Fix #8281 (Error when customizing builtin recipes with same name (e.g. The Nation)) --- src/calibre/gui2/dialogs/user_profiles.py | 69 ++++++++++++++++----- src/calibre/web/feeds/recipes/collection.py | 19 +++++- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/calibre/gui2/dialogs/user_profiles.py b/src/calibre/gui2/dialogs/user_profiles.py index 71c9ebcd04..04c41f0c5e 100644 --- a/src/calibre/gui2/dialogs/user_profiles.py +++ b/src/calibre/gui2/dialogs/user_profiles.py @@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal ' import time, os from PyQt4.Qt import SIGNAL, QUrl, QAbstractListModel, Qt, \ - QVariant, QInputDialog + QVariant from calibre.web.feeds.recipes import compile_recipe from calibre.web.feeds.news import AutomaticNewsRecipe @@ -256,24 +256,61 @@ class %(classname)s(%(base_class)s): def add_builtin_recipe(self): from calibre.web.feeds.recipes.collection import \ - get_builtin_recipe_by_title, get_builtin_recipe_titles - items = sorted(get_builtin_recipe_titles(), key=sort_key) + get_builtin_recipe_collection, get_builtin_recipe_by_id + from PyQt4.Qt import QDialog, QVBoxLayout, QListWidgetItem, \ + QListWidget, QDialogButtonBox, QSize + d = QDialog(self) + d.l = QVBoxLayout() + d.setLayout(d.l) + d.list = QListWidget(d) + d.list.doubleClicked.connect(lambda x: d.accept()) + d.l.addWidget(d.list) + d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, + Qt.Horizontal, d) + d.bb.accepted.connect(d.accept) + d.bb.rejected.connect(d.reject) + d.l.addWidget(d.bb) + d.setWindowTitle(_('Choose builtin recipe')) + items = [] + for r in get_builtin_recipe_collection(): + id_ = r.get('id', '') + title = r.get('title', '') + lang = r.get('language', '') + if id_ and title: + items.append((title + ' [%s]'%lang, id_)) - title, ok = QInputDialog.getItem(self, _('Pick recipe'), _('Pick the recipe to customize'), - items, 0, False) - if ok: - title = unicode(title) - profile = get_builtin_recipe_by_title(title) - if self._model.has_title(title): - if question_dialog(self, _('Replace recipe?'), - _('A custom recipe named %s already exists. Do you want to ' - 'replace it?')%title): - self._model.replace_by_title(title, profile) - else: - return + items.sort(key=lambda x:sort_key(x[0])) + for title, id_ in items: + item = QListWidgetItem(title) + item.setData(Qt.UserRole, id_) + d.list.addItem(item) + + d.resize(QSize(450, 400)) + ret = d.exec_() + d.list.doubleClicked.disconnect() + if ret != d.Accepted: + return + + items = list(d.list.selectedItems()) + if not items: + return + item = items[-1] + id_ = unicode(item.data(Qt.UserRole).toString()) + title = unicode(item.data(Qt.DisplayRole).toString()).rpartition(' [')[0] + profile = get_builtin_recipe_by_id(id_) + if profile is None: + raise Exception('Something weird happened') + + if self._model.has_title(title): + if question_dialog(self, _('Replace recipe?'), + _('A custom recipe named %s already exists. Do you want to ' + 'replace it?')%title): + self._model.replace_by_title(title, profile) else: - self.model.add(title, profile) + return + else: + self.model.add(title, profile) self.clear() diff --git a/src/calibre/web/feeds/recipes/collection.py b/src/calibre/web/feeds/recipes/collection.py index a513cf3880..5dd360213b 100644 --- a/src/calibre/web/feeds/recipes/collection.py +++ b/src/calibre/web/feeds/recipes/collection.py @@ -108,7 +108,6 @@ def download_builtin_recipe(urn): br = browser() return br.open_novisit('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: @@ -127,6 +126,24 @@ def get_builtin_recipe_by_title(title, log=None, download_recipe=False): 'Failed to download recipe, using builtin version') return P('recipes/%s.recipe'%urn, data=True) +def get_builtin_recipe_by_id(id_, log=None, download_recipe=False): + for x in get_builtin_recipe_collection(): + if x.get('id') == id_: + 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): def __init__(self):