def __call__(self, oeb, path): """ Write the book in the :class:`OEBBook` object :param:`oeb` to a folder at :param:`path`. """ version = int(self.version[0]) opfname = None if os.path.splitext(path)[1].lower() == '.opf': opfname = os.path.basename(path) path = os.path.dirname(path) if not os.path.isdir(path): os.mkdir(path) output = DirContainer(path, oeb.log) for item in oeb.manifest.values(): output.write(item.href, str(item)) if version == 1: metadata = oeb.to_opf1() elif version == 2: metadata = oeb.to_opf2(page_map=self.page_map) else: raise OEBError("Unrecognized OPF version %r" % self.version) pretty_print = self.pretty_print for mime, (href, data) in metadata.items(): if opfname and mime == OPF_MIME: href = opfname output.write(href, xml2str(data, pretty_print=pretty_print)) return
def __call__(self, oeb, path): """ Write the book in the :class:`OEBBook` object :param:`oeb` to a folder at :param:`path`. """ version = int(self.version[0]) opfname = None if os.path.splitext(path)[1].lower() == '.opf': opfname = os.path.basename(path) path = os.path.dirname(path) if not os.path.isdir(path): os.mkdir(path) output = DirContainer(path, oeb.log) for item in oeb.manifest.values(): output.write(item.href, item.bytes_representation) if version == 1: metadata = oeb.to_opf1() elif version == 2: metadata = oeb.to_opf2(page_map=self.page_map) else: raise OEBError("Unrecognized OPF version %r" % self.version) pretty_print = self.pretty_print for mime, (href, data) in metadata.items(): if opfname and mime == OPF_MIME: href = opfname output.write(href, xml2str(data, pretty_print=pretty_print)) return
def convert(self, stream: IO, options, file_ext, log, accelerators): from calibre.ebooks.oeb.base import DirContainer from calibre.ebooks.conversion.plumber import create_oebbook log.debug("Parsing UMD file...") book = UMDFile.from_stream(stream) log.debug("Handle meta data ...") oeb = create_oebbook(log, None, options, encoding=options.input_encoding, populate=False) oeb.metadata.add('title', book.title) oeb.metadata.add('creator', book.author, attrib={'role': 'aut'}) oeb.metadata.add('publisher', book.publisher) oeb.metadata.add('identifier', str(uuid.uuid4()), id='uuid_id', scheme='uuid') for id_ in oeb.metadata.identifier: if 'id' in id_.attrib: oeb.uid = oeb.metadata.identifier[0] break with TemporaryDirectory('_umd2oeb', keep=True) as tmp_dir: log.debug('Process TOC ...') oeb.container = DirContainer(tmp_dir, log) content, cover = book.chapters, book.cover if content: for i, ch in enumerate(content): ch_title, ch_content = ch.title, ch.content if ch_title is None or ch_content is None: continue ch_content = ch_content.replace("\u2029", "") ch_fn = Path(tmp_dir) / f"ch_{i:04d}.html" ch_fn.write_text(convert_basic(ch_content, title=ch_title)) oeb.toc.add(ch_title, ch_fn.name) id_, href = oeb.manifest.generate(id='html', href=ch_fn.name) item = oeb.manifest.add(id_, href, 'text/html') item.html_input_href = ch_fn.name oeb.spine.add(item, True) if cover: cover_file = Path(tmp_dir) / "cover.jpeg" cover_file.write_bytes(cover) id_, href = oeb.manifest.generate(id='image', href=cover_file.name) oeb.guide.add('cover', 'Cover', href) return oeb
def create_oebbook(self, htmlpath, basedir, opts, log, mi): import uuid from calibre.ebooks.conversion.plumber import create_oebbook from calibre.ebooks.oeb.base import (DirContainer, rewrite_links, urlnormalize, urldefrag, BINARY_MIME, OEB_STYLES, xpath, urlquote) from calibre import guess_type from calibre.ebooks.oeb.transforms.metadata import \ meta_info_to_oeb_metadata from calibre.ebooks.html.input import get_filelist from calibre.ebooks.metadata import string_to_authors from calibre.utils.localization import canonicalize_lang import css_parser, logging css_parser.log.setLevel(logging.WARN) self.OEB_STYLES = OEB_STYLES oeb = create_oebbook(log, None, opts, self, encoding=opts.input_encoding, populate=False) self.oeb = oeb metadata = oeb.metadata meta_info_to_oeb_metadata(mi, metadata, log) if not metadata.language: l = canonicalize_lang(getattr(opts, 'language', None)) if not l: oeb.logger.warn('Language not specified') l = get_lang().replace('_', '-') metadata.add('language', l) if not metadata.creator: a = getattr(opts, 'authors', None) if a: a = string_to_authors(a) if not a: oeb.logger.warn('Creator not specified') a = [self.oeb.translate(__('Unknown'))] for aut in a: metadata.add('creator', aut) if not metadata.title: oeb.logger.warn('Title not specified') metadata.add('title', self.oeb.translate(__('Unknown'))) bookid = unicode_type(uuid.uuid4()) metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') for ident in metadata.identifier: if 'id' in ident.attrib: self.oeb.uid = metadata.identifier[0] break filelist = get_filelist(htmlpath, basedir, opts, log) filelist = [f for f in filelist if not f.is_binary] htmlfile_map = {} for f in filelist: path = f.path oeb.container = DirContainer(os.path.dirname(path), log, ignore_opf=True) bname = os.path.basename(path) id, href = oeb.manifest.generate(id='html', href=sanitize_file_name(bname)) htmlfile_map[path] = href item = oeb.manifest.add(id, href, 'text/html') if path == htmlpath and '%' in path: bname = urlquote(bname) item.html_input_href = bname oeb.spine.add(item, True) self.added_resources = {} self.log = log self.log('Normalizing filename cases') for path, href in htmlfile_map.items(): if not self.is_case_sensitive(path): path = path.lower() self.added_resources[path] = href self.urlnormalize, self.DirContainer = urlnormalize, DirContainer self.urldefrag = urldefrag self.guess_type, self.BINARY_MIME = guess_type, BINARY_MIME self.log('Rewriting HTML links') for f in filelist: path = f.path dpath = os.path.dirname(path) oeb.container = DirContainer(dpath, log, ignore_opf=True) href = htmlfile_map[path] try: item = oeb.manifest.hrefs[href] except KeyError: item = oeb.manifest.hrefs[urlnormalize(href)] rewrite_links(item.data, partial(self.resource_adder, base=dpath)) for item in oeb.manifest.values(): if item.media_type in self.OEB_STYLES: dpath = None for path, href in self.added_resources.items(): if href == item.href: dpath = os.path.dirname(path) break css_parser.replaceUrls( item.data, partial(self.resource_adder, base=dpath)) toc = self.oeb.toc self.oeb.auto_generated_toc = True titles = [] headers = [] for item in self.oeb.spine: if not item.linear: continue html = item.data title = ''.join(xpath(html, '/h:html/h:head/h:title/text()')) title = re.sub(r'\s+', ' ', title.strip()) if title: titles.append(title) headers.append('(unlabled)') for tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'strong'): expr = '/h:html/h:body//h:%s[position()=1]/text()' header = ''.join(xpath(html, expr % tag)) header = re.sub(r'\s+', ' ', header.strip()) if header: headers[-1] = header break use = titles if len(titles) > len(set(titles)): use = headers for title, item in zip(use, self.oeb.spine): if not item.linear: continue toc.add(title, item.href) oeb.container = DirContainer(getcwd(), oeb.log, ignore_opf=True) return oeb
def convert(self, stream, options, file_ext, log, accelerators): import uuid from calibre.ebooks.oeb.base import DirContainer from calibre.ebooks.snb.snbfile import SNBFile from calibre.utils.xml_parse import safe_xml_fromstring log.debug("Parsing SNB file...") snbFile = SNBFile() try: snbFile.Parse(stream) except: raise ValueError("Invalid SNB file") if not snbFile.IsValid(): log.debug("Invalid SNB file") raise ValueError("Invalid SNB file") log.debug("Handle meta data ...") from calibre.ebooks.conversion.plumber import create_oebbook oeb = create_oebbook(log, None, options, encoding=options.input_encoding, populate=False) meta = snbFile.GetFileStream('snbf/book.snbf') if meta is not None: meta = safe_xml_fromstring(meta) l = { 'title': './/head/name', 'creator': './/head/author', 'language': './/head/language', 'generator': './/head/generator', 'publisher': './/head/publisher', 'cover': './/head/cover', } d = {} for item in l: node = meta.find(l[item]) if node is not None: d[item] = node.text if node.text is not None else '' else: d[item] = '' oeb.metadata.add('title', d['title']) oeb.metadata.add('creator', d['creator'], attrib={'role': 'aut'}) oeb.metadata.add('language', d['language'].lower().replace('_', '-')) oeb.metadata.add('generator', d['generator']) oeb.metadata.add('publisher', d['publisher']) if d['cover'] != '': oeb.guide.add('cover', 'Cover', d['cover']) bookid = unicode_type(uuid.uuid4()) oeb.metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') for ident in oeb.metadata.identifier: if 'id' in ident.attrib: oeb.uid = oeb.metadata.identifier[0] break with TemporaryDirectory('_snb2oeb', keep=True) as tdir: log.debug('Process TOC ...') toc = snbFile.GetFileStream('snbf/toc.snbf') oeb.container = DirContainer(tdir, log) if toc is not None: toc = safe_xml_fromstring(toc) i = 1 for ch in toc.find('.//body'): chapterName = ch.text chapterSrc = ch.get('src') fname = 'ch_%d.htm' % i data = snbFile.GetFileStream('snbc/' + chapterSrc) if data is None: continue snbc = safe_xml_fromstring(data) lines = [] for line in snbc.find('.//body'): if line.tag == 'text': lines.append('<p>%s</p>' % html_encode(line.text)) elif line.tag == 'img': lines.append('<p><img src="%s" /></p>' % html_encode(line.text)) with open(os.path.join(tdir, fname), 'wb') as f: f.write((HTML_TEMPLATE % (chapterName, '\n'.join(lines))).encode( 'utf-8', 'replace')) oeb.toc.add(ch.text, fname) id, href = oeb.manifest.generate( id='html', href=ascii_filename(fname)) item = oeb.manifest.add(id, href, 'text/html') item.html_input_href = fname oeb.spine.add(item, True) i = i + 1 imageFiles = snbFile.OutputImageFiles(tdir) for f, m in imageFiles: id, href = oeb.manifest.generate(id='image', href=ascii_filename(f)) item = oeb.manifest.add(id, href, m) item.html_input_href = f return oeb
def _create_oebbook(self, hhcpath, basedir, opts, log, mi): import uuid from lxml import html from calibre.ebooks.conversion.plumber import create_oebbook from calibre.ebooks.oeb.base import DirContainer oeb = create_oebbook(log, None, opts, encoding=opts.input_encoding, populate=False) self.oeb = oeb metadata = oeb.metadata if mi.title: metadata.add('title', mi.title) if mi.authors: for a in mi.authors: metadata.add('creator', a, attrib={'role': 'aut'}) if mi.publisher: metadata.add('publisher', mi.publisher) if mi.isbn: metadata.add('identifier', mi.isbn, attrib={'scheme': 'ISBN'}) if not metadata.language: oeb.logger.warn(u'Language not specified') metadata.add('language', get_lang().replace('_', '-')) if not metadata.creator: oeb.logger.warn('Creator not specified') metadata.add('creator', _('Unknown')) if not metadata.title: oeb.logger.warn('Title not specified') metadata.add('title', _('Unknown')) bookid = str(uuid.uuid4()) metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') for ident in metadata.identifier: if 'id' in ident.attrib: self.oeb.uid = metadata.identifier[0] break hhcdata = self._read_file(hhcpath) hhcroot = html.fromstring(hhcdata) chapters = self._process_nodes(hhcroot) #print "=============================" #print "Printing hhcroot" #print etree.tostring(hhcroot, pretty_print=True) #print "=============================" log.debug('Found %d section nodes' % len(chapters)) if len(chapters) > 0: path0 = chapters[0][1] subpath = os.path.dirname(path0) htmlpath = os.path.join(basedir, subpath) oeb.container = DirContainer(htmlpath, log) for chapter in chapters: title = chapter[0] basename = os.path.basename(chapter[1]) self._add_item(oeb, title, basename) oeb.container = DirContainer(htmlpath, oeb.log) return oeb