Exemple #1
0
    def convert(self, oeb_book, output_path, input_plugin, opts, log):
        from calibre.gui2 import must_use_qt, load_builtin_fonts
        from calibre.ebooks.oeb.transforms.split import Split
        # Turn off hinting in WebKit (requires a patched build of QtWebKit)
        os.environ['CALIBRE_WEBKIT_NO_HINTING'] = '1'
        self.filtered_font_warnings = set()
        try:
            # split on page breaks, as the JS code to convert page breaks to
            # column breaks will not work because of QWebSettings.LocalContentCanAccessFileUrls
            Split()(oeb_book, opts)
            must_use_qt()
            load_builtin_fonts()

            self.oeb = oeb_book
            self.input_plugin, self.opts, self.log = input_plugin, opts, log
            self.output_path = output_path
            from calibre.ebooks.oeb.base import OPF, OPF2_NS
            from lxml import etree
            from io import BytesIO
            package = etree.Element(OPF('package'),
                attrib={'version': '2.0', 'unique-identifier': 'dummy'},
                nsmap={None: OPF2_NS})
            from calibre.ebooks.metadata.opf2 import OPF
            self.oeb.metadata.to_opf2(package)
            self.metadata = OPF(BytesIO(etree.tostring(package))).to_book_metadata()
            self.cover_data = None

            if input_plugin.is_image_collection:
                log.debug('Converting input as an image collection...')
                self.convert_images(input_plugin.get_images())
            else:
                log.debug('Converting input as a text based book...')
                self.convert_text(oeb_book)
        finally:
            os.environ.pop('CALIBRE_WEBKIT_NO_HINTING', None)
Exemple #2
0
    def convert(self, oeb, output_path, input_plugin, opts, log):
        from calibre.ebooks.mobi.writer2.resources import Resources
        from calibre.ebooks.mobi.writer8.main import create_kf8_book
        from calibre.ebooks.mobi.writer8.cleanup import remove_duplicate_anchors

        self.oeb, self.opts, self.log = oeb, opts, log
        opts.mobi_periodical = self.is_periodical
        passthrough = getattr(opts, 'mobi_passthrough', False)
        remove_duplicate_anchors(oeb)

        resources = Resources(self.oeb,
                              self.opts,
                              self.is_periodical,
                              add_fonts=True,
                              process_images=False)
        if not passthrough:
            remove_html_cover(self.oeb, self.log)

            # Split on pagebreaks so that the resulting KF8 is faster to load
            from calibre.ebooks.oeb.transforms.split import Split
            Split()(self.oeb, self.opts)

        kf8 = create_kf8_book(self.oeb, self.opts, resources, for_joint=False)

        kf8.write(output_path)
        extract_mobi(output_path, opts)
Exemple #3
0
    def convert(self, oeb, output_path, input_plugin, opts, log):
        from calibre.ebooks.mobi.writer2.resources import Resources
        self.log, self.opts, self.oeb = log, opts, oeb

        mobi_type = opts.mobi_file_type
        if self.is_periodical:
            mobi_type = 'old'  # Amazon does not support KF8 periodicals
        create_kf8 = mobi_type in ('new', 'both')

        remove_html_cover(self.oeb, self.log)
        resources = Resources(oeb,
                              opts,
                              self.is_periodical,
                              add_fonts=create_kf8)
        self.check_for_periodical()

        if create_kf8:
            from calibre.ebooks.mobi.writer8.cleanup import remove_duplicate_anchors
            remove_duplicate_anchors(self.oeb)
            # Split on pagebreaks so that the resulting KF8 is faster to load
            from calibre.ebooks.oeb.transforms.split import Split
            Split()(self.oeb, self.opts)

        kf8 = self.create_kf8(resources, for_joint=mobi_type
                              == 'both') if create_kf8 else None
        if mobi_type == 'new':
            kf8.write(output_path)
            extract_mobi(output_path, opts)
            return

        self.log('Creating MOBI 6 output')
        self.write_mobi(input_plugin, output_path, kf8, resources)
Exemple #4
0
    def convert(self, oeb, output_path, opts, log):
        from calibre.ebooks.mobi.writer2.resources import Resources
        self.log, self.opts, self.oeb = log, opts, oeb

        mobi_type = opts.mobi_file_type
        if self.is_periodical:
            mobi_type = 'old'  # Amazon does not support KF8 periodicals
        create_kf8 = mobi_type in ('new', 'both')

        remove_html_cover(self.oeb, self.log)
        resources = Resources(oeb,
                              opts,
                              self.is_periodical,
                              add_fonts=create_kf8,
                              process_images=opts.process_images)
        self.check_for_periodical()

        if create_kf8:
            # Split on pagebreaks so that the resulting KF8 works better with
            # calibre's viewer, which does not support CSS page breaks
            from calibre.ebooks.oeb.transforms.split import Split
            Split()(self.oeb, self.opts)

        kf8 = self.create_kf8(resources, for_joint=mobi_type
                              == 'both') if create_kf8 else None
        if mobi_type == 'new':
            kf8.write(output_path)
            extract_mobi(output_path, opts)
            return

        self.log.info('Creating MOBI 6 output')
        self.write_mobi(output_path, kf8, resources)
