From 9c8357c31bb5266a19c381e2bcb4c1f5bd8f3230 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 10 Jul 2014 09:54:37 +0530 Subject: [PATCH] =?UTF-8?q?Edit=20Book:=20Check=20Book:=20Add=20a=20check?= =?UTF-8?q?=20for=20manifest=20items=20missing=20href=20attributes.=20Fixe?= =?UTF-8?q?s=20#1339766=20[Validator=20gives=20error=20on=20=E2=80=9Chref?= =?UTF-8?q?=E2=80=9D=20attribute=20in=20manifest=20item=20for=20remote=20r?= =?UTF-8?q?esources](https://bugs.launchpad.net/calibre/+bug/1339766)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/calibre/ebooks/oeb/polish/check/opf.py | 42 ++++++++++++++++------ 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/calibre/ebooks/oeb/polish/check/opf.py b/src/calibre/ebooks/oeb/polish/check/opf.py index e3c3e66101..ea7ff1960a 100644 --- a/src/calibre/ebooks/oeb/polish/check/opf.py +++ b/src/calibre/ebooks/oeb/polish/check/opf.py @@ -62,6 +62,25 @@ class IncorrectToc(BaseError): self.HELP = _('The media type for the table of contents must be %s') % guess_type('a.ncx') BaseError.__init__(self, msg, name, lnum) +class NoHref(BaseError): + + HELP = _('This manifest entry has no href attribute. Either add the href attribute or remove the entry.') + INDIVIDUAL_FIX = _('Remove this manifest entry') + + def __init__(self, name, item_id, lnum): + BaseError.__init__(self, _('Item in manifest has no href attribute'), name, lnum) + self.item_id = item_id + + def __call__(self, container): + changed = False + for item in container.opf_xpath('/opf:package/opf:manifest/opf:item'): + if item.get('id', None) == self.item_id: + changed = True + container.remove_from_xml(item) + container.dirty(container.opf_name) + return changed + + class MissingHref(BaseError): HELP = _('A file listed in the manifest is missing, you should either remove' @@ -213,17 +232,20 @@ def check_opf(container): errors.append(NonLinearItems(container.opf_name, nl_items)) seen, dups = {}, {} - for item in container.opf_xpath('/opf:package/opf:manifest/opf:item[@href]'): - href = item.get('href') - hname = container.href_to_name(href, container.opf_name) - if not hname or not container.exists(hname): - errors.append(MissingHref(container.opf_name, href, item.sourceline)) - if href in seen: - if href not in dups: - dups[href] = [seen[href]] - dups[href].append(item.sourceline) + for item in container.opf_xpath('/opf:package/opf:manifest/opf:item'): + href = item.get('href', None) + if href is None: + errors.append(NoHref(container.opf_name, item.get('id', None), item.sourceline)) else: - seen[href] = item.sourceline + hname = container.href_to_name(href, container.opf_name) + if not hname or not container.exists(hname): + errors.append(MissingHref(container.opf_name, href, item.sourceline)) + if href in seen: + if href not in dups: + dups[href] = [seen[href]] + dups[href].append(item.sourceline) + else: + seen[href] = item.sourceline errors.extend(DuplicateHref(container.opf_name, eid, locs) for eid, locs in dups.iteritems()) seen, dups = {}, {}