mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add a button to easily customize builtin recipes
This commit is contained in:
parent
d1d6827ce9
commit
931b26c868
15
setup.py
15
setup.py
@ -174,6 +174,16 @@ if __name__ == '__main__':
|
|||||||
max = mtime if mtime > max else max
|
max = mtime if mtime > max else max
|
||||||
return resources, 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):
|
def run(self):
|
||||||
data, dest, RESOURCES = {}, self.DEST, self.RESOURCES
|
data, dest, RESOURCES = {}, self.DEST, self.RESOURCES
|
||||||
for key in RESOURCES:
|
for key in RESOURCES:
|
||||||
@ -183,13 +193,16 @@ if __name__ == '__main__':
|
|||||||
translations = self.get_qt_translations()
|
translations = self.get_qt_translations()
|
||||||
RESOURCES.update(translations)
|
RESOURCES.update(translations)
|
||||||
static, smax = self.get_static_resources()
|
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...'
|
print 'Compiling resources...'
|
||||||
with open(dest, 'wb') as f:
|
with open(dest, 'wb') as f:
|
||||||
for key in RESOURCES:
|
for key in RESOURCES:
|
||||||
data = open(RESOURCES[key], 'rb').read()
|
data = open(RESOURCES[key], 'rb').read()
|
||||||
f.write(key + ' = ' + repr(data)+'\n\n')
|
f.write(key + ' = ' + repr(data)+'\n\n')
|
||||||
f.write('server_resources = %s\n\n'%repr(static))
|
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'))
|
f.write('build_time = "%s"\n\n'%time.strftime('%d %m %Y %H%M%S'))
|
||||||
else:
|
else:
|
||||||
print 'Resources are up to date'
|
print 'Resources are up to date'
|
||||||
|
@ -10,8 +10,7 @@ from calibre.web.feeds.news import AutomaticNewsRecipe
|
|||||||
from calibre.gui2.dialogs.user_profiles_ui import Ui_Dialog
|
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 import qstring_to_unicode, error_dialog, question_dialog, choose_files
|
||||||
from calibre.gui2.widgets import PythonHighlighter
|
from calibre.gui2.widgets import PythonHighlighter
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre import isosx
|
|
||||||
|
|
||||||
class UserProfiles(QDialog, Ui_Dialog):
|
class UserProfiles(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
@ -27,6 +26,7 @@ class UserProfiles(QDialog, Ui_Dialog):
|
|||||||
self.connect(self.add_feed_button, SIGNAL('clicked(bool)'),
|
self.connect(self.add_feed_button, SIGNAL('clicked(bool)'),
|
||||||
self.add_feed)
|
self.add_feed)
|
||||||
self.connect(self.load_button, SIGNAL('clicked()'), self.load)
|
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.share_button, SIGNAL('clicked()'), self.share)
|
||||||
self.connect(self.down_button, SIGNAL('clicked()'), self.down)
|
self.connect(self.down_button, SIGNAL('clicked()'), self.down)
|
||||||
self.connect(self.up_button, SIGNAL('clicked()'), self.up)
|
self.connect(self.up_button, SIGNAL('clicked()'), self.up)
|
||||||
@ -184,6 +184,39 @@ class %(classname)s(%(base_class)s):
|
|||||||
return
|
return
|
||||||
self.clear()
|
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):
|
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)
|
files = choose_files(self, 'recipe loader dialog', _('Choose a recipe file'), filters=[(_('Recipes'), '*.py')], all_files=False, select_only_single_file=True)
|
||||||
if files:
|
if files:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>703</width>
|
<width>744</width>
|
||||||
<height>633</height>
|
<height>633</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -13,7 +13,8 @@
|
|||||||
<string>Add custom news source</string>
|
<string>Add custom news source</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon" >
|
<property name="windowIcon" >
|
||||||
<iconset resource="../images.qrc" >:/images/user_profile.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/user_profile.svg</normaloff>:/images/user_profile.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" >
|
<layout class="QGridLayout" >
|
||||||
<item row="1" column="0" >
|
<item row="1" column="0" >
|
||||||
@ -22,7 +23,7 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons" >
|
<property name="standardButtons" >
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -64,7 +65,8 @@
|
|||||||
<string>Add/Update &recipe</string>
|
<string>Add/Update &recipe</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/plus.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/plus.svg</normaloff>:/images/plus.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -74,7 +76,8 @@
|
|||||||
<string>&Remove recipe</string>
|
<string>&Remove recipe</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/list_remove.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/list_remove.svg</normaloff>:/images/list_remove.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -84,7 +87,19 @@
|
|||||||
<string>&Share recipe</string>
|
<string>&Share recipe</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/forward.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/forward.svg</normaloff>:/images/forward.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="builtin_recipe_button" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Customize &builtin recipe</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon" >
|
||||||
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/news.svg</normaloff>:/images/news.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -94,7 +109,8 @@
|
|||||||
<string>&Load recipe from file</string>
|
<string>&Load recipe from file</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/chapters.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/chapters.svg</normaloff>:/images/chapters.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -232,7 +248,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/arrow-up.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/arrow-up.svg</normaloff>:/images/arrow-up.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -245,7 +262,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/list_remove.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/list_remove.svg</normaloff>:/images/list_remove.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -255,7 +273,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/arrow-down.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/arrow-down.svg</normaloff>:/images/arrow-down.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -305,7 +324,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string>&Add feed</string>
|
<string>&Add feed</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon" >
|
||||||
<iconset resource="../images.qrc" >:/images/plus.svg</iconset>
|
<iconset resource="../images.qrc" >
|
||||||
|
<normaloff>:/images/plus.svg</normaloff>:/images/plus.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user