Exemple #5
0
    def convert(self, oeb, output_path, input_plugin, opts, log):
        from calibre.ebooks.mobi.writer2.resources import Resources
        from calibre.ebooks.mobi.writer8.main import create_kf8_book

        self.oeb, self.opts, self.log = oeb, opts, log
        opts.mobi_periodical = self.is_periodical
        passthrough = getattr(opts, 'mobi_passthrough', False)

        resources = Resources(self.oeb,
                              self.opts,
                              self.is_periodical,
                              add_fonts=True,
                              process_images=False)
        if not passthrough:
            remove_html_cover(self.oeb, self.log)

            # Split on pagebreaks so that the resulting KF8 works better with
            # calibre's viewer, which does not support CSS page breaks
            from calibre.ebooks.oeb.transforms.split import Split
            Split()(self.oeb, self.opts)

        kf8 = create_kf8_book(self.oeb, self.opts, resources, for_joint=False)

        kf8.write(output_path)
        extract_mobi(output_path, opts)
    def convert(self, oeb, output_path, input_plugin, opts, log):
        self.log, self.opts, self.oeb = log, opts, oeb
        from calibre.ebooks.oeb.transforms.manglecase import CaseMangler
        from calibre.ebooks.oeb.transforms.rasterize import SVGRasterizer
        from calibre.ebooks.oeb.transforms.htmltoc import HTMLTOCAdder
        from calibre.ebooks.lit.writer import LitWriter
        from calibre.ebooks.oeb.transforms.split import Split
        split = Split(split_on_page_breaks=True, max_flow_size=0,
                remove_css_pagebreaks=False)
        split(self.oeb, self.opts)

        tocadder = HTMLTOCAdder()
        tocadder(oeb, opts)
        mangler = CaseMangler()
        mangler(oeb, opts)
        rasterizer = SVGRasterizer()
        rasterizer(oeb, opts)
        lit = LitWriter(self.opts)
        lit(oeb, output_path)
    def convert(self, oeb, output_path, input_plugin, opts, log):
        self.log, self.opts, self.oeb = log, opts, oeb

        if self.opts.epub_inline_toc:
            from calibre.ebooks.mobi.writer8.toc import TOCAdder
            opts.mobi_toc_at_start = not opts.epub_toc_at_end
            opts.mobi_passthrough = False
            opts.no_inline_toc = False
            TOCAdder(oeb,
                     opts,
                     replace_previous_inline_toc=True,
                     ignore_existing_toc=True)

        if self.opts.epub_flatten:
            from calibre.ebooks.oeb.transforms.filenames import FlatFilenames
            FlatFilenames()(oeb, opts)
        else:
            from calibre.ebooks.oeb.transforms.filenames import UniqueFilenames
            UniqueFilenames()(oeb, opts)

        self.workaround_ade_quirks()
        self.workaround_webkit_quirks()
        self.upshift_markup()
        from calibre.ebooks.oeb.transforms.rescale import RescaleImages
        RescaleImages(check_colorspaces=True)(oeb, opts)

        from calibre.ebooks.oeb.transforms.split import Split
        split = Split(not self.opts.dont_split_on_page_breaks,
                      max_flow_size=self.opts.flow_size * 1024)
        split(self.oeb, self.opts)

        from calibre.ebooks.oeb.transforms.cover import CoverManager
        cm = CoverManager(
            no_default_cover=self.opts.no_default_epub_cover,
            no_svg_cover=self.opts.no_svg_cover,
            preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
        cm(self.oeb, self.opts, self.log)

        self.workaround_sony_quirks()

        if self.oeb.toc.count() == 0:
            self.log.warn('This EPUB file has no Table of Contents. '
                          'Creating a default TOC')
            first = next(iter(self.oeb.spine))
            self.oeb.toc.add(_('Start'), first.href)

        from calibre.ebooks.oeb.base import OPF
        identifiers = oeb.metadata['identifier']
        uuid = None
        for x in identifiers:
            if x.get(OPF('scheme'),
                     None).lower() == 'uuid' or str(x).startswith('urn:uuid:'):
                uuid = str(x).split(':')[-1]
                break
        encrypted_fonts = getattr(input_plugin, 'encrypted_fonts', [])

        if uuid is None:
            self.log.warn('No UUID identifier found')
            from uuid import uuid4
            uuid = str(uuid4())
            oeb.metadata.add('identifier', uuid, scheme='uuid', id=uuid)

        if encrypted_fonts and not uuid.startswith('urn:uuid:'):
            # Apparently ADE requires this value to start with urn:uuid:
            # for some absurd reason, or it will throw a hissy fit and refuse
            # to use the obfuscated fonts.
            for x in identifiers:
                if str(x) == uuid:
                    x.content = 'urn:uuid:' + uuid

        with TemporaryDirectory('_epub_output') as tdir:
            from calibre.customize.ui import plugin_for_output_format
            metadata_xml = None
            extra_entries = []
            if self.is_periodical:
                if self.opts.output_profile.epub_periodical_format == 'sony':
                    from calibre.ebooks.epub.periodical import sony_metadata
                    metadata_xml, atom_xml = sony_metadata(oeb)
                    extra_entries = [('atom.xml', 'application/atom+xml',
                                      atom_xml)]
            oeb_output = plugin_for_output_format('oeb')
            oeb_output.convert(oeb, tdir, input_plugin, opts, log)
            opf = [x for x in os.listdir(tdir) if x.endswith('.opf')][0]
            self.condense_ncx([
                os.path.join(tdir, x) for x in os.listdir(tdir)
                if x.endswith('.ncx')
            ][0])
            encryption = None
            if encrypted_fonts:
                encryption = self.encrypt_fonts(encrypted_fonts, tdir, uuid)

            from calibre.ebooks.epub import initialize_container
            with initialize_container(output_path,
                                      os.path.basename(opf),
                                      extra_entries=extra_entries) as epub:
                epub.add_dir(tdir)
                if encryption is not None:
                    epub.writestr('META-INF/encryption.xml', encryption)
                if metadata_xml is not None:
                    epub.writestr('META-INF/metadata.xml',
                                  metadata_xml.encode('utf-8'))
            if opts.extract_to is not None:
                from calibre.utils.zipfile import ZipFile
                if os.path.exists(opts.extract_to):
                    if os.path.isdir(opts.extract_to):
                        shutil.rmtree(opts.extract_to)
                    else:
                        os.remove(opts.extract_to)
                os.mkdir(opts.extract_to)
                with ZipFile(output_path) as zf:
                    zf.extractall(path=opts.extract_to)
                self.log.info('EPUB extracted to', opts.extract_to)
    def convert(self, oeb, output_path, opts, log):
        self.log, self.opts, self.oeb = log, opts, oeb

        if self.opts.epub_flatten:
            from calibre.ebooks.oeb.transforms.filenames import FlatFilenames
            FlatFilenames()(oeb, opts)
        else:
            from calibre.ebooks.oeb.transforms.filenames import UniqueFilenames
            UniqueFilenames()(oeb, opts)

        self.workaround_ade_quirks()
        self.workaround_webkit_quirks()
        self.upshift_markup()
        #from calibre.ebooks.oeb.transforms.rescale import RescaleImages
        #RescaleImages()(oeb, opts)

        from calibre.ebooks.oeb.transforms.split import Split
        split = Split(not self.opts.dont_split_on_page_breaks,
                      max_flow_size=self.opts.flow_size * 1024)
        split(self.oeb, self.opts)

        #from calibre.ebooks.oeb.transforms.cover import CoverManager
        #cm = CoverManager(
        #        no_default_cover=self.opts.no_default_epub_cover,
        #        no_svg_cover=self.opts.no_svg_cover,
        #        preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
        #cm(self.oeb, self.opts, self.log)

        self.workaround_sony_quirks()

        if self.oeb.toc.count() == 0:
            self.log.warn('This EPUB file has no Table of Contents. '
                          'Creating a default TOC')
            first = iter(self.oeb.spine).next()
            self.oeb.toc.add(_('Start'), first.href)

        from calibre.ebooks.oeb.base import OPF_MIME, NCX_MIME, PAGE_MAP_MIME
        results = oeb.to_opf2(page_map=True)

        epub = zipfile.ZipFile(output_path, "w", zipfile.ZIP_STORED)
        epub.writestr('mimetype', "application/epub+zip")

        CONTAINER = u'''\
<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="{0}" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>
    '''
        if hasattr(self.opts,
                   "epub_dont_compress") and self.opts.epub_dont_compress:
            compress = zipfile.ZIP_STORED
        else:
            compress = zipfile.ZIP_DEFLATED
        from lxml import etree
        for key in (OPF_MIME, NCX_MIME, PAGE_MAP_MIME):
            href, root = results.pop(key, [None, None])
            if root is not None:
                if key == OPF_MIME:
                    epub.writestr('META-INF/container.xml',
                                  CONTAINER.format('OEBPS/%s' %
                                                   href).encode('utf-8'),
                                  compress_type=compress)
                raw = etree.tostring(root,
                                     pretty_print=True,
                                     encoding='utf-8',
                                     xml_declaration=True)
                epub.writestr('OEBPS/%s' % href, raw)

        from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES
        for item in oeb.manifest:
            if item.media_type in OEB_RASTER_IMAGES:
                try:
                    img = self.process_image(str(item))
                except:
                    self.log.warn('Bad image file %r.' % item.href)
                else:
                    epub.writestr('OEBPS/%s' % item.href,
                                  img,
                                  compress_type=compress)
            else:
                epub.writestr('OEBPS/%s' % item.href,
                              str(item),
                              compress_type=compress)