Automatic fixing of errors

This commit is contained in:
Kovid Goyal 2013-12-09 12:51:03 +05:30
parent bbdadc6ab1
commit 089a76662f
4 changed files with 42 additions and 5 deletions

View File

@ -13,12 +13,13 @@ from calibre.ebooks.oeb.polish.container import guess_type
from calibre.ebooks.oeb.polish.check.base import run_checkers
from calibre.ebooks.oeb.polish.check.parsing import check_xml_parsing
XML_TYPES = frozenset(map(guess_type, ('a.xml', 'a.svg', 'a.opf', 'a.ncx')))
def run_checks(container):
errors = []
# Check parsing
XML_TYPES = frozenset(map(guess_type, ('a.xml', 'a.svg', 'a.opf', 'a.ncx')))
xml_items, html_items = [], []
for name, mt in container.mime_map.iteritems():
items = None
@ -33,3 +34,9 @@ def run_checks(container):
return errors
def fix_errors(container, errors):
# Fix parsing
for name in {e.name for e in errors if getattr(e, 'is_parsing_error', False)}:
container.parsed(name)
container.dirty(name)

View File

@ -13,6 +13,8 @@ from calibre.ebooks.oeb.base import OEB_DOCS
class XMLParseError(BaseError):
is_parsing_error = True
HELP = _('A parsing error in an XML file means that the XML syntax in the file is incorrect.'
' Such a file will most probably not open in an ebook reader. These errors can '
' usually be fixed automatically, however, automatic fixing can sometimes '

View File

@ -94,6 +94,7 @@ class Boss(QObject):
self.gui.preview.link_clicked.connect(self.link_clicked)
self.gui.check_book.item_activated.connect(self.check_item_activated)
self.gui.check_book.check_requested.connect(self.check_requested)
self.gui.check_book.fix_requested.connect(self.fix_requested)
def preferences(self):
p = Preferences(self.gui)
@ -703,6 +704,17 @@ class Boss(QObject):
c.parent().raise_()
c.run_checks(current_container())
@in_thread_job
def fix_requested(self):
self.commit_all_editors_to_container()
self.add_savepoint(_('Auto-fix errors'))
c = self.gui.check_book
c.parent().show()
c.parent().raise_()
c.fix_errors(current_container())
self.apply_container_update_to_gui()
self.set_modified()
@in_thread_job
def merge_requested(self, category, names, master):
self.commit_all_editors_to_container()

View File

@ -13,7 +13,7 @@ from PyQt4.Qt import (
QListWidgetItem, pyqtSignal, QApplication, QStyledItemDelegate)
from calibre.ebooks.oeb.polish.check.base import WARN, INFO, DEBUG, ERROR, CRITICAL
from calibre.ebooks.oeb.polish.check.main import run_checks
from calibre.ebooks.oeb.polish.check.main import run_checks, fix_errors
from calibre.gui2.tweak_book import tprefs
def icon_for_level(level):
@ -39,6 +39,7 @@ class Check(QSplitter):
item_activated = pyqtSignal(object)
check_requested = pyqtSignal()
fix_requested = pyqtSignal()
def __init__(self, parent=None):
QSplitter.__init__(self, parent)
@ -77,6 +78,8 @@ class Check(QSplitter):
self.current_item_activated()
elif url == 'run:check':
self.check_requested.emit()
elif url == 'fix:errors':
self.fix_requested.emit()
def next_error(self, delta=1):
row = self.items.currentRow()
@ -106,10 +109,14 @@ class Check(QSplitter):
if loc:
loc = ' (%s)' % loc
self.help.setText(
'''<h2 style="text-align:center">%s</h2>
<div><a style="text-decoration:none" href="activate:item" title="%s">%s %s</a></div>
'''<style>a { text-decoration: none}</style><h2>%s [%d]</h2>
<div><a href="activate:item" title="%s">%s %s</a></div>
<p>%s</p>
''' % (header, _('Click to open in editor'), err.name, loc, err.HELP))
<div><a href="fix:errors" title="%s">%s</a><br><br>
<a href="run:check" title="%s">%s</a></div>
''' % (header, self.items.currentRow()+1, _('Click to open in editor'), err.name, loc, err.HELP,
_('Try to fix all errors automatically. Only works for some types of error.'), _('Try fixing errors automatically'),
_('Re-run the check'), _('Re-run check')))
def run_checks(self, container):
from calibre.gui2.tweak_book.boss import BusyCursor
@ -130,6 +137,15 @@ class Check(QSplitter):
else:
self.clear_help(_('No problems found'))
def fix_errors(self, container):
from calibre.gui2.tweak_book.boss import BusyCursor
with BusyCursor():
errors = [self.items.item(i).data(Qt.UserRole).toPyObject() for i in xrange(self.items.count())]
self.show_busy(_('Running fixers, please wait...'))
QApplication.processEvents()
fix_errors(container, errors)
self.run_checks(container)
def show_busy(self, msg=_('Running checks, please wait...')):
self.help.setText(msg)
self.items.clear()