From 931b26c8688f746fd9897355ed689e04744bdcc5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 24 Nov 2008 17:15:23 -0800 Subject: [PATCH] Add a button to easily customize builtin recipes --- setup.py | 15 +++++++- src/calibre/gui2/dialogs/user_profiles.py | 37 ++++++++++++++++++-- src/calibre/gui2/dialogs/user_profiles.ui | 42 +++++++++++++++++------ 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/setup.py b/setup.py index 35a2ae176d..37d54c4317 100644 --- a/setup.py +++ b/setup.py @@ -174,6 +174,16 @@ if __name__ == '__main__': max = mtime if mtime > max else max return resources, max + def get_recipes(self): + sdir = os.path.join('src', 'calibre', 'web', 'feeds', 'recipes') + resources, max = {}, 0 + for f in os.listdir(sdir): + if f.endswith('.py') and f != '__init__.py': + resources[f.replace('.py', '')] = open(os.path.join(sdir, f), 'rb').read() + mtime = os.stat(os.path.join(sdir, f)).st_mtime + max = mtime if mtime > max else max + return resources, max + def run(self): data, dest, RESOURCES = {}, self.DEST, self.RESOURCES for key in RESOURCES: @@ -183,13 +193,16 @@ if __name__ == '__main__': translations = self.get_qt_translations() RESOURCES.update(translations) static, smax = self.get_static_resources() - if newer([dest], RESOURCES.values()) or os.stat(dest).st_mtime < smax: + recipes, rmax = self.get_recipes() + amax = max(rmax, smax) + if newer([dest], RESOURCES.values()) or os.stat(dest).st_mtime < amax: print 'Compiling resources...' with open(dest, 'wb') as f: for key in RESOURCES: data = open(RESOURCES[key], 'rb').read() f.write(key + ' = ' + repr(data)+'\n\n') f.write('server_resources = %s\n\n'%repr(static)) + f.write('recipes = %s\n\n'%repr(recipes)) f.write('build_time = "%s"\n\n'%time.strftime('%d %m %Y %H%M%S')) else: print 'Resources are up to date' diff --git a/src/calibre/gui2/dialogs/user_profiles.py b/src/calibre/gui2/dialogs/user_profiles.py index a06191e48c..efb34239c0 100644 --- a/src/calibre/gui2/dialogs/user_profiles.py +++ b/src/calibre/gui2/dialogs/user_profiles.py @@ -10,8 +10,7 @@ from calibre.web.feeds.news import AutomaticNewsRecipe from calibre.gui2.dialogs.user_profiles_ui import Ui_Dialog from calibre.gui2 import qstring_to_unicode, error_dialog, question_dialog, choose_files from calibre.gui2.widgets import PythonHighlighter -from calibre.ptempfile import PersistentTemporaryFile -from calibre import isosx +from calibre.ptempfile import PersistentTemporaryFile class UserProfiles(QDialog, Ui_Dialog): @@ -27,6 +26,7 @@ class UserProfiles(QDialog, Ui_Dialog): self.connect(self.add_feed_button, SIGNAL('clicked(bool)'), self.add_feed) self.connect(self.load_button, SIGNAL('clicked()'), self.load) + self.connect(self.builtin_recipe_button, SIGNAL('clicked()'), self.add_builtin_recipe) self.connect(self.share_button, SIGNAL('clicked()'), self.share) self.connect(self.down_button, SIGNAL('clicked()'), self.down) self.connect(self.up_button, SIGNAL('clicked()'), self.up) @@ -184,6 +184,39 @@ class %(classname)s(%(base_class)s): return self.clear() + def add_builtin_recipe(self): + from calibre.web.feeds.recipes import recipes, recipe_modules, english_sort + from calibre.resources import recipes as rdat + from PyQt4.Qt import QInputDialog + + class Recipe(object): + def __init__(self, title, id, recipes): + self.title = title + self.id = id + self.text = recipes[id] + def __cmp__(self, other): + return english_sort(self.title, other.title) + + recipes = sorted([Recipe(r.title, i, rdat) for r, i in zip(recipes, recipe_modules)]) + items = [r.title for r in recipes] + title, ok = QInputDialog.getItem(self, _('Pick recipe'), _('Pick the recipe to customize'), + items, 0, False) + if ok: + for r in recipes: + if r.title == unicode(title): + try: + self.available_profiles.add_item(title, (title, r.text), replace=False) + except ValueError: + d = question_dialog(self, _('Replace recipe?'), + _('A custom recipe named %s already exists. Do you want to replace it?')%title) + if d.exec_() == QMessageBox.Yes: + self.available_profiles.add_item(title, (title, r.text), replace=True) + else: + return + self.clear() + break + + def load(self): files = choose_files(self, 'recipe loader dialog', _('Choose a recipe file'), filters=[(_('Recipes'), '*.py')], all_files=False, select_only_single_file=True) if files: diff --git a/src/calibre/gui2/dialogs/user_profiles.ui b/src/calibre/gui2/dialogs/user_profiles.ui index b41c9c0165..74a9891caf 100644 --- a/src/calibre/gui2/dialogs/user_profiles.ui +++ b/src/calibre/gui2/dialogs/user_profiles.ui @@ -5,7 +5,7 @@ 0 0 - 703 + 744 633 @@ -13,7 +13,8 @@ Add custom news source - :/images/user_profile.svg + + :/images/user_profile.svg:/images/user_profile.svg @@ -22,7 +23,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -64,7 +65,8 @@ Add/Update &recipe - :/images/plus.svg + + :/images/plus.svg:/images/plus.svg @@ -74,7 +76,8 @@ &Remove recipe - :/images/list_remove.svg + + :/images/list_remove.svg:/images/list_remove.svg @@ -84,7 +87,19 @@ &Share recipe - :/images/forward.svg + + :/images/forward.svg:/images/forward.svg + + + + + + + Customize &builtin recipe + + + + :/images/news.svg:/images/news.svg @@ -94,7 +109,8 @@ &Load recipe from file - :/images/chapters.svg + + :/images/chapters.svg:/images/chapters.svg @@ -232,7 +248,8 @@ p, li { white-space: pre-wrap; } ... - :/images/arrow-up.svg + + :/images/arrow-up.svg:/images/arrow-up.svg @@ -245,7 +262,8 @@ p, li { white-space: pre-wrap; } ... - :/images/list_remove.svg + + :/images/list_remove.svg:/images/list_remove.svg @@ -255,7 +273,8 @@ p, li { white-space: pre-wrap; } ... - :/images/arrow-down.svg + + :/images/arrow-down.svg:/images/arrow-down.svg @@ -305,7 +324,8 @@ p, li { white-space: pre-wrap; } &Add feed - :/images/plus.svg + + :/images/plus.svg:/images/plus.svg