Search & Replace wizard: Run the conversion to generate the markup for this wizard in a separate process, to avoid memory leaks and crashes

This commit is contained in:
Kovid Goyal 2012-04-16 14:31:10 +05:30
parent f690dab1ff
commit dd2d76a8df
2 changed files with 31 additions and 12 deletions

View File

@ -367,3 +367,17 @@ class EbookIterator(object):
for x in self.delete_on_exit: for x in self.delete_on_exit:
if os.path.exists(x): if os.path.exists(x):
os.remove(x) os.remove(x)
def get_preprocess_html(path_to_ebook, output):
from calibre.ebooks.conversion.preprocess import HTMLPreProcessor
iterator = EbookIterator(path_to_ebook)
iterator.__enter__(only_input_plugin=True)
preprocessor = HTMLPreProcessor(None, False)
with open(output, 'wb') as out:
for path in iterator.spine:
with open(path, 'rb') as f:
html = f.read().decode('utf-8', 'replace')
html = preprocessor(html, get_preprocess_html=True)
out.write(html.encode('utf-8'))
out.write(b'\n\n' + b'-'*80 + b'\n\n')

View File

@ -13,10 +13,10 @@ from PyQt4.QtGui import (QDialog, QWidget, QDialogButtonBox,
from calibre.gui2.convert.regex_builder_ui import Ui_RegexBuilder from calibre.gui2.convert.regex_builder_ui import Ui_RegexBuilder
from calibre.gui2.convert.xexp_edit_ui import Ui_Form as Ui_Edit from calibre.gui2.convert.xexp_edit_ui import Ui_Form as Ui_Edit
from calibre.gui2 import error_dialog, choose_files from calibre.gui2 import error_dialog, choose_files
from calibre.ebooks.oeb.iterator import EbookIterator
from calibre.ebooks.conversion.preprocess import HTMLPreProcessor
from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
from calibre.constants import iswindows from calibre.constants import iswindows
from calibre.utils.ipc.simple_worker import fork_job, WorkerError
from calibre.ptempfile import TemporaryFile
class RegexBuilder(QDialog, Ui_RegexBuilder): class RegexBuilder(QDialog, Ui_RegexBuilder):
@ -161,16 +161,21 @@ class RegexBuilder(QDialog, Ui_RegexBuilder):
return True return True
def open_book(self, pathtoebook): def open_book(self, pathtoebook):
self.iterator = EbookIterator(pathtoebook) with TemporaryFile('_prepprocess_gui') as tf:
self.iterator.__enter__(only_input_plugin=True) err_msg = _('Failed to generate markup for testing. Click '
text = [u''] '"Show Details" to learn more.')
preprocessor = HTMLPreProcessor(None, False) try:
for path in self.iterator.spine: fork_job('calibre.ebooks.oeb.iterator', 'get_preprocess_html',
with open(path, 'rb') as f: (pathtoebook, tf))
html = f.read().decode('utf-8', 'replace') except WorkerError as e:
html = preprocessor(html, get_preprocess_html=True) return error_dialog(self, _('Failed to generate preview'),
text.append(html) err_msg, det_msg=e.orig_tb, show=True)
self.preview.setPlainText('\n---\n'.join(text)) except:
import traceback
return error_dialog(self, _('Failed to generate preview'),
err_msg, det_msg=traceback.format_exc(), show=True)
with open(tf, 'rb') as f:
self.preview.setPlainText(f.read().decode('utf-8'))
def button_clicked(self, button): def button_clicked(self, button):
if button == self.button_box.button(QDialogButtonBox.Open): if button == self.button_box.button(QDialogButtonBox.Open):