Ejemplo n.º 1
0
    def workaround_nook_cover_bug(self, root):  # {{{
        cov = root.xpath('//*[local-name() = "meta" and @name="cover" and'
                         ' @content != "cover"]')

        def manifest_items_with_id(id_):
            return root.xpath(
                '//*[local-name() = "manifest"]/*[local-name() = "item" '
                ' and @id="%s"]' % id_)

        if len(cov) == 1:
            cov = cov[0]
            covid = cov.get('content', '')

            if covid:
                manifest_item = manifest_items_with_id(covid)
                if len(manifest_item) == 1 and \
                        manifest_item[0].get('media-type',
                                '').startswith('image/'):
                    self.log.warn(
                        'The cover image has an id != "cover". Renaming'
                        ' to work around bug in Nook Color')

                    from calibre.ebooks.oeb.base import uuid_id
                    newid = uuid_id()

                    for item in manifest_items_with_id('cover'):
                        item.set('id', newid)

                    for x in root.xpath('//*[@idref="cover"]'):
                        x.set('idref', newid)

                    manifest_item = manifest_item[0]
                    manifest_item.set('id', 'cover')
                    cov.set('content', 'cover')
Ejemplo n.º 2
0
    def workaround_nook_cover_bug(self, root):  # {{{
        cov = root.xpath('//*[local-name() = "meta" and @name="cover" and'
                ' @content != "cover"]')

        def manifest_items_with_id(id_):
            return root.xpath('//*[local-name() = "manifest"]/*[local-name() = "item" '
                ' and @id="%s"]'%id_)

        if len(cov) == 1:
            cov = cov[0]
            covid = cov.get('content', '')

            if covid:
                manifest_item = manifest_items_with_id(covid)
                if len(manifest_item) == 1 and \
                        manifest_item[0].get('media-type',
                                '').startswith('image/'):
                    self.log.warn('The cover image has an id != "cover". Renaming'
                            ' to work around bug in Nook Color')

                    from calibre.ebooks.oeb.base import uuid_id
                    newid = uuid_id()

                    for item in manifest_items_with_id('cover'):
                        item.set('id', newid)

                    for x in root.xpath('//*[@idref="cover"]'):
                        x.set('idref', newid)

                    manifest_item = manifest_item[0]
                    manifest_item.set('id', 'cover')
                    cov.set('content', 'cover')
Ejemplo n.º 3
0
def commit_ncx_toc(container, toc, lang=None, uid=None):
    tocname = find_existing_ncx_toc(container)
    if tocname is None:
        item = container.generate_item('toc.ncx', id_prefix='toc')
        tocname = container.href_to_name(item.get('href'), base=container.opf_name)
        ncx_id = item.get('id')
        [s.set('toc', ncx_id) for s in container.opf_xpath('//opf:spine')]
    if not lang:
        lang = get_lang()
        for l in container.opf_xpath('//dc:language'):
            l = canonicalize_lang(xml2text(l).strip())
            if l:
                lang = l
                lang = lang_as_iso639_1(l) or l
                break
    lang = lang_as_iso639_1(lang) or lang
    if not uid:
        uid = uuid_id()
        eid = container.opf.get('unique-identifier', None)
        if eid:
            m = container.opf_xpath('//*[@id="%s"]'%eid)
            if m:
                uid = xml2text(m[0])

    title = _('Table of Contents')
    m = container.opf_xpath('//dc:title')
    if m:
        x = xml2text(m[0]).strip()
        title = x or title

    to_href = partial(container.name_to_href, base=tocname)
    root = create_ncx(toc, to_href, title, lang, uid)
    container.replace(tocname, root)
    container.pretty_print.add(tocname)
