def __init__(self, name, eid, locs): BaseError.__init__(self, _('Duplicate id: %s') % eid, name) self.HELP = _( 'The id {0} is present on more than one element in {1}. This is' ' not allowed. Remove the id from all but one of the elements').format(eid, name) self.all_locations = [(name, lnum, None) for lnum in sorted(locs)] self.duplicate_id = eid
def __init__(self, msg, *args, **kwargs): msg = msg or '' BaseError.__init__(self, 'Parsing failed: ' + msg, *args, **kwargs) m = mismatch_pat.search(msg) if m is not None: self.has_multiple_locations = True self.all_locations = [(self.name, int(m.group(1)), None), (self.name, self.line, self.col)]
def __init__(self, link_source, link_dest, link_elem, fragment): BaseError.__init__(self, _('Link points to a location not present in the target file'), link_source, line=link_elem.sourceline) self.bad_href = link_elem.get('href') self.HELP = _('The link "{0}" points to a location <i>{1}</i> in the file {2} that does not exist.' ' You should either remove the location so that the link points to the top of the file,' ' or change the link to point to the correct location.').format( self.bad_href, fragment, link_dest)
def __init__(self, name, namespace): BaseError.__init__(self, _('Invalid or missing namespace'), name) self.HELP = prepare_string_for_xml(_( 'This file has {0}. Its namespace must be {1}. Set the namespace by defining the xmlns' ' attribute on the <html> element, like this <html xmlns="{1}">').format( (_('incorrect namespace %s') % namespace) if namespace else _('no namespace'), XHTML_NS))
def __init__(self, font_name, css_name, name, line): BaseError.__init__(self, _('The CSS font-family name {0} does not match the actual font name {1}').format(css_name, font_name), name, line) self.HELP = _('The font family name specified in the CSS @font-face rule: "{0}" does' ' not match the font name inside the actual font file: "{1}". This can' ' cause problems in some viewers. You should change the CSS font name' ' to match the actual font name.').format(css_name, font_name) self.INDIVIDUAL_FIX = _('Change the font name {0} to {1} everywhere').format(css_name, font_name) self.font_name, self.css_name = font_name, css_name
def __init__(self, name, lnum, bad_idref=None, bad_mimetype=None): if bad_idref is not None: msg = _('The item identified as the Table of Contents (%s) does not exist') % bad_idref self.HELP = _('There is no item with id="%s" in the manifest.') % bad_idref else: msg = _('The item identified as the Table of Contents has an incorrect media-type (%s)') % bad_mimetype self.HELP = _('The media type for the table of contents must be %s') % guess_type('a.ncx') BaseError.__init__(self, msg, name, lnum)
def __init__(self, name, line, eid): BaseError.__init__(self, _('Invalid id: %s') % eid, name, line) self.HELP = _( 'The id {0} is not a valid id. IDs must start with a letter ([A-Za-z]) and may be' ' followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_")' ', colons (":"), and periods ("."). This is to ensure maximum compatibility' ' with a wide range of devices.').format(eid) self.invalid_id = eid
def __init__(self, link_source, link_dest, link_elem): BaseError.__init__(self, _('Link points to a file that is not a text document'), link_source, line=link_elem.sourceline) self.HELP = _('The link "{0}" points to a file <i>{1}</i> that is not a text (HTML) document.' ' Many ebook readers will be unable to follow such a link. You should' ' either remove the link or change it to point to a text document.' ' For example, if it points to an image, you can create small wrapper' ' document that contains the image and change the link to point to that.').format( link_elem.get('href'), link_dest) self.bad_href = link_elem.get('href')
def __init__(self, container, name, opf_mt, ext_mt): self.opf_mt, self.ext_mt = opf_mt, ext_mt self.file_name = name BaseError.__init__(self, _('The file %s has a mimetype that does not match its extension') % name, container.opf_name) ext = name.rpartition('.')[-1] self.HELP = _('The file {0} has its mimetype specified as {1} in the OPF file.' ' The recommended mimetype for files with the extension "{2}" is {3}.' ' You should change either the file extension or the mimetype in the OPF.').format( name, opf_mt, ext, ext_mt) self.INDIVIDUAL_FIX = _('Change the mimetype for this file in the OPF to %s') % ext_mt
def __init__(self, name, eid, locs, for_spine=False): loc = 'spine' if for_spine else 'manifest' BaseError.__init__(self, _('Duplicate item in {0}: {1}').format(loc, eid), name) self.HELP = _( 'The item {0} is present more than once in the {2} in {1}. This is' ' not allowed.').format(eid, name, loc) self.all_locations = [(name, lnum, None) for lnum in sorted(locs)] self.duplicate_href = eid self.xpath = '/opf:package/opf:' + ('spine/opf:itemref[@idref]' if for_spine else 'manifest/opf:item[@href]') self.attr = 'idref' if for_spine else 'href'
def __init__(self, name, enc): BaseError.__init__(self, _("Non UTF-8 encoding declaration"), name) self.HELP = ( _( "This file has its encoding declared as %s. Some" " reader software cannot handle non-UTF8 encoded files." " You should change the encoding to UTF-8." ) % enc )
def __init__(self, name, iid, mt, lnum, opf_name): BaseError.__init__(self, _('Incorrect media-type for spine item'), opf_name, lnum) self.HELP = _( 'The item {0} present in the spine has the media-type {1}. ' ' Most ebook software cannot handle non-HTML spine items. ' ' If the item is actually HTML, you should change its media-type to {2}.' ' If it is not-HTML you should consider replacing it with an HTML item, as it' ' is unlikely to work in most readers.').format(name, mt, XHTML_MIME) if iid is not None: self.INDIVIDUAL_FIX = _('Change the media-type to %s') % XHTML_MIME self.iid = iid
def __init__(self, name): BaseError.__init__(self, _('Filename contains unsafe characters'), name) qname = urlquote(name) self.sname = make_filename_safe(name) self.HELP = _( 'The filename {0} contains unsafe characters, that must be escaped, like' ' this {1}. This can cause problems with some e-book readers. To be' ' absolutely safe, use only the English alphabet [a-z], the numbers [0-9],' ' underscores and hyphens in your file names. While many other characters' ' are allowed, they may cause problems with some software.').format(name, qname) self.INDIVIDUAL_FIX = _( 'Rename the file {0} to {1}').format(name, self.sname)
def __init__(self, name): from calibre.utils.filenames import ascii_filename BaseError.__init__(self, _('Filename contains unsafe characters'), name) qname = urlquote(name) def esc(n): return ''.join(x if x in URL_SAFE else '_' for x in n) self.sname = '/'.join(esc(ascii_filename(x)) for x in name.split('/')) self.HELP = _( 'The filename {0} contains unsafe characters, that must be escaped, like' ' this {1}. This can cause problems with some ebook readers. To be' ' absolutely safe, use only the English alphabet [a-z], the numbers [0-9],' ' underscores and hyphens in your file names. While many other characters' ' are allowed, they may cause problems with some software.').format(name, qname) self.INDIVIDUAL_FIX = _( 'Rename the file {0} to {1}').format(name, self.sname)
def __init__(self, level, msg, name, line, col): self.level = level prefix = 'CSS: ' BaseError.__init__(self, prefix + msg, name, line, col) if level == WARN: self.HELP = _('This CSS construct is not recognized. That means that it' ' most likely will not work on reader devices. Consider' ' replacing it with something else.') else: self.HELP = _('Some reader programs are very' ' finicky about CSS stylesheets and will ignore the whole' ' sheet if there is an error. These errors can often' ' be fixed automatically, however, automatic fixing will' ' typically remove unrecognized items, instead of correcting them.') self.INDIVIDUAL_FIX = _('Try to fix parsing errors in this stylesheet automatically')
def __init__(self, container, name, opf_mt, ext_mt): self.opf_mt, self.ext_mt = opf_mt, ext_mt self.file_name = name BaseError.__init__( self, _("The file %s has a mimetype that does not match its extension") % name, container.opf_name ) ext = name.rpartition(".")[-1] self.HELP = _( "The file {0} has its mimetype specified as {1} in the OPF file." ' The recommended mimetype for files with the extension "{2}" is {3}.' " You should change either the file extension or the mimetype in the OPF." ).format(name, opf_mt, ext, ext_mt) if opf_mt in OEB_DOCS and name in {n for n, l in container.spine_names}: self.INDIVIDUAL_FIX = _("Change the file extension to .xhtml") self.change_ext_to = "xhtml" else: self.INDIVIDUAL_FIX = _("Change the mimetype for this file in the OPF to %s") % ext_mt self.change_ext_to = None
def __init__(self, container, name, opf_mt, ext_mt): self.opf_mt, self.ext_mt = opf_mt, ext_mt self.file_name = name BaseError.__init__( self, _('The file %s has a mimetype that does not match its extension') % name, container.opf_name) ext = name.rpartition('.')[-1] self.HELP = _( 'The file {0} has its mimetype specified as {1} in the OPF file.' ' The recommended mimetype for files with the extension "{2}" is {3}.' ' You should change either the file extension or the mimetype in the OPF.' ).format(name, opf_mt, ext, ext_mt) if opf_mt in OEB_DOCS and name in { n for n, l in container.spine_names }: self.INDIVIDUAL_FIX = _('Change the file extension to .xhtml') self.change_ext_to = 'xhtml' else: self.INDIVIDUAL_FIX = _( 'Change the mimetype for this file in the OPF to %s') % ext_mt self.change_ext_to = None
def __init__(self, name, enc): BaseError.__init__(self, _('Non UTF-8 encoding declaration'), name) self.HELP = _('This file has its encoding declared as %s. Some' ' reader software cannot handle non-UTF8 encoded files.' ' You should change the encoding to UTF-8.') % enc
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 __init__(self, ent, name, lnum, col): BaseError.__init__(self, _('Invalid entity: %s') % ent, name, lnum, col)
def __init__(self, name, idref, lnum): BaseError.__init__(self, _('idref="%s" points to unknown id') % idref, name, lnum) self.HELP = xml(_( 'The idref="%s" points to an id that does not exist in the OPF') % idref)
def __init__(self, msg, *args, **kwargs): BaseError.__init__(self, 'Invalid image: ' + msg, *args, **kwargs)
def __init__(self, name): BaseError.__init__(self, _('The file %s is empty') % name, name)
def __init__(self, name): BaseError.__init__(self, _('Parsing of %s failed, could not decode') % name, name)
def __init__(self, name, lnum): BaseError.__init__(self, _('Empty identifier element'), name, lnum)
def __init__(self, name, section_name): BaseError.__init__(self, _('The <%s> section is missing from the OPF') % section_name, name) self.HELP = xml(_( 'The <%s> section is required in the OPF file. You have to create one.') % section_name)
def __init__(self, name, href, lnum): BaseError.__init__(self, _('Item (%s) in manifest is missing') % href, name, lnum) self.bad_href = href self.INDIVIDUAL_FIX = _('Remove the entry for %s from the manifest') % href
def __init__(self, name, lnum): BaseError.__init__(self, _('Missing ToC in navigation document'), name, lnum)
def __init__(self, name, lnum, ncx_id): BaseError.__init__(self, _('Missing reference to the NCX Table of Contents'), name, lnum) self.ncx_id = ncx_id
def __init__(self, name, lines): BaseError.__init__(self, _('Bare text in body tag'), name) self.all_locations = [(name, l, None) for l in sorted(lines)]
def __init__(self, name): BaseError.__init__(self, _('Named entities present'), name)
def __init__(self, name, locs): BaseError.__init__(self, _('There is more than one cover defined'), name) self.all_locations = [(name, lnum, None) for lnum in sorted(locs)]
def check_opf(container): errors = [] opf_version = container.opf_version_parsed if container.opf.tag != OPF('package'): err = BaseError(_('The OPF does not have the correct root element'), container.opf_name, container.opf.sourceline) err.HELP = xml(_( 'The opf must have the root element <package> in namespace {0}, like this: <package xmlns="{0}">')).format(OPF2_NS) errors.append(err) elif container.opf.get('version') is None and container.book_type == 'epub': err = BaseError(_('The OPF does not have a version'), container.opf_name, container.opf.sourceline) err.HELP = xml(_( 'The <package> tag in the OPF must have a version attribute. This is usually version="2.0" for EPUB2 and AZW3 and version="3.0" for EPUB3')) errors.append(err) for tag in ('metadata', 'manifest', 'spine'): if not container.opf_xpath('/opf:package/opf:' + tag): errors.append(MissingSection(container.opf_name, tag)) all_ids = set(container.opf_xpath('//*/@id')) for elem in container.opf_xpath('//*[@idref]'): if elem.get('idref') not in all_ids: errors.append(IncorrectIdref(container.opf_name, elem.get('idref'), elem.sourceline)) nl_items = [elem.sourceline for elem in container.opf_xpath('//opf:spine/opf:itemref[@linear="no"]')] if nl_items: errors.append(NonLinearItems(container.opf_name, nl_items)) seen, dups = {}, {} 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: 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 = {}, {} for item in container.opf_xpath('/opf:package/opf:spine/opf:itemref[@idref]'): ref = item.get('idref') if ref in seen: if ref not in dups: dups[ref] = [seen[ref]] dups[ref].append(item.sourceline) else: seen[ref] = item.sourceline errors.extend(DuplicateHref(container.opf_name, eid, locs, for_spine=True) for eid, locs in dups.iteritems()) spine = container.opf_xpath('/opf:package/opf:spine[@toc]') if spine: spine = spine[0] mitems = [x for x in container.opf_xpath('/opf:package/opf:manifest/opf:item[@id]') if x.get('id') == spine.get('toc')] if mitems: mitem = mitems[0] if mitem.get('media-type', '') != guess_type('a.ncx'): errors.append(IncorrectToc(container.opf_name, mitem.sourceline, bad_mimetype=mitem.get('media-type'))) else: errors.append(IncorrectToc(container.opf_name, spine.sourceline, bad_idref=spine.get('toc'))) else: spine = container.opf_xpath('/opf:package/opf:spine') if spine: spine = spine[0] ncx = container.manifest_type_map.get(guess_type('a.ncx')) if ncx: ncx_name = ncx[0] rmap = {v:k for k, v in container.manifest_id_map.iteritems()} ncx_id = rmap.get(ncx_name) if ncx_id: errors.append(MissingNCXRef(container.opf_name, spine.sourceline, ncx_id)) if opf_version.major > 2: if find_existing_nav_toc(container) is None: errors.append(MissingNav(container.opf_name, 0)) covers = container.opf_xpath('/opf:package/opf:metadata/opf:meta[@name="cover"]') if len(covers) > 0: if len(covers) > 1: errors.append(MultipleCovers(container.opf_name, [c.sourceline for c in covers])) manifest_ids = set(container.opf_xpath('/opf:package/opf:manifest/opf:item/@id')) for cover in covers: if cover.get('content', None) not in manifest_ids: errors.append(IncorrectCover(container.opf_name, cover.sourceline, cover.get('content', ''))) raw = etree.tostring(cover) try: n, c = raw.index('name="'), raw.index('content="') except ValueError: n = c = -1 if n > -1 and c > -1 and n > c: errors.append(NookCover(container.opf_name, cover.sourceline)) uid = container.opf.get('unique-identifier', None) if uid is None or not container.opf_xpath('/opf:package/opf:metadata/dc:identifier[@id=%r]' % uid): errors.append(NoUID(container.opf_name)) for item, name, linear in container.spine_iter: mt = container.mime_map[name] if mt != XHTML_MIME: iid = item.get('idref', None) lnum = None if iid: mitem = container.opf_xpath('/opf:package/opf:manifest/opf:item[@id=%r]' % iid) if mitem: lnum = mitem[0].sourceline else: iid = None errors.append(BadSpineMime(name, iid, mt, lnum, container.opf_name)) return errors
def check_opf(container): errors = [] if container.opf.tag != OPF('package'): err = BaseError(_('The OPF does not have the correct root element'), container.opf_name) err.HELP = xml( _('The opf must have the root element <package> in namespace {0}, like this: <package xmlns="{0}">' )).format(OPF2_NS) errors.append(err) for tag in ('metadata', 'manifest', 'spine'): if not container.opf_xpath('/opf:package/opf:' + tag): errors.append(MissingSection(container.opf_name, tag)) all_ids = set(container.opf_xpath('//*/@id')) for elem in container.opf_xpath('//*[@idref]'): if elem.get('idref') not in all_ids: errors.append( IncorrectIdref(container.opf_name, elem.get('idref'), elem.sourceline)) nl_items = [ elem.sourceline for elem in container.opf_xpath( '//opf:spine/opf:itemref[@linear="no"]') ] if nl_items: 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') if not container.exists( container.href_to_name(href, container.opf_name)): 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 = {}, {} for item in container.opf_xpath( '/opf:package/opf:spine/opf:itemref[@idref]'): ref = item.get('idref') if ref in seen: if ref not in dups: dups[ref] = [seen[ref]] dups[ref].append(item.sourceline) else: seen[ref] = item.sourceline errors.extend( DuplicateHref(container.opf_name, eid, locs, for_spine=True) for eid, locs in dups.iteritems()) spine = container.opf_xpath('/opf:package/opf:spine[@toc]') if spine: spine = spine[0] mitems = [ x for x in container.opf_xpath( '/opf:package/opf:manifest/opf:item[@id]') if x.get('id') == spine.get('toc') ] if mitems: mitem = mitems[0] if mitem.get('media-type', '') != guess_type('a.ncx'): errors.append( IncorrectToc(container.opf_name, mitem.sourceline, bad_mimetype=mitem.get('media-type'))) else: errors.append( IncorrectToc(container.opf_name, spine.sourceline, bad_idref=spine.get('toc'))) covers = container.opf_xpath( '/opf:package/opf:metadata/opf:meta[@name="cover"]') if len(covers) > 0: if len(covers) > 1: errors.append( MultipleCovers(container.opf_name, [c.sourceline for c in covers])) manifest_ids = set( container.opf_xpath('/opf:package/opf:manifest/opf:item/@id')) for cover in covers: if cover.get('content', None) not in manifest_ids: errors.append( IncorrectCover(container.opf_name, cover.sourceline, cover.get('content', ''))) raw = etree.tostring(cover) try: n, c = raw.index('name="'), raw.index('content="') except ValueError: n = c = -1 if n > -1 and c > -1 and n > c: errors.append(NookCover(container.opf_name, cover.sourceline)) uid = container.opf.get('unique-identifier', None) if uid is None or not container.opf_xpath( '/opf:package/opf:metadata/dc:identifier[@id=%r]' % uid): errors.append(NoUID(container.opf_name)) for item, name, linear in container.spine_iter: mt = container.mime_map[name] if mt != XHTML_MIME: iid = item.get('idref', None) lnum = None if iid: mitem = container.opf_xpath( '/opf:package/opf:manifest/opf:item[@id=%r]' % iid) if mitem: lnum = mitem[0].sourceline else: iid = None errors.append(BadSpineMime(name, iid, mt, lnum, container.opf_name)) return errors
def __init__(self, name): BaseError.__init__(self, _('File too large'), name)
def __init__(self, name, fs_type): BaseError.__init__(self, _('The font {} is not allowed to be embedded').format(name), name) self.HELP = _('The font has a flag in its metadata ({:09b}) set indicating that it is' ' not licensed for embedding. You can ignore this warning, if you are' ' sure you have permission to embed this font.').format(fs_type)
def __init__(self, name, lnum, cover): BaseError.__init__(self, _('The meta cover tag points to an non-existent item'), name, lnum) self.HELP = xml(_( 'The meta cover tag points to an item with id="%s" which does not exist in the manifest') % cover)
def __init__(self, name, lnum): BaseError.__init__(self, _('The meta cover tag has content before name'), name, lnum)
def __init__(self, name, lnum): BaseError.__init__(self, _('Empty id attributes are invalid'), name, lnum) self.HELP = xml(_( 'Empty ID attributes are invalid in OPF files.'))
def __init__(self, msg, *args, **kwargs): BaseError.__init__(self, 'Parsing failed: ' + msg, *args, **kwargs)
def check_opf(container): errors = [] opf_version = container.opf_version_parsed if container.opf.tag != OPF('package'): err = BaseError(_('The OPF does not have the correct root element'), container.opf_name, container.opf.sourceline) err.HELP = xml(_( 'The opf must have the root element <package> in namespace {0}, like this: <package xmlns="{0}">')).format(OPF2_NS) errors.append(err) elif container.opf.get('version') is None and container.book_type == 'epub': err = BaseError(_('The OPF does not have a version'), container.opf_name, container.opf.sourceline) err.HELP = xml(_( 'The <package> tag in the OPF must have a version attribute. This is usually version="2.0" for EPUB2 and AZW3 and version="3.0" for EPUB3')) errors.append(err) for tag in ('metadata', 'manifest', 'spine'): if not container.opf_xpath('/opf:package/opf:' + tag): errors.append(MissingSection(container.opf_name, tag)) all_ids = set(container.opf_xpath('//*/@id')) if '' in all_ids: for empty_id_tag in container.opf_xpath('//*[@id=""]'): errors.append(EmptyID(container.opf_name, empty_id_tag.sourceline)) all_ids.discard('') for elem in container.opf_xpath('//*[@idref]'): if elem.get('idref') not in all_ids: errors.append(IncorrectIdref(container.opf_name, elem.get('idref'), elem.sourceline)) nl_items = [elem.sourceline for elem in container.opf_xpath('//opf:spine/opf:itemref[@linear="no"]')] if nl_items: errors.append(NonLinearItems(container.opf_name, nl_items)) seen, dups = {}, {} 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: 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 iteritems(dups)) seen, dups = {}, {} for item in container.opf_xpath('/opf:package/opf:spine/opf:itemref[@idref]'): ref = item.get('idref') if ref in seen: if ref not in dups: dups[ref] = [seen[ref]] dups[ref].append(item.sourceline) else: seen[ref] = item.sourceline errors.extend(DuplicateHref(container.opf_name, eid, locs, for_spine=True) for eid, locs in iteritems(dups)) spine = container.opf_xpath('/opf:package/opf:spine[@toc]') if spine: spine = spine[0] mitems = [x for x in container.opf_xpath('/opf:package/opf:manifest/opf:item[@id]') if x.get('id') == spine.get('toc')] if mitems: mitem = mitems[0] if mitem.get('media-type', '') != guess_type('a.ncx'): errors.append(IncorrectToc(container.opf_name, mitem.sourceline, bad_mimetype=mitem.get('media-type'))) else: errors.append(IncorrectToc(container.opf_name, spine.sourceline, bad_idref=spine.get('toc'))) else: spine = container.opf_xpath('/opf:package/opf:spine') if spine: spine = spine[0] ncx = container.manifest_type_map.get(guess_type('a.ncx')) if ncx: ncx_name = ncx[0] rmap = {v:k for k, v in iteritems(container.manifest_id_map)} ncx_id = rmap.get(ncx_name) if ncx_id: errors.append(MissingNCXRef(container.opf_name, spine.sourceline, ncx_id)) if opf_version.major > 2: existing_nav = find_existing_nav_toc(container) if existing_nav is None: errors.append(MissingNav(container.opf_name, 0)) else: toc = parse_nav(container, existing_nav) if len(toc) == 0: errors.append(EmptyNav(existing_nav, 0)) covers = container.opf_xpath('/opf:package/opf:metadata/opf:meta[@name="cover"]') if len(covers) > 0: if len(covers) > 1: errors.append(MultipleCovers(container.opf_name, [c.sourceline for c in covers])) manifest_ids = set(container.opf_xpath('/opf:package/opf:manifest/opf:item/@id')) for cover in covers: if cover.get('content', None) not in manifest_ids: errors.append(IncorrectCover(container.opf_name, cover.sourceline, cover.get('content', ''))) raw = etree.tostring(cover) try: n, c = raw.index(b'name="'), raw.index(b'content="') except ValueError: n = c = -1 if n > -1 and c > -1 and n > c: errors.append(NookCover(container.opf_name, cover.sourceline)) uid = container.opf.get('unique-identifier', None) if uid is None or not container.opf_xpath('/opf:package/opf:metadata/dc:identifier[@id=%r]' % uid): errors.append(NoUID(container.opf_name)) for elem in container.opf_xpath('/opf:package/opf:metadata/dc:identifier'): if not elem.text or not elem.text.strip(): errors.append(EmptyIdentifier(container.opf_name, elem.sourceline)) for item, name, linear in container.spine_iter: mt = container.mime_map[name] if mt != XHTML_MIME: iid = item.get('idref', None) lnum = None if iid: mitem = container.opf_xpath('/opf:package/opf:manifest/opf:item[@id=%r]' % iid) if mitem: lnum = mitem[0].sourceline else: iid = None errors.append(BadSpineMime(name, iid, mt, lnum, container.opf_name)) return errors
def __init__(self, name, locs): BaseError.__init__(self, _('Non-linear items in the spine'), name) self.all_locations = [(name, x, None) for x in locs]
def __init__(self, name): BaseError.__init__(self, _('The OPF has no unique identifier'), name)
def __init__(self, msg, *args, **kwargs): BaseError.__init__(self, 'Parsing failed: ' + msg, *args, **kwargs) m = mismatch_pat.search(msg) if m is not None: self.has_multiple_locations = True self.all_locations = [(self.name, int(m.group(1)), None), (self.name, self.line, self.col)]