def add_quick_start_guide(library_view, refresh_cover_browser=None): from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.covers import calibre_cover2 from calibre.utils.zipfile import safe_replace from calibre.utils.localization import get_lang, canonicalize_lang from calibre.ptempfile import PersistentTemporaryFile l = canonicalize_lang(get_lang()) or 'eng' gprefs['quick_start_guide_added'] = True imgbuf = BytesIO(calibre_cover2(_('Quick Start Guide'), '')) try: with lopen(P('quick_start/%s.epub' % l), 'rb') as src: buf = BytesIO(src.read()) except EnvironmentError as err: if err.errno != errno.ENOENT: raise with lopen(P('quick_start/eng.epub'), 'rb') as src: buf = BytesIO(src.read()) safe_replace(buf, 'images/cover.jpg', imgbuf) buf.seek(0) mi = get_metadata(buf, 'epub') with PersistentTemporaryFile('.epub') as tmp: tmp.write(buf.getvalue()) library_view.model().add_books([tmp.name], ['epub'], [mi]) os.remove(tmp.name) library_view.model().books_added(1) if refresh_cover_browser is not None: refresh_cover_browser() if library_view.model().rowCount(None) < 3: library_view.resizeColumnsToContents()
def add_quick_start_guide(library_view, db_images): from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks import calibre_cover from calibre.utils.zipfile import safe_replace from calibre.utils.localization import get_lang, canonicalize_lang from calibre.ptempfile import PersistentTemporaryFile l = canonicalize_lang(get_lang()) or "eng" gprefs["quick_start_guide_added"] = True imgbuf = BytesIO(calibre_cover(_("Quick Start Guide"), "", author_size=8)) try: with open(P("quick_start/%s.epub" % l), "rb") as src: buf = BytesIO(src.read()) except EnvironmentError as err: if err.errno != errno.ENOENT: raise with open(P("quick_start/eng.epub"), "rb") as src: buf = BytesIO(src.read()) safe_replace(buf, "images/cover.jpg", imgbuf) buf.seek(0) mi = get_metadata(buf, "epub") with PersistentTemporaryFile(".epub") as tmp: tmp.write(buf.getvalue()) library_view.model().add_books([tmp.name], ["epub"], [mi]) os.remove(tmp.name) library_view.model().books_added(1) if hasattr(db_images, "reset"): db_images.reset() if library_view.model().rowCount(None) < 3: library_view.resizeColumnsToContents()
def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True): stream.seek(0) reader = get_zip_reader(stream, root=getcwd()) new_cdata = None try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except Exception: try: with lopen(mi.cover, 'rb') as f: new_cdata = f.read() except Exception: pass opfbytes, ver, raster_cover = set_metadata_opf( reader.read_bytes(reader.opf_path), mi, cover_prefix=posixpath.dirname(reader.opf_path), cover_data=new_cdata, apply_null=apply_null, update_timestamp=update_timestamp, force_identifiers=force_identifiers, add_missing_cover=add_missing_cover) cpath = None replacements = {} if new_cdata and raster_cover: try: cpath = posixpath.join(posixpath.dirname(reader.opf_path), raster_cover) cover_replacable = not reader.encryption_meta.is_encrypted(cpath) and \ os.path.splitext(cpath)[1].lower() in ('.png', '.jpg', '.jpeg') if cover_replacable: replacements[cpath] = serialize_cover_data(new_cdata, cpath) except Exception: import traceback traceback.print_exc() if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], opfbytes, extra_replacements=replacements, add_missing=True) else: safe_replace(stream, reader.container[OPF.MIMETYPE], opfbytes, extra_replacements=replacements, add_missing=True) try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except Exception: pass
def update_cover(self): # get the calibre cover cover_path = self.db.cover(self.book_id, as_path=True) fmt = cover_path.rpartition('.')[-1] new_cover_name = "00000000_cover." + fmt self.make_temp_cbz_file() # search for a previously embeded cover zf = ZipFile(self.file) cover_info = "" for name in zf.namelist(): if name.rsplit(".", 1)[0] == "00000000_cover": cover_info = name break zf.close() # delete previous cover if cover_info != "": with open(self.file, 'r+b') as zf, open(cover_path, 'r+b') as cp: safe_replace(zf, cover_info, cp) # save the cover in the file else: zf = ZipFile(self.file, "a") zf.write(cover_path, new_cover_name) zf.close() delete_temp_file(cover_path)
def update_cover(self): # get the calibre cover cover_path = self.db.cover(self.book_id, as_path=True) fmt = cover_path.rpartition('.')[-1] new_cover_name = "00000000_cover." + fmt self.make_temp_cbz_file() # search for a previously embeded cover zf = ZipFile(self.file) cover_info = "" for name in zf.namelist(): if name.rsplit(".", 1)[0] == "00000000_cover": cover_info = name break # delete previous cover if cover_info != "": with open(self.file, 'r+b') as zf, open(cover_path, 'r+b') as cp: safe_replace(zf, cover_info, cp) # save the cover in the file else: zf = ZipFile(self.file, "a") zf.write(cover_path, new_cover_name) zf.close() delete_temp_file(cover_path)
def add_quick_start_guide(library_view, refresh_cover_browser=None): from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks import calibre_cover from calibre.utils.zipfile import safe_replace from calibre.utils.localization import get_lang, canonicalize_lang from calibre.ptempfile import PersistentTemporaryFile l = canonicalize_lang(get_lang()) or 'eng' gprefs['quick_start_guide_added'] = True imgbuf = BytesIO(calibre_cover(_('Quick Start Guide'), '', author_size=8)) try: with open(P('quick_start/%s.epub' % l), 'rb') as src: buf = BytesIO(src.read()) except EnvironmentError as err: if err.errno != errno.ENOENT: raise with open(P('quick_start/eng.epub'), 'rb') as src: buf = BytesIO(src.read()) safe_replace(buf, 'images/cover.jpg', imgbuf) buf.seek(0) mi = get_metadata(buf, 'epub') with PersistentTemporaryFile('.epub') as tmp: tmp.write(buf.getvalue()) library_view.model().add_books([tmp.name], ['epub'], [mi]) os.remove(tmp.name) library_view.model().books_added(1) if refresh_cover_browser is not None: refresh_cover_browser() if library_view.model().rowCount(None) < 3: library_view.resizeColumnsToContents()
def set_metadata(stream, mi): from calibre.utils.zipfile import safe_replace c = DOCX(stream, extract=False) dp_name, ap_name = c.get_document_properties_names() dp_raw = c.read(dp_name) try: ap_raw = c.read(ap_name) except Exception: ap_raw = None cp = etree.fromstring(dp_raw) update_doc_props(cp, mi) replacements = {} if ap_raw is not None: ap = etree.fromstring(ap_raw) comp = ap.makeelement('{%s}Company' % namespaces['ep']) for child in tuple(ap): if child.tag == comp.tag: ap.remove(child) comp.text = mi.publisher ap.append(comp) replacements[ap_name] = BytesIO(xml2str(ap)) stream.seek(0) safe_replace(stream, dp_name, BytesIO(xml2str(cp)), extra_replacements=replacements)
def save_annots_to_epub(path, serialized_annots): try: zf = open(path, 'r+b') except IOError: return with zf: serialized_annots = EPUB_FILE_TYPE_MAGIC + b'\n'.join(split_lines(as_base64_bytes(serialized_annots))) safe_replace(zf, 'META-INF/calibre_bookmarks.txt', BytesIO(serialized_annots), add_missing=True)
def set_metadata(stream, mi): with ZipFile(stream) as zf: raw = _set_metadata(zf.open('meta.xml').read(), mi) # print(raw.decode('utf-8')) stream.seek(os.SEEK_SET) safe_replace(stream, "meta.xml", io.BytesIO(raw))
def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_identifiers=False): stream.seek(0) reader = get_zip_reader(stream, root=os.getcwdu()) raster_cover = reader.opf.raster_cover mi = MetaInformation(mi) new_cdata = None replacements = {} try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except: try: new_cdata = open(mi.cover, 'rb').read() except: pass new_cover = cpath = None if new_cdata and raster_cover: try: cpath = posixpath.join(posixpath.dirname(reader.opf_path), raster_cover) cover_replacable = not reader.encryption_meta.is_encrypted(cpath) and \ os.path.splitext(cpath)[1].lower() in ('.png', '.jpg', '.jpeg') if cover_replacable: new_cover = _write_new_cover(new_cdata, cpath) replacements[cpath] = open(new_cover.name, 'rb') except: import traceback traceback.print_exc() update_metadata(reader.opf, mi, apply_null=apply_null, update_timestamp=update_timestamp, force_identifiers=force_identifiers) newopf = StringIO(reader.opf.render()) if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], newopf, extra_replacements=replacements) else: safe_replace(stream, reader.container[OPF.MIMETYPE], newopf, extra_replacements=replacements) try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except: pass
def set_metadata(self, stream, mi, type): """Set standard ePub metadata then properly set the cover image.""" common.log.debug( "KEPUBMetadataWriter::set_metadata - self.__class__={0}".format( self.__class__ ) ) super(KEPUBMetadataWriter, self).set_metadata(stream, mi, type) stream.seek(0) reader = get_zip_reader(stream, root=os.getcwd()) found_cover = False covers = reader.opf.raster_cover_path(reader.opf.metadata) if len(covers) > 0: common.log.debug( "KEPUBMetadataWriter::set_metadata - covers={0}".format(covers) ) cover_id = covers[0].get("content") common.log.debug( "KEPUBMetadataWriter::set_metadata - cover_id={0}".format(cover_id) ) for item in reader.opf.itermanifest(): if item.get("id", None) == cover_id: mt = item.get("media-type", "") if mt and mt.startswith("image/"): common.log.debug( "KEPUBMetadataWriter::set_metadata - found cover" ) item.set("properties", "cover-image") found_cover = True break if not found_cover: common.log.debug( "KEPUBMetadataWriter::set_metadata - looking for cover " "using href" ) for item in reader.opf.itermanifest(): if item.get("href", None) == cover_id: mt = item.get("media-type", "") if mt and mt.startswith("image/"): common.log( "KEPUBMetadataWriter::set_metadata -found " "cover" ) item.set("properties", "cover-image") found_cover = True if found_cover: opfbytes = reader.read_bytes(reader.opf_path) if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace( reader.container[OPF.MIMETYPE], opfbytes ) else: safe_replace(stream, reader.container[OPF.MIMETYPE], opfbytes)
def save_bookmarks(self, bookmarks=None, no_copy_to_file=False): if bookmarks is None: bookmarks = self.bookmarks dat = self.serialize_bookmarks(bookmarks) self.config['bookmarks_'+self.pathtoebook] = dat if not no_copy_to_file and self.copy_bookmarks_to_file and os.path.splitext( self.pathtoebook)[1].lower() == '.epub' and os.access(self.pathtoebook, os.W_OK): try: zf = open(self.pathtoebook, 'r+b') except IOError: return safe_replace(zf, 'META-INF/calibre_bookmarks.txt', BytesIO(dat.encode('utf-8')), add_missing=True)
def set_metadata(self, stream, mi, type): """Set standard ePub metadata then properly set the cover image.""" default_log( "KEPUBMetadataWriter::set_metadata - self.__class__={0}".format( self.__class__ ) ) super(KEPUBMetadataWriter, self).set_metadata(stream, mi, type) stream.seek(0) reader = get_zip_reader(stream, root=os.getcwdu()) found_cover = False covers = reader.opf.raster_cover_path(reader.opf.metadata) if len(covers) > 0: default_log("KEPUBMetadataWriter::set_metadata - covers={0}".format(covers)) cover_id = covers[0].get("content") default_log( "KEPUBMetadataWriter::set_metadata - cover_id={0}".format(cover_id) ) for item in reader.opf.itermanifest(): if item.get("id", None) == cover_id: mt = item.get("media-type", "") if mt and mt.startswith("image/"): default_log("KEPUBMetadataWriter::set_metadata - found cover") item.set("properties", "cover-image") found_cover = True break if not found_cover: default_log( "KEPUBMetadataWriter::set_metadata - looking for cover " "using href" ) for item in reader.opf.itermanifest(): if item.get("href", None) == cover_id: mt = item.get("media-type", "") if mt and mt.startswith("image/"): default_log( "KEPUBMetadataWriter::set_metadata -found " "cover" ) item.set("properties", "cover-image") found_cover = True if found_cover: newopf = StringIO(reader.opf.render()) if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], newopf) else: safe_replace(stream, reader.container[OPF.MIMETYPE], newopf)
def set_metadata(self, stream, mi, type): debug_print("KEPUBMetadataWriter::set_metadata - self.__class__=%s" % (self.__class__)) super(KEPUBMetadataWriter, self).set_metadata(stream, mi, type) stream.seek(0) reader = get_zip_reader(stream, root=os.getcwdu()) raster_cover = reader.opf.raster_cover found_cover = False covers = reader.opf.raster_cover_path(reader.opf.metadata) if len(covers) > 0: debug_print("KEPUBMetadataWriter::set_metadata - covers=", covers) cover_id = covers[0].get('content') debug_print("KEPUBMetadataWriter::set_metadata - cover_id=", cover_id) for item in reader.opf.itermanifest(): if item.get('id', None) == cover_id: mt = item.get('media-type', '') if mt and mt.startswith('image/'): debug_print( "KEPUBMetadataWriter::set_metadata - found cover") item.set("properties", "cover-image") found_cover = True break if not found_cover: debug_print( "KEPUBMetadataWriter::set_metadata - looking for cover using href" ) for item in reader.opf.itermanifest(): if item.get('href', None) == cover_id: mt = item.get('media-type', '') if mt and mt.startswith('image/'): debug_print( "KEPUBMetadataWriter::set_metadata -found cover" ) item.set("properties", "cover-image") found_cover = True if found_cover: newopf = StringIO(reader.opf.render()) if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], newopf) else: safe_replace(stream, reader.container[OPF.MIMETYPE], newopf)
def set_metadata(stream, mi): replacements = {} # Get the OPF in the archive. with ZipFile(stream) as zf: opf_path = get_first_opf_name(zf) opf_stream = io.BytesIO(zf.read(opf_path)) opf = OPF(opf_stream) # Cover. new_cdata = None try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except: try: with open(mi.cover, 'rb') as f: new_cdata = f.read() except: pass if new_cdata: cpath = opf.raster_cover if not cpath: cpath = 'cover.jpg' new_cover = _write_new_cover(new_cdata, cpath) replacements[cpath] = open(new_cover.name, 'rb') mi.cover = cpath # Update the metadata. opf.smart_update(mi, replace_metadata=True) newopf = io.BytesIO(opf.render()) safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True) # Cleanup temporary files. try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except: pass
def set_metadata(self, stream, mi, type): debug_print("KEPUBMetadataWriter::set_metadata - self.__class__=%s" % (self.__class__)) super(KEPUBMetadataWriter, self).set_metadata(stream, mi, type) stream.seek(0) reader = get_zip_reader(stream, root=os.getcwdu()) raster_cover = reader.opf.raster_cover found_cover = False covers = reader.opf.raster_cover_path(reader.opf.metadata) if len(covers) > 0: debug_print("KEPUBMetadataWriter::set_metadata - covers=", covers) cover_id = covers[0].get('content') debug_print("KEPUBMetadataWriter::set_metadata - cover_id=", cover_id) for item in reader.opf.itermanifest(): if item.get('id', None) == cover_id: mt = item.get('media-type', '') if mt and mt.startswith('image/'): debug_print( "KEPUBMetadataWriter::set_metadata - found cover") item.set("properties", "cover-image") found_cover = True break if not found_cover: debug_print( "KEPUBMetadataWriter::set_metadata - looking for cover using href") for item in reader.opf.itermanifest(): if item.get('href', None) == cover_id: mt = item.get('media-type', '') if mt and mt.startswith('image/'): debug_print( "KEPUBMetadataWriter::set_metadata -found cover") item.set("properties", "cover-image") found_cover = True if found_cover: newopf = StringIO(reader.opf.render()) if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], newopf) else: safe_replace(stream, reader.container[OPF.MIMETYPE], newopf)
def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True): stream.seek(0) reader = get_zip_reader(stream, root=getcwd()) new_cdata = None try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except Exception: try: with lopen(mi.cover, 'rb') as f: new_cdata = f.read() except Exception: pass opfbytes, ver, raster_cover = set_metadata_opf( reader.read_bytes(reader.opf_path), mi, cover_prefix=posixpath.dirname(reader.opf_path), cover_data=new_cdata, apply_null=apply_null, update_timestamp=update_timestamp, force_identifiers=force_identifiers, add_missing_cover=add_missing_cover) cpath = None replacements = {} if new_cdata and raster_cover: try: cpath = posixpath.join(posixpath.dirname(reader.opf_path), raster_cover) cover_replacable = not reader.encryption_meta.is_encrypted(cpath) and \ os.path.splitext(cpath)[1].lower() in ('.png', '.jpg', '.jpeg') if cover_replacable: replacements[cpath] = serialize_cover_data(new_cdata, cpath) except Exception: import traceback traceback.print_exc() if isinstance(reader.archive, LocalZipFile): reader.archive.safe_replace(reader.container[OPF.MIMETYPE], opfbytes, extra_replacements=replacements, add_missing=True) else: safe_replace(stream, reader.container[OPF.MIMETYPE], opfbytes, extra_replacements=replacements, add_missing=True) try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except: pass
def embed_cix_metadata(self): ''' Embeds the cix_metadata ''' from io import StringIO cix_string = ComicInfoXml().stringFromMetadata(self.comic_metadata) # ensure we have a temp file self.make_temp_cbz_file() # use the safe_replace function from calibre to prevent coruption if self.zipinfo is not None: with open(self.file, 'r+b') as zf: safe_replace(zf, self.zipinfo, StringIO(cix_string.decode('utf-8', 'ignore'))) # save the metadata in the file else: zf = ZipFile(self.file, "a") zf.writestr("ComicInfo.xml", cix_string.decode('utf-8', 'ignore')) zf.close()
def embed_cix_metadata(self): ''' Embeds the cix_metadata ''' from io import StringIO cix_string = ComicInfoXml().stringFromMetadata(self.comic_metadata) # ensure we have a temp file self.make_temp_cbz_file() # make a new cbz if a metadata file is already there, to prevent corruption if self.zipinfo is not None: with open(self.file, 'r+b') as zf: safe_replace(zf, self.zipinfo, StringIO(cix_string.decode('utf-8', 'ignore'))) else: # save the metadata in the file zf = ZipFile(self.file, "a") zf.writestr("ComicInfo.xml", cix_string.decode('utf-8', 'ignore')) zf.close()
def set_metadata(stream, mi): replacements = {} # Get the OPF in the archive. with ZipFile(stream) as zf: opf_path = get_first_opf_name(zf) opf_stream = StringIO(zf.read(opf_path)) opf = OPF(opf_stream) # Cover. new_cdata = None try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except: try: new_cdata = open(mi.cover, 'rb').read() except: pass if new_cdata: cpath = opf.raster_cover if not cpath: cpath = 'cover.jpg' new_cover = _write_new_cover(new_cdata, cpath) replacements[cpath] = open(new_cover.name, 'rb') mi.cover = cpath # Update the metadata. opf.smart_update(mi, replace_metadata=True) newopf = StringIO(opf.render()) safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True) # Cleanup temporary files. try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except: pass
def set_metadata(stream, mi, apply_null=False, update_timestamp=False): stream.seek(0) reader = OCFZipReader(stream, root=os.getcwdu()) raster_cover = reader.opf.raster_cover mi = MetaInformation(mi) new_cdata = None replacements = {} try: new_cdata = mi.cover_data[1] if not new_cdata: raise Exception('no cover') except: try: new_cdata = open(mi.cover, 'rb').read() except: pass new_cover = cpath = None if new_cdata and raster_cover: try: cpath = posixpath.join(posixpath.dirname(reader.opf_path), raster_cover) cover_replacable = not reader.encryption_meta.is_encrypted(cpath) and \ os.path.splitext(cpath)[1].lower() in ('.png', '.jpg', '.jpeg') if cover_replacable: new_cover = _write_new_cover(new_cdata, cpath) replacements[cpath] = open(new_cover.name, 'rb') except: import traceback traceback.print_exc() for x in ('guide', 'toc', 'manifest', 'spine'): setattr(mi, x, None) if mi.languages: langs = [] for lc in mi.languages: lc2 = lang_as_iso639_1(lc) if lc2: lc = lc2 langs.append(lc) mi.languages = langs reader.opf.smart_update(mi) if apply_null: if not getattr(mi, 'series', None): reader.opf.series = None if not getattr(mi, 'tags', []): reader.opf.tags = [] if not getattr(mi, 'isbn', None): reader.opf.isbn = None if update_timestamp and mi.timestamp is not None: reader.opf.timestamp = mi.timestamp newopf = StringIO(reader.opf.render()) safe_replace(stream, reader.container[OPF.MIMETYPE], newopf, extra_replacements=replacements) try: if cpath is not None: replacements[cpath].close() os.remove(replacements[cpath].name) except: pass