Ejemplo n.º 4
0
def commit_toc(container, toc, lang=None, uid=None):
    tocname = find_existing_toc(container)
    if tocname is None:
        item = container.generate_item("toc.ncx", id_prefix="toc")
        tocname = container.href_to_name(item.get("href"), base=container.opf_name)
    if not lang:
        lang = get_lang()
        for l in container.opf_xpath("//dc:language"):
            l = canonicalize_lang(xml2text(l).strip())
            if l:
                lang = l
                lang = lang_as_iso639_1(l) or l
                break
    lang = lang_as_iso639_1(lang) or lang
    if not uid:
        uid = uuid_id()
        eid = container.opf.get("unique-identifier", None)
        if eid:
            m = container.opf_xpath('//*[@id="%s"]' % eid)
            if m:
                uid = xml2text(m[0])

    title = _("Table of Contents")
    m = container.opf_xpath("//dc:title")
    if m:
        x = xml2text(m[0]).strip()
        title = x or title

    to_href = partial(container.name_to_href, base=tocname)
    root = create_ncx(toc, to_href, title, lang, uid)
    container.replace(tocname, root)
    container.pretty_print.add(tocname)
Ejemplo n.º 5
0
Archivo: toc.py Proyecto: tokot/calibre
def commit_toc(container, toc, lang=None, uid=None):
    tocname = find_existing_toc(container)
    if tocname is None:
        item = container.generate_item('toc.ncx', id_prefix='toc')
        tocname = container.href_to_name(item.get('href'),
                                         base=container.opf_name)
    if not lang:
        lang = get_lang()
        for l in container.opf_xpath('//dc:language'):
            l = canonicalize_lang(xml2text(l).strip())
            if l:
                lang = l
                lang = lang_as_iso639_1(l) or l
                break
    lang = lang_as_iso639_1(lang) or lang
    if not uid:
        uid = uuid_id()
        eid = container.opf.get('unique-identifier', None)
        if eid:
            m = container.opf_xpath('//*[@id="%s"]' % eid)
            if m:
                uid = xml2text(m[0])

    title = _('Table of Contents')
    m = container.opf_xpath('//dc:title')
    if m:
        x = xml2text(m[0]).strip()
        title = x or title

    to_href = partial(container.name_to_href, base=tocname)
    root = create_ncx(toc, to_href, title, lang, uid)
    container.replace(tocname, root)
    container.pretty_print.add(tocname)
Ejemplo n.º 6
0
def create_epub_cover(container, cover_path):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    ext = cover_path.rpartition('.')[-1].lower()
    raster_cover_item = container.generate_item('cover.'+ext, id_prefix='cover')
    raster_cover = container.href_to_name(raster_cover_item.get('href'),
                                          container.opf_name)
    with open(cover_path, 'rb') as src, container.open(raster_cover, 'wb') as dest:
        shutil.copyfileobj(src, dest)
    opts = load_defaults('epub_output')
    keep_aspect = opts.get('preserve_cover_aspect_ratio', False)
    no_svg = opts.get('no_svg_cover', False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace('__style__', style)
    else:
        width, height = 600, 800
        try:
            width, height = identify(cover_path)[:2]
        except:
            container.log.exception("Failed to get width and height of cover")
        ar = 'xMidYMid meet' if keep_aspect else 'none'
        templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar)
        templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height))
        templ = templ.replace('__width__', str(width))
        templ = templ.replace('__height__', str(height))
    titlepage_item = container.generate_item('titlepage.xhtml',
                                             id_prefix='titlepage')
    titlepage = container.href_to_name(titlepage_item.get('href'),
                                          container.opf_name)
    raw = templ%container.name_to_href(raster_cover).encode('utf-8')
    with container.open(titlepage, 'wb') as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get('id') != 'cover':
        from calibre.ebooks.oeb.base import uuid_id
        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set('id', newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set('idref', newid)
        raster_cover_item.set('id', 'cover')

    spine = container.opf_xpath('//opf:spine')[0]
    ref = spine.makeelement(OPF('itemref'), idref=titlepage_item.get('id'))
    container.insert_into_xml(spine, ref, index=0)
    guide = container.opf_get_or_create('guide')
    container.insert_into_xml(guide, guide.makeelement(
        OPF('reference'), type='cover', title=_('Cover'),
        href=container.name_to_href(titlepage, base=container.opf_name)))
    metadata = container.opf_get_or_create('metadata')
    meta = metadata.makeelement(OPF('meta'), name='cover')
    meta.set('content', raster_cover_item.get('id'))
    container.insert_into_xml(metadata, meta)

    return raster_cover, titlepage
Ejemplo n.º 7
0
def create_epub_cover(container, cover_path):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    ext = cover_path.rpartition('.')[-1].lower()
    raster_cover_item = container.generate_item('cover.'+ext, id_prefix='cover')
    raster_cover = container.href_to_name(raster_cover_item.get('href'),
                                          container.opf_name)
    with open(cover_path, 'rb') as src, container.open(raster_cover, 'wb') as dest:
        shutil.copyfileobj(src, dest)
    opts = load_defaults('epub_output')
    keep_aspect = opts.get('preserve_cover_aspect_ratio', False)
    no_svg = opts.get('no_svg_cover', False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace('__style__', style)
    else:
        width, height = 600, 800
        try:
            width, height = identify(cover_path)[:2]
        except:
            container.log.exception("Failed to get width and height of cover")
        ar = 'xMidYMid meet' if keep_aspect else 'none'
        templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar)
        templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height))
        templ = templ.replace('__width__', str(width))
        templ = templ.replace('__height__', str(height))
    titlepage_item = container.generate_item('titlepage.xhtml',
                                             id_prefix='titlepage')
    titlepage = container.href_to_name(titlepage_item.get('href'),
                                          container.opf_name)
    raw = templ%container.name_to_href(raster_cover).encode('utf-8')
    with container.open(titlepage, 'wb') as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get('id') != 'cover':
        from calibre.ebooks.oeb.base import uuid_id
        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set('id', newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set('idref', newid)
        raster_cover_item.set('id', 'cover')

    spine = container.opf_xpath('//opf:spine')[0]
    ref = spine.makeelement(OPF('itemref'), idref=titlepage_item.get('id'))
    container.insert_into_xml(spine, ref, index=0)
    guide = container.opf_get_or_create('guide')
    container.insert_into_xml(guide, guide.makeelement(
        OPF('reference'), type='cover', title=_('Cover'),
        href=container.name_to_href(titlepage, base=container.opf_name)))
    metadata = container.opf_get_or_create('metadata')
    meta = metadata.makeelement(OPF('meta'), name='cover')
    meta.set('content', raster_cover_item.get('id'))
    container.insert_into_xml(metadata, meta)

    return raster_cover, titlepage
Ejemplo n.º 8
0
def ensure_id(elem):
    if elem.tag == XHTML("a"):
        anchor = elem.get("name", None)
        if anchor:
            return False, anchor
    elem_id = elem.get("id", None)
    if elem_id:
        return False, elem_id
    elem.set("id", uuid_id())
    return True, elem.get("id")
Ejemplo n.º 9
0
def ensure_id(elem):
    if elem.tag == XHTML('a'):
        anchor = elem.get('name', None)
        if anchor:
            return False, anchor
    elem_id = elem.get('id', None)
    if elem_id:
        return False, elem_id
    elem.set('id', uuid_id())
    return True, elem.get('id')
Ejemplo n.º 10
0
Archivo: toc.py Proyecto: tokot/calibre
def ensure_id(elem):
    if elem.tag == XHTML('a'):
        anchor = elem.get('name', None)
        if anchor:
            return False, anchor
    elem_id = elem.get('id', None)
    if elem_id:
        return False, elem_id
    elem.set('id', uuid_id())
    return True, elem.get('id')
Ejemplo n.º 11
0
Archivo: toc.py Proyecto: sss/calibre
def add_id(container, name, loc):
    root = container.parsed(name)
    body = root.xpath('//*[local-name()="body"]')[0]
    locs = deque(loc)
    node = body
    while locs:
        children = tuple(node.iterchildren(etree.Element))
        node = children[locs[0]]
        locs.popleft()
    node.set('id', node.get('id', uuid_id()))
    container.commit_item(name, keep_parsed=True)
    return node.get('id')
Ejemplo n.º 12
0
 def __call__(self, container):
     from calibre.ebooks.oeb.base import uuid_id
     from calibre.ebooks.oeb.polish.replace import replace_ids
     newid = uuid_id()
     changed = False
     elems = (e for e in container.parsed(self.name).xpath('//*[@id]') if e.get('id') == self.invalid_id)
     for e in elems:
         e.set('id', newid)
         changed = True
         container.dirty(self.name)
     if changed:
         replace_ids(container, {self.name:{self.invalid_id:newid}})
     return changed
Ejemplo n.º 13
0
 def __call__(self, container):
     from calibre.ebooks.oeb.base import uuid_id
     from calibre.ebooks.oeb.polish.replace import replace_ids
     newid = uuid_id()
     changed = False
     elems = (e for e in container.parsed(self.name).xpath('//*[@id]') if e.get('id') == self.invalid_id)
     for e in elems:
         e.set('id', newid)
         changed = True
         container.dirty(self.name)
     if changed:
         replace_ids(container, {self.name:{self.invalid_id:newid}})
     return changed
Ejemplo n.º 14
0
 def __call__(self, container):
     from calibre.ebooks.oeb.base import uuid_id
     opf = container.opf
     uid = uuid_id()
     opf.set('unique-identifier', uid)
     m = container.opf_xpath('/opf:package/opf:metadata')
     if not m:
         m = [container.opf.makeelement(OPF('metadata'), nsmap={'dc':DC11_NS})]
         container.insert_into_xml(container.opf, m[0], 0)
     m = m[0]
     dc = m.makeelement(DC('identifier'), id=uid, nsmap={'opf':OPF2_NS})
     dc.set(OPF('scheme'), 'uuid')
     dc.text = uid
     container.insert_into_xml(m, dc)
     container.dirty(container.opf_name)
     return True
Ejemplo n.º 15
0
 def __call__(self, container):
     from calibre.ebooks.oeb.base import uuid_id
     opf = container.opf
     uid = uuid_id()
     opf.set('unique-identifier', uid)
     m = container.opf_xpath('/opf:package/opf:metadata')
     if not m:
         m = [container.opf.makeelement(OPF('metadata'), nsmap={'dc':DC11_NS})]
         container.insert_into_xml(container.opf, m[0], 0)
     m = m[0]
     dc = m.makeelement(DC('identifier'), id=uid, nsmap={'opf':OPF2_NS})
     dc.set(OPF('scheme'), 'uuid')
     dc.text = uid
     container.insert_into_xml(m, dc)
     container.dirty(container.opf_name)
     return True
Ejemplo n.º 16
0
 def process_node(xml_parent, toc_parent):
     for child in toc_parent:
         play_order['c'] += 1
         point = etree.SubElement(xml_parent, NCX('navPoint'), id=uuid_id(),
                         playOrder=str(play_order['c']))
         label = etree.SubElement(point, NCX('navLabel'))
         title = child.title
         if title:
             title = spat.sub(' ', title)
         etree.SubElement(label, NCX('text')).text = title
         if child.dest:
             href = to_href(child.dest)
             if child.frag:
                 href += '#'+child.frag
             etree.SubElement(point, NCX('content'), src=href)
         process_node(point, child)
Ejemplo n.º 17
0
 def process_node(xml_parent, toc_parent):
     for child in toc_parent:
         play_order['c'] += 1
         point = etree.SubElement(xml_parent, NCX('navPoint'), id=uuid_id(),
                         playOrder=str(play_order['c']))
         label = etree.SubElement(point, NCX('navLabel'))
         title = child.title
         if title:
             title = spat.sub(' ', title)
         etree.SubElement(label, NCX('text')).text = title
         if child.dest:
             href = to_href(child.dest)
             if child.frag:
                 href += '#'+child.frag
             etree.SubElement(point, NCX('content'), src=href)
         process_node(point, child)
Ejemplo n.º 18
0
def add_id(container, name, loc, totals=None):
    root = container.parsed(name)
    try:
        node = node_from_loc(root, loc, totals=totals)
    except MalformedMarkup:
        # The webkit HTML parser and the container parser have yielded
        # different node counts, this can happen if the file is valid XML
        # but contains constructs like nested <p> tags. So force parse it
        # with the HTML 5 parser and try again.
        raw = container.raw_data(name)
        root = container.parse_xhtml(raw, fname=name, force_html5_parse=True)
        try:
            node = node_from_loc(root, loc, totals=totals)
        except MalformedMarkup:
            raise MalformedMarkup(_('The file %s has malformed markup. Try running the Fix HTML tool'
                                    ' before editing.') % name)
        container.replace(name, root)

    node.set('id', node.get('id', uuid_id()))
    container.commit_item(name, keep_parsed=True)
    return node.get('id')
Ejemplo n.º 19
0
def create_epub_cover(container, cover_path, existing_image, options=None):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    try:
        ext = cover_path.rpartition(".")[-1].lower()
    except Exception:
        ext = "jpeg"
    cname, tname = "cover." + ext, "titlepage.xhtml"
    recommended_folders = get_recommended_folders(container, (cname, tname))

    if existing_image:
        raster_cover = existing_image
        manifest_id = {v: k for k, v in container.manifest_id_map.iteritems()}[existing_image]
        raster_cover_item = container.opf_xpath('//opf:manifest/*[@id="%s"]' % manifest_id)[0]
    else:
        folder = recommended_folders[cname]
        if folder:
            cname = folder + "/" + cname
        raster_cover_item = container.generate_item(cname, id_prefix="cover")
        raster_cover = container.href_to_name(raster_cover_item.get("href"), container.opf_name)

        with container.open(raster_cover, "wb") as dest:
            if callable(cover_path):
                cover_path("write_image", dest)
            else:
                with lopen(cover_path, "rb") as src:
                    shutil.copyfileobj(src, dest)
    if options is None:
        opts = load_defaults("epub_output")
        keep_aspect = opts.get("preserve_cover_aspect_ratio", False)
        no_svg = opts.get("no_svg_cover", False)
    else:
        keep_aspect = options.get("keep_aspect", False)
        no_svg = options.get("no_svg", False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace("__style__", style)
    else:
        if callable(cover_path):
            templ = (options or {}).get("template", CoverManager.SVG_TEMPLATE)
        else:
            width, height = 600, 800
            try:
                if existing_image:
                    width, height = identify(container.raw_data(existing_image, decode=False))[1:]
                else:
                    with lopen(cover_path, "rb") as csrc:
                        width, height = identify(csrc)[1:]
            except:
                container.log.exception("Failed to get width and height of cover")
            ar = "xMidYMid meet" if keep_aspect else "none"
            templ = CoverManager.SVG_TEMPLATE.replace("__ar__", ar)
            templ = templ.replace("__viewbox__", "0 0 %d %d" % (width, height))
            templ = templ.replace("__width__", str(width))
            templ = templ.replace("__height__", str(height))
    folder = recommended_folders[tname]
    if folder:
        tname = folder + "/" + tname
    titlepage_item = container.generate_item(tname, id_prefix="titlepage")
    titlepage = container.href_to_name(titlepage_item.get("href"), container.opf_name)
    raw = templ % container.name_to_href(raster_cover, titlepage).encode("utf-8")
    with container.open(titlepage, "wb") as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get("id") != "cover":
        from calibre.ebooks.oeb.base import uuid_id

        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set("id", newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set("idref", newid)
        raster_cover_item.set("id", "cover")

    spine = container.opf_xpath("//opf:spine")[0]
    ref = spine.makeelement(OPF("itemref"), idref=titlepage_item.get("id"))
    container.insert_into_xml(spine, ref, index=0)
    guide = container.opf_get_or_create("guide")
    container.insert_into_xml(
        guide,
        guide.makeelement(
            OPF("reference"),
            type="cover",
            title=_("Cover"),
            href=container.name_to_href(titlepage, base=container.opf_name),
        ),
    )
    metadata = container.opf_get_or_create("metadata")
    meta = metadata.makeelement(OPF("meta"), name="cover")
    meta.set("content", raster_cover_item.get("id"))
    container.insert_into_xml(metadata, meta)

    return raster_cover, titlepage
Ejemplo n.º 20
0
def create_epub_cover(container, cover_path, existing_image, options=None):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    try:
        ext = cover_path.rpartition('.')[-1].lower()
    except Exception:
        ext = 'jpeg'
    cname, tname = 'cover.' + ext, 'titlepage.xhtml'
    recommended_folders = get_recommended_folders(container, (cname, tname))

    if existing_image:
        raster_cover = existing_image
        manifest_id = {v:k for k, v in container.manifest_id_map.iteritems()}[existing_image]
        raster_cover_item = container.opf_xpath('//opf:manifest/*[@id="%s"]' % manifest_id)[0]
    else:
        folder = recommended_folders[cname]
        if folder:
            cname = folder + '/' + cname
        raster_cover_item = container.generate_item(cname, id_prefix='cover')
        raster_cover = container.href_to_name(raster_cover_item.get('href'), container.opf_name)

        with container.open(raster_cover, 'wb') as dest:
            if callable(cover_path):
                cover_path('write_image', dest)
            else:
                with lopen(cover_path, 'rb') as src:
                    shutil.copyfileobj(src, dest)
    if options is None:
        opts = load_defaults('epub_output')
        keep_aspect = opts.get('preserve_cover_aspect_ratio', False)
        no_svg = opts.get('no_svg_cover', False)
    else:
        keep_aspect = options.get('keep_aspect', False)
        no_svg = options.get('no_svg', False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace('__style__', style)
        has_svg = False
    else:
        if callable(cover_path):
            templ = (options or {}).get('template', CoverManager.SVG_TEMPLATE)
            has_svg = 'xlink:href' in templ
        else:
            width, height = 600, 800
            has_svg = True
            try:
                if existing_image:
                    width, height = identify(container.raw_data(existing_image, decode=False))[1:]
                else:
                    with lopen(cover_path, 'rb') as csrc:
                        width, height = identify(csrc)[1:]
            except:
                container.log.exception("Failed to get width and height of cover")
            ar = 'xMidYMid meet' if keep_aspect else 'none'
            templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar)
            templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height))
            templ = templ.replace('__width__', str(width))
            templ = templ.replace('__height__', str(height))
    folder = recommended_folders[tname]
    if folder:
        tname = folder + '/' + tname
    titlepage_item = container.generate_item(tname, id_prefix='titlepage')
    titlepage = container.href_to_name(titlepage_item.get('href'),
                                          container.opf_name)
    raw = templ%container.name_to_href(raster_cover, titlepage).encode('utf-8')
    with container.open(titlepage, 'wb') as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get('id') != 'cover':
        from calibre.ebooks.oeb.base import uuid_id
        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set('id', newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set('idref', newid)
        raster_cover_item.set('id', 'cover')

    spine = container.opf_xpath('//opf:spine')[0]
    ref = spine.makeelement(OPF('itemref'), idref=titlepage_item.get('id'))
    container.insert_into_xml(spine, ref, index=0)
    ver = container.opf_version_parsed
    if ver.major < 3:
        guide = container.opf_get_or_create('guide')
        container.insert_into_xml(guide, guide.makeelement(
            OPF('reference'), type='cover', title=_('Cover'),
            href=container.name_to_href(titlepage, base=container.opf_name)))
        metadata = container.opf_get_or_create('metadata')
        meta = metadata.makeelement(OPF('meta'), name='cover')
        meta.set('content', raster_cover_item.get('id'))
        container.insert_into_xml(metadata, meta)
    else:
        container.apply_unique_properties(raster_cover, 'cover-image')
        container.apply_unique_properties(titlepage, 'calibre:title-page')
        if has_svg:
            container.add_properties(titlepage, 'svg')

    return raster_cover, titlepage
Ejemplo n.º 21
0
def create_epub_cover(container, cover_path):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    ext = cover_path.rpartition(".")[-1].lower()
    raster_cover_item = container.generate_item("cover." + ext, id_prefix="cover")
    raster_cover = container.href_to_name(raster_cover_item.get("href"), container.opf_name)
    with open(cover_path, "rb") as src, container.open(raster_cover, "wb") as dest:
        shutil.copyfileobj(src, dest)
    opts = load_defaults("epub_output")
    keep_aspect = opts.get("preserve_cover_aspect_ratio", False)
    no_svg = opts.get("no_svg_cover", False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace("__style__", style)
    else:
        width, height = 600, 800
        try:
            width, height = identify(cover_path)[:2]
        except:
            container.log.exception("Failed to get width and height of cover")
        ar = "xMidYMid meet" if keep_aspect else "none"
        templ = CoverManager.SVG_TEMPLATE.replace("__ar__", ar)
        templ = templ.replace("__viewbox__", "0 0 %d %d" % (width, height))
        templ = templ.replace("__width__", str(width))
        templ = templ.replace("__height__", str(height))
    titlepage_item = container.generate_item("titlepage.xhtml", id_prefix="titlepage")
    titlepage = container.href_to_name(titlepage_item.get("href"), container.opf_name)
    raw = templ % container.name_to_href(raster_cover).encode("utf-8")
    with container.open(titlepage, "wb") as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get("id") != "cover":
        from calibre.ebooks.oeb.base import uuid_id

        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set("id", newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set("idref", newid)
        raster_cover_item.set("id", "cover")

    spine = container.opf_xpath("//opf:spine")[0]
    ref = spine.makeelement(OPF("itemref"), idref=titlepage_item.get("id"))
    container.insert_into_xml(spine, ref, index=0)
    guide = container.opf_get_or_create("guide")
    container.insert_into_xml(
        guide,
        guide.makeelement(
            OPF("reference"),
            type="cover",
            title=_("Cover"),
            href=container.name_to_href(titlepage, base=container.opf_name),
        ),
    )
    metadata = container.opf_get_or_create("metadata")
    meta = metadata.makeelement(OPF("meta"), name="cover")
    meta.set("content", raster_cover_item.get("id"))
    container.insert_into_xml(metadata, meta)

    return raster_cover, titlepage
Ejemplo n.º 22
0
def add_id(container, name, loc):
    root = container.parsed(name)
    node = node_from_loc(root, loc)
    node.set('id', node.get('id', uuid_id()))
    container.commit_item(name, keep_parsed=True)
    return node.get('id')
Ejemplo n.º 23
0
def create_epub_cover(container, cover_path, existing_image, options=None):
    from calibre.ebooks.conversion.config import load_defaults
    from calibre.ebooks.oeb.transforms.cover import CoverManager

    try:
        ext = cover_path.rpartition('.')[-1].lower()
    except Exception:
        ext = 'jpeg'
    cname, tname = 'cover.' + ext, 'titlepage.xhtml'
    recommended_folders = get_recommended_folders(container, (cname, tname))

    if existing_image:
        raster_cover = existing_image
        manifest_id = {v: k
                       for k, v in iteritems(container.manifest_id_map)
                       }[existing_image]
        raster_cover_item = container.opf_xpath('//opf:manifest/*[@id="%s"]' %
                                                manifest_id)[0]
    else:
        folder = recommended_folders[cname]
        if folder:
            cname = folder + '/' + cname
        raster_cover_item = container.generate_item(cname, id_prefix='cover')
        raster_cover = container.href_to_name(raster_cover_item.get('href'),
                                              container.opf_name)

        with container.open(raster_cover, 'wb') as dest:
            if callable(cover_path):
                cover_path('write_image', dest)
            else:
                with lopen(cover_path, 'rb') as src:
                    shutil.copyfileobj(src, dest)
    if options is None:
        opts = load_defaults('epub_output')
        keep_aspect = opts.get('preserve_cover_aspect_ratio', False)
        no_svg = opts.get('no_svg_cover', False)
    else:
        keep_aspect = options.get('keep_aspect', False)
        no_svg = options.get('no_svg', False)
    if no_svg:
        style = 'style="height: 100%%"'
        templ = CoverManager.NONSVG_TEMPLATE.replace('__style__', style)
        has_svg = False
    else:
        if callable(cover_path):
            templ = (options or {}).get('template', CoverManager.SVG_TEMPLATE)
            has_svg = 'xlink:href' in templ
        else:
            width, height = 600, 800
            has_svg = True
            try:
                if existing_image:
                    width, height = identify(
                        container.raw_data(existing_image, decode=False))[1:]
                else:
                    with lopen(cover_path, 'rb') as csrc:
                        width, height = identify(csrc)[1:]
            except:
                container.log.exception(
                    "Failed to get width and height of cover")
            ar = 'xMidYMid meet' if keep_aspect else 'none'
            templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar)
            templ = templ.replace('__viewbox__', '0 0 %d %d' % (width, height))
            templ = templ.replace('__width__', str(width))
            templ = templ.replace('__height__', str(height))
    folder = recommended_folders[tname]
    if folder:
        tname = folder + '/' + tname
    titlepage_item = container.generate_item(tname, id_prefix='titlepage')
    titlepage = container.href_to_name(titlepage_item.get('href'),
                                       container.opf_name)
    raw = templ % container.name_to_href(raster_cover,
                                         titlepage).encode('utf-8')
    with container.open(titlepage, 'wb') as f:
        f.write(raw)

    # We have to make sure the raster cover item has id="cover" for the moron
    # that wrote the Nook firmware
    if raster_cover_item.get('id') != 'cover':
        from calibre.ebooks.oeb.base import uuid_id
        newid = uuid_id()
        for item in container.opf_xpath('//*[@id="cover"]'):
            item.set('id', newid)
        for item in container.opf_xpath('//*[@idref="cover"]'):
            item.set('idref', newid)
        raster_cover_item.set('id', 'cover')

    spine = container.opf_xpath('//opf:spine')[0]
    ref = spine.makeelement(OPF('itemref'), idref=titlepage_item.get('id'))
    container.insert_into_xml(spine, ref, index=0)
    ver = container.opf_version_parsed
    if ver.major < 3:
        guide = container.opf_get_or_create('guide')
        container.insert_into_xml(
            guide,
            guide.makeelement(OPF('reference'),
                              type='cover',
                              title=_('Cover'),
                              href=container.name_to_href(
                                  titlepage, base=container.opf_name)))
        metadata = container.opf_get_or_create('metadata')
        meta = metadata.makeelement(OPF('meta'), name='cover')
        meta.set('content', raster_cover_item.get('id'))
        container.insert_into_xml(metadata, meta)
    else:
        container.apply_unique_properties(raster_cover, 'cover-image')
        container.apply_unique_properties(titlepage, 'calibre:title-page')
        if has_svg:
            container.add_properties(titlepage, 'svg')

    return raster_cover, titlepage
Ejemplo n.º 24
0
def add_id(container, name, loc):
    root = container.parsed(name)
    node = node_from_loc(root, loc)
    node.set('id', node.get('id', uuid_id()))
    container.commit_item(name, keep_parsed=True)
    return node.get('id')