From 2dd5346104e33839f1fe166c95b0eb03b1bbd109 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Jan 2012 23:17:12 +0530 Subject: [PATCH] Tweak EPUB: Also allow tweaking of HTMLZ files (when both EPUB and HTMLZ are present, EPUB is preferred, can be changed via Preferences->Tweaks). --- resources/default_tweaks.py | 6 +++++ src/calibre/customize/builtins.py | 2 +- src/calibre/gui2/actions/tweak_epub.py | 36 +++++++++++++++++++------- src/calibre/gui2/dialogs/tweak_epub.py | 28 +++++++++++++++----- src/calibre/gui2/dialogs/tweak_epub.ui | 23 +++++++++++----- src/calibre/manual/conversion.rst | 2 +- 6 files changed, 71 insertions(+), 26 deletions(-) diff --git a/resources/default_tweaks.py b/resources/default_tweaks.py index c77bcf5228..7e2e9508ab 100644 --- a/resources/default_tweaks.py +++ b/resources/default_tweaks.py @@ -476,3 +476,9 @@ save_original_format = True # how many should be shown, here. gui_view_history_size = 15 +#: When using the 'Tweak Book' action, which format to prefer +# When tweaking a book that has multiple formats, calibre picks one +# automatically. By default EPUB is preferred to HTMLZ. If you would like to +# prefer HTMLZ to EPUB for tweaking, change this to 'htmlz' +tweak_book_prefer = 'epub' + diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index e576cf84ad..70032bb027 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -839,7 +839,7 @@ class ActionCopyToLibrary(InterfaceActionBase): class ActionTweakEpub(InterfaceActionBase): name = 'Tweak ePub' actual_plugin = 'calibre.gui2.actions.tweak_epub:TweakEpubAction' - description = _('Make small tweaks to epub files in your calibre library') + description = _('Make small tweaks to epub or htmlz files in your calibre library') class ActionNextMatch(InterfaceActionBase): name = 'Next Match' diff --git a/src/calibre/gui2/actions/tweak_epub.py b/src/calibre/gui2/actions/tweak_epub.py index d5ee346d31..02fc327f38 100755 --- a/src/calibre/gui2/actions/tweak_epub.py +++ b/src/calibre/gui2/actions/tweak_epub.py @@ -10,12 +10,13 @@ import os from calibre.gui2 import error_dialog from calibre.gui2.actions import InterfaceAction from calibre.gui2.dialogs.tweak_epub import TweakEpub +from calibre.utils.config import tweaks class TweakEpubAction(InterfaceAction): name = 'Tweak ePub' - action_spec = (_('Tweak ePub'), 'trim.png', - _('Make small changes to ePub format books'), + action_spec = (_('Tweak Book'), 'trim.png', + _('Make small changes to ePub or HTMLZ format books'), _('T')) dont_add_to = frozenset(['context-menu-device']) action_type = 'current' @@ -26,33 +27,48 @@ class TweakEpubAction(InterfaceAction): def edit_epub_in_situ(self, *args): row = self.gui.library_view.currentIndex() if not row.isValid(): - return error_dialog(self.gui, _('Cannot tweak ePub'), + return error_dialog(self.gui, _('Cannot tweak Book'), _('No book selected'), show=True) - # Confirm 'EPUB' in formats book_id = self.gui.library_view.model().id(row) + + # Confirm 'EPUB' in formats try: path_to_epub = self.gui.library_view.model().db.format( book_id, 'EPUB', index_is_id=True, as_path=True) except: path_to_epub = None - if not path_to_epub: - return error_dialog(self.gui, _('Cannot tweak ePub'), - _('No ePub available. First convert the book to ePub.'), + # Confirm 'HTMLZ' in formats + try: + path_to_htmlz = self.gui.library_view.model().db.format( + book_id, 'HTMLZ', index_is_id=True, as_path=True) + except: + path_to_htmlz = None + + if not path_to_epub and not path_to_htmlz: + return error_dialog(self.gui, _('Cannot tweak Book'), + _('The book must be in ePub or HTMLZ format to tweak.' + '\n\nFirst convert the book to ePub or HTMLZ.'), show=True) # Launch modal dialog waiting for user to tweak or cancel - dlg = TweakEpub(self.gui, path_to_epub) + if tweaks['tweak_book_prefer'] == 'htmlz': + path_to_book = path_to_htmlz or path_to_epub + else: + path_to_book = path_to_epub or path_to_htmlz + + dlg = TweakEpub(self.gui, path_to_book) if dlg.exec_() == dlg.Accepted: self.update_db(book_id, dlg._output) dlg.cleanup() - os.remove(path_to_epub) + os.remove(path_to_book) def update_db(self, book_id, rebuilt): ''' Update the calibre db with the tweaked epub ''' - self.gui.library_view.model().db.add_format(book_id, 'EPUB', + fmt = os.path.splitext(rebuilt)[1][1:].upper() + self.gui.library_view.model().db.add_format(book_id, fmt, open(rebuilt, 'rb'), index_is_id=True) diff --git a/src/calibre/gui2/dialogs/tweak_epub.py b/src/calibre/gui2/dialogs/tweak_epub.py index e0be9fa1e9..503b1f45d3 100755 --- a/src/calibre/gui2/dialogs/tweak_epub.py +++ b/src/calibre/gui2/dialogs/tweak_epub.py @@ -7,6 +7,7 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' import os, shutil +from itertools import repeat, izip from calibre.utils.zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED from PyQt4.Qt import QDialog @@ -30,9 +31,20 @@ class TweakEpub(QDialog, Ui_Dialog): self._epub = epub self._exploded = None self._output = None + self.ishtmlz = epub.lower().endswith('.htmlz') + self.rebuilt_name = 'rebuilt.' + ('htmlz' if self.ishtmlz else 'epub') # Run the dialog setup generated from tweak_epub.ui self.setupUi(self) + for x, props in [(self, ['windowTitle']), (self.label, ['text'])]+\ + list(izip([self.cancel_button, self.explode_button, + self.rebuild_button, self.preview_button], + repeat(['text', 'statusTip', 'toolTip']))): + for prop in props: + val = unicode(getattr(x, prop)()) + val = val.format('HTMLZ' if self.ishtmlz else 'ePub') + prop = 'set' + prop[0].upper() + prop[1:] + getattr(x, prop)(val) self.cancel_button.clicked.connect(self.reject) self.explode_button.clicked.connect(self.explode) @@ -83,9 +95,11 @@ class TweakEpub(QDialog, Ui_Dialog): def do_rebuild(self, src): with ZipFile(src, 'w', compression=ZIP_DEFLATED) as zf: # Write mimetype - zf.write(os.path.join(self._exploded,'mimetype'), 'mimetype', compress_type=ZIP_STORED) + mt = os.path.join(self._exploded, 'mimetype') + if os.path.exists(mt): + zf.write(mt, 'mimetype', compress_type=ZIP_STORED) # Write everything else - exclude_files = ['.DS_Store','mimetype','iTunesMetadata.plist','rebuilt.epub'] + exclude_files = ['.DS_Store','mimetype','iTunesMetadata.plist',self.rebuilt_name] for root, dirs, files in os.walk(self._exploded): for fn in files: if fn in exclude_files: @@ -97,11 +111,11 @@ class TweakEpub(QDialog, Ui_Dialog): def preview(self): if not self._exploded: - return error_dialog(self, _('Cannot preview'), - _('You must first explode the epub before previewing.'), - show=True) + msg = _('You must first explode the %s before previewing.') + msg = msg%('HTMLZ' if self.ishtmlz else 'ePub') + return error_dialog(self, _('Cannot preview'), msg, show=True) - tf = PersistentTemporaryFile('.epub') + tf = PersistentTemporaryFile('.htmlz' if self.ishtmlz else '.epub') tf.close() self._preview_files.append(tf.name) @@ -110,7 +124,7 @@ class TweakEpub(QDialog, Ui_Dialog): self.gui.iactions['View']._view_file(tf.name) def rebuild(self, *args): - self._output = os.path.join(self._exploded, 'rebuilt.epub') + self._output = os.path.join(self._exploded, self.rebuilt_name) self.do_rebuild(self._output) return QDialog.accept(self) diff --git a/src/calibre/gui2/dialogs/tweak_epub.ui b/src/calibre/gui2/dialogs/tweak_epub.ui index a59af4fde1..9f14a1b275 100644 --- a/src/calibre/gui2/dialogs/tweak_epub.ui +++ b/src/calibre/gui2/dialogs/tweak_epub.ui @@ -14,7 +14,7 @@ - Tweak ePub + Tweak {0} false @@ -26,7 +26,7 @@ - <p>Explode the ePub to display contents in a file browser window. To tweak individual files, right-click, then 'Open with...' your editor of choice. When tweaks are complete, close the file browser window <b>and the editor windows you used to edit files in the epub</b>.</p><p>Rebuild the ePub, updating your calibre library.</p> + <p>Explode the {0} to display contents in a file browser window. To tweak individual files, right-click, then 'Open with...' your editor of choice. When tweaks are complete, close the file browser window <b>and the editor windows you used to edit files in the ePub</b>.</p><p>Rebuild the ePub, updating your calibre library.</p> true @@ -35,11 +35,14 @@ + + Display contents of exploded {0} + - Display contents of exploded ePub + Display contents of exploded {0} - &Explode ePub + &Explode {0} @@ -49,6 +52,9 @@ + + Discard changes + Discard changes @@ -66,11 +72,14 @@ false + + Rebuild {0} from exploded contents + - Rebuild ePub from exploded contents + Rebuild {0} from exploded contents - &Rebuild ePub + &Rebuild {0} @@ -81,7 +90,7 @@ - &Preview ePub + &Preview {0} diff --git a/src/calibre/manual/conversion.rst b/src/calibre/manual/conversion.rst index 7ced74c70d..c37c1eafdb 100644 --- a/src/calibre/manual/conversion.rst +++ b/src/calibre/manual/conversion.rst @@ -323,7 +323,7 @@ remove all non-breaking-space entities, or may include false positive matches re tags, i.e. horizontal rules, and tags are exceptions. Horizontal rules can optionally be specified with styles, if you choose to add your own style be sure to include the 'width' setting, otherwise the style information will be discarded. Image tags can used, but |app| does not provide the ability to add the image during conversion, this must be done after the fact using - the 'Tweak Epub' feature, or Sigil. + the 'Tweak Book' feature, or Sigil. Example image tag (place the image within an 'Images' folder inside the epub after conversion):