def test_epub3_covers(self): # cover image ce = partial(self.create_epub, ver=3) c = ce([cmi('c.jpg')]) self.assertIsNone(find_cover_image(c)) c = ce([cmi('c.jpg')], meta_cover='c.jpg') self.assertEqual('c.jpg', find_cover_image(c)) c = ce([cmi('c.jpg', b'z', 'cover-image'), cmi('d.jpg')], meta_cover='d.jpg') self.assertEqual('c.jpg', find_cover_image(c)) mark_as_cover(c, 'd.jpg') self.assertEqual('d.jpg', find_cover_image(c)) self.assertFalse(c.opf_xpath('//*/@name')) # title page c = ce([cmi('c.html'), cmi('a.html')]) self.assertIsNone(find_cover_page(c)) mark_as_titlepage(c, 'a.html', move_to_start=False) self.assertEqual('a.html', find_cover_page(c)) self.assertEqual('c.html', next(c.spine_names)[0]) mark_as_titlepage(c, 'a.html', move_to_start=True) self.assertEqual('a.html', find_cover_page(c)) self.assertEqual('a.html', next(c.spine_names)[0]) # clean opf of all cover information c = ce([cmi('c.jpg', b'z', 'cover-image'), cmi('c.html', b'', 'calibre:title-page'), cmi('d.html')], meta_cover='c.jpg', guide=[('c.jpg', 'cover'), ('d.html', 'cover')]) self.assertEqual(set(clean_opf(c)), {'c.jpg', 'c.html', 'd.html'}) self.assertFalse(c.opf_xpath('//*/@name')) self.assertFalse(c.opf_xpath('//*/@type')) for prop in 'cover-image calibre:title-page'.split(): self.assertEqual([], list(c.manifest_items_with_property(prop)))
def find_epub_cover(container): cover_image = find_cover_image(container) marked_title_page = find_cover_page(container) cover_image_in_first_page = None first_page_name = next(container.spine_names)[0] if not marked_title_page: cover_image_in_first_page = find_cover_image_in_page( container, first_page_name) has_epub_cover = cover_image or marked_title_page or cover_image_in_first_page if not has_epub_cover: return None, None if marked_title_page and cover_image: return marked_title_page, cover_image if marked_title_page: if cover_image: return marked_title_page, cover_image cover_image = find_cover_image_in_page(container, marked_title_page) if cover_image: return marked_title_page, cover_image return None, None if cover_image_in_first_page: return first_page_name, cover_image_in_first_page return None, None
def create_cover_page(self, input_fmt): templ = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><style> html, body, img { height: 100%%; display: block; margin: 0; padding: 0; border-width: 0; } img { width: auto; margin-left:auto; margin-right: auto; } </style></head><body><img src="%s"/></body></html> ''' if input_fmt == 'epub': def cover_path(action, data): if action == 'write_image': data.write(BLANK_JPEG) return set_epub_cover(self, cover_path, (lambda *a: None), options={'template':templ}) raster_cover_name = find_cover_image(self, strict=True) if raster_cover_name is None: item = self.generate_item(name='cover.jpeg', id_prefix='cover') raster_cover_name = self.href_to_name(item.get('href'), self.opf_name) with self.open(raster_cover_name, 'wb') as dest: dest.write(BLANK_JPEG) item = self.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = self.href_to_name(item.get('href'), self.opf_name) raw = templ % prepare_string_for_xml(self.name_to_href(raster_cover_name, titlepage_name), True) with self.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = self.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) self.insert_into_xml(spine, ref, index=0) self.dirty(self.opf_name) return raster_cover_name, titlepage_name
def create_cover_page(self, input_fmt): if input_fmt == 'epub': def cover_path(action, data): if action == 'write_image': data.write(BLANK_JPEG) return set_epub_cover(self, cover_path, (lambda *a: None)) from calibre.ebooks.oeb.transforms.cover import CoverManager raster_cover_name = find_cover_image(self, strict=True) if raster_cover_name is None: item = self.generate_item(name='cover.jpeg', id_prefix='cover') raster_cover_name = self.href_to_name(item.get('href'), self.opf_name) with self.open(raster_cover_name, 'wb') as dest: dest.write(BLANK_JPEG) item = self.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = self.href_to_name(item.get('href'), self.opf_name) templ = CoverManager.SVG_TEMPLATE raw = templ % self.name_to_href(raster_cover_name, titlepage_name) with self.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = self.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) self.insert_into_xml(spine, ref, index=0) self.dirty(self.opf_name) return raster_cover_name, titlepage_name
def create_cover_page(self, input_fmt): templ = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><style> html, body, img { height: 100%%; display: block; margin: 0; padding: 0; border-width: 0; } img { width: auto; margin-left:auto; margin-right: auto; } </style></head><body><img src="%s"/></body></html> ''' if input_fmt == 'epub': def cover_path(action, data): if action == 'write_image': data.write(BLANK_JPEG) return set_epub_cover(self, cover_path, (lambda *a: None), options={'template': templ}) raster_cover_name = find_cover_image(self, strict=True) if raster_cover_name is None: item = self.generate_item(name='cover.jpeg', id_prefix='cover') raster_cover_name = self.href_to_name(item.get('href'), self.opf_name) with self.open(raster_cover_name, 'wb') as dest: dest.write(BLANK_JPEG) item = self.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = self.href_to_name(item.get('href'), self.opf_name) raw = templ % prepare_string_for_xml( self.name_to_href(raster_cover_name, titlepage_name), True) with self.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = self.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) self.insert_into_xml(spine, ref, index=0) self.dirty(self.opf_name) return raster_cover_name, titlepage_name
def create_cover_page(self, input_fmt): templ = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><style> html, body, img { height: 100vh; display: block; margin: 0; padding: 0; border-width: 0; } img { width: 100%%; height: 100%%; object-fit: contain; margin-left: auto; margin-right: auto; max-width: 100vw; max-height: 100vh; top: 50vh; transform: translateY(-50%%); position: relative; } body.cover-fill img { object-fit: fill; } </style></head><body><img src="%s"/></body></html> ''' def generic_cover(): if self.book_metadata is not None: from calibre.ebooks.covers import create_cover mi = self.book_metadata return create_cover(mi.title, mi.authors, mi.series, mi.series_index) return BLANK_JPEG if input_fmt == 'epub': def image_callback(cover_image, wrapped_image): if cover_image: image_callback.cover_data = self.raw_data(cover_image, decode=False) if wrapped_image and not getattr(image_callback, 'cover_data', None): image_callback.cover_data = self.raw_data(wrapped_image, decode=False) def cover_path(action, data): if action == 'write_image': cdata = getattr(image_callback, 'cover_data', None) or generic_cover() data.write(cdata) raster_cover_name, titlepage_name = set_epub_cover( self, cover_path, (lambda *a: None), options={'template':templ}, image_callback=image_callback) else: raster_cover_name = find_cover_image(self, strict=True) if raster_cover_name is None: item = self.generate_item(name='cover.jpeg', id_prefix='cover') raster_cover_name = self.href_to_name(item.get('href'), self.opf_name) with self.open(raster_cover_name, 'wb') as dest: dest.write(generic_cover()) item = self.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = self.href_to_name(item.get('href'), self.opf_name) raw = templ % prepare_string_for_xml(self.name_to_href(raster_cover_name, titlepage_name), True) with self.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = self.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) self.insert_into_xml(spine, ref, index=0) self.dirty(self.opf_name) return raster_cover_name, titlepage_name
def test_epub2_covers(self): # cover image ce = partial(self.create_epub, ver=2) c = ce([cmi('c.jpg')]) self.assertIsNone(find_cover_image(c)) c = ce([cmi('c.jpg')], meta_cover='c.jpg') self.assertEqual('c.jpg', find_cover_image(c)) c = ce([cmi('c.jpg'), cmi('d.jpg')], guide=[('c.jpg', 'cover')]) self.assertEqual('c.jpg', find_cover_image(c)) mark_as_cover(c, 'd.jpg') self.assertEqual('d.jpg', find_cover_image(c)) self.assertEqual({'cover':'d.jpg'}, c.guide_type_map) # title page c = ce([cmi('c.html'), cmi('a.html')]) self.assertIsNone(find_cover_page(c)) mark_as_titlepage(c, 'a.html', move_to_start=False) self.assertEqual('a.html', find_cover_page(c)) self.assertEqual('c.html', next(c.spine_names)[0]) mark_as_titlepage(c, 'a.html', move_to_start=True) self.assertEqual('a.html', find_cover_page(c)) self.assertEqual('a.html', next(c.spine_names)[0])
def create_cover_page(container, input_fmt, is_comic, book_metadata=None): templ = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><style> html, body, img { height: 100vh; display: block; margin: 0; padding: 0; border-width: 0; } img { width: 100%%; height: 100%%; object-fit: contain; margin-left: auto; margin-right: auto; max-width: 100vw; max-height: 100vh; top: 50vh; transform: translateY(-50%%); position: relative; } body.cover-fill img { object-fit: fill; } </style></head><body><img src="%s"/></body></html> ''' def generic_cover(): if book_metadata is not None: from calibre.ebooks.covers import create_cover mi = book_metadata return create_cover(mi.title, mi.authors, mi.series, mi.series_index) return BLANK_JPEG if input_fmt == 'epub': titlepage_name, raster_cover_name = find_epub_cover(container) if raster_cover_name and titlepage_name: raw = templ % prepare_string_for_xml( container.name_to_href(raster_cover_name, titlepage_name), True) with container.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) else: raster_cover_name = find_cover_image(container, strict=True) if raster_cover_name is None: return None, None if is_comic: return raster_cover_name, None item = container.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = container.href_to_name(item.get('href'), container.opf_name) raw = templ % prepare_string_for_xml( container.name_to_href(raster_cover_name, titlepage_name), True) with container.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = container.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) container.insert_into_xml(spine, ref, index=0) return raster_cover_name, titlepage_name
def create_cover_page(self, input_fmt): templ = ''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><style> html, body, img { height: 100vh; display: block; margin: 0; padding: 0; border-width: 0; } img { width: auto; height: auto; margin-left: auto; margin-right: auto; max-width: 100vw; max-height: 100vh } </style></head><body><img src="%s"/></body></html> ''' blank = {'q': False} if input_fmt == 'epub': def cover_path(action, data): if action == 'write_image': data.write(BLANK_JPEG) blank['q'] = True raster_cover_name, titlepage_name = set_epub_cover( self, cover_path, (lambda *a: None), options={'template': templ}) else: raster_cover_name = find_cover_image(self, strict=True) if raster_cover_name is None: item = self.generate_item(name='cover.jpeg', id_prefix='cover') raster_cover_name = self.href_to_name(item.get('href'), self.opf_name) with self.open(raster_cover_name, 'wb') as dest: dest.write(BLANK_JPEG) blank['q'] = True item = self.generate_item(name='titlepage.html', id_prefix='titlepage') titlepage_name = self.href_to_name(item.get('href'), self.opf_name) raw = templ % prepare_string_for_xml( self.name_to_href(raster_cover_name, titlepage_name), True) with self.open(titlepage_name, 'wb') as f: f.write(raw.encode('utf-8')) spine = self.opf_xpath('//opf:spine')[0] ref = spine.makeelement(OPF('itemref'), idref=item.get('id')) self.insert_into_xml(spine, ref, index=0) self.dirty(self.opf_name) if blank['q'] and self.book_metadata is not None: authors = authors_to_string(self.book_metadata.authors) title = self.book_metadata.title with self.open(titlepage_name, 'wb') as f: f.write(''' <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head><meta charset="utf-8"/></head> <body> <div style="position: fixed; top: 50%; width: 100vw; transform: translateY(-50%)"> <h1 style="text-align: center; margin: auto">{title}</h1> <p>\xa0</p> <h3 style="text-align: center; margin: auto; font-style: italic">{authors}</h3> </div> </body> </html> '''.format(title=title, authors=authors).encode('utf-8')) return raster_cover_name, titlepage_name
def scramble_main(self): # NB: an epub3 nav.xhtml file will currently be scrambled by HTML rules not NCX rules textnames = get_textnames(self.eb) if self.dsettings['x_html']: [ self.scramble_html(n, scramble_dgts=self.dsettings['x_dgts']) for n in textnames ] self.log.append(' Scrambled text content') self.ncxnames = get_ncxnames(self.eb) # no need to scramble digits in a TOC if self.dsettings['x_toc']: if len(self.ncxnames) > 0: self.scramble_toc(self.ncxnames[0], scramble_dgts=False) self.log.append(' Scrambled TOC') svgnames = get_imgnames(self.eb, SVG_MIME) imgnames = get_imgnames(self.eb, OEB_RASTER_IMAGES) if self.dsettings['x_imgs']: cover_img_name = find_cover_image(self.eb, strict=True) cover_img_names = [] if self.dsettings['keep_cover']: if cover_img_name: cover_img_names.append(cover_img_name) [ self.scramble_img(n) for n in imgnames if n not in cover_img_names ] for svgn in [n for n in svgnames if n not in cover_img_names]: #self.eb.remove_item(svgn) data = self.eb.parsed(svgn) self.eb.replace(svgn, self.dummysvg) self.log.append(' Replaced images') fontnames = get_fontnames(self.eb) if len(fontnames) > 0 and (self.dsettings['x_fontsno'] or self.dsettings['x_fontsob']): self.log.append(' Removed these fonts:') if self.dsettings['x_fontsno']: # remove non-obfuscated embedded fonts for name in [ n for n in fontnames if n not in self.eb.obfuscated_fonts ]: self.eb.remove_item(name) self.log.append(' - non-obfuscated font: %s' % name) if self.dsettings['x_fontsob']: # remove obfuscated embedded fonts for name in [n for n in self.eb.obfuscated_fonts]: self.eb.remove_item(name) self.log.append(' - obfuscated font: %s' % name) if self.dsettings['x_meta']: self.scramble_metadata() msg = ' Removed basic metadata' if self.dsettings['x_meta_extra']: msg += ' & extra metadata' self.log.append(msg) if self.dsettings['x_fnames']: spine_names = tuple([ n for n in get_spinenames(self.eb) if n not in self.eb.names_that_must_not_be_changed ]) self.scramble_filenames(spine_names, 'txcontent_') svgnames = get_imgnames(self.eb, SVG_MIME) img_names = tuple([ n for n in imgnames + svgnames if n not in self.eb.names_that_must_not_be_changed ]) self.scramble_filenames(img_names, 'img_') css_names = tuple([ n for n in get_cssnames(self.eb) if n not in self.eb.names_that_must_not_be_changed ]) self.scramble_filenames(css_names, 'style_') if self.file_map: rename_files(self.eb, self.file_map) self.log.append(' Renamed internal files:') [ self.log.append(' %s \t--> %s' % (old, self.file_map.get(old, old))) for old in spine_names + img_names + css_names ]