def makeEPUB(self): # add the mimetype file uncompressed mimetype = 'application/epub+zip' fileout = os.path.join(self.outdir,'mimetype') open(fileout,'wb').write(mimetype.encode('utf-8')) epub_zip_up_book_contents(self.outdir, self.epubname) return self.epubname
def save_result(tempDir): # 询问放置修改后epub文件的位置 doctitle = "newepub" fname = cleanup_file_name(doctitle) + "_noteChanger.epub" localRoot = tkinter.Tk() localRoot.withdraw() fpath = tkinter_filedialog.asksaveasfilename(parent=localRoot, title="存储为 ...", initialfile=fname, initialdir=_USER_HOME, defaultextension=".epub") localRoot.quit() if not fpath: print("用户取消了保存修改后的epub文件") else: epub_zip_up_book_contents(tempDir, fpath) print("文件转化完成") shutil.rmtree(tempDir) # 删除临时文件 return 0
def run(bk): if not bk.epub_version().startswith('3'): print('Error: NCXRemove requires a valid EPUB 3.0 ebook as input') return -1 try: from PyQt5.QtWidgets import QApplication except ImportError: GUI = 'tkinter' else: GUI = 'pyqt' ncxid = bk.gettocid() if ncxid is None: print('Error: EPUB 3.0 ebook has no NCX') return -1 ncxhref = bk.id_to_href(ncxid) prefs = bk.getPrefs() # set default preference values if 'use_file_path' not in prefs: prefs['use_file_path'] = os.path.expanduser('~') if 'check_for_updates' not in prefs: prefs['check_for_updates'] = True if 'last_time_checked' not in prefs: prefs['last_time_checked'] = str(datetime.now() - timedelta(hours=12)) if 'last_online_version' not in prefs: prefs['last_online_version'] = '0.1.0' if prefs['check_for_updates']: chk = UpdateChecker(prefs['last_time_checked'], prefs['last_online_version'], bk._w) update_available, online_version, time = chk.update_info() # update preferences with latest date/time/version prefs['last_time_checked'] = time if online_version is not None: prefs['last_online_version'] = online_version if update_available: title = 'Plugin Update Available' msg = 'Version {} of the {} plugin is now available.'.format( online_version, bk._w.plugin_name) update_msgbox(title, msg, GUI) if _DEBUG_: print('Python sys.path', sys.path) doctitle = getTitle(bk.getmetadataxml()) fname = cleanup_file_name(doctitle) + '_no_ncx.epub' outpath = fileChooser(fname, prefs['use_file_path'], GUI) if not outpath: print("NCXRemove plugin cancelled by user") return 0 with make_temp_directory() as temp_dir: bk.copy_book_contents_to(temp_dir) opfdata = bk.readotherfile("OEBPS/content.opf").splitlines() opfout = os.path.join(temp_dir, 'OEBPS', 'content.opf') ncxfile = os.path.join(temp_dir, 'OEBPS', ncxhref) open(os.path.join(temp_dir, 'mimetype'), 'wb').write('application/epub+zip'.encode('utf-8')) newopf = '' ncxitem = 'id="{}"'.format(ncxid) spineattr = ' toc="{}"'.format(ncxid) for line in opfdata: skip = False # Remove ncx item from the manifest of the OPF if line.lstrip().startswith('<item ') and line.find( ncxitem) is not -1: skip = True # Remove the ncx attribute from the spine tag of the OPF if line.lstrip().startswith('<spine') and line.find( spineattr) is not -1: line = line.replace(spineattr, '') if not skip: newopf += line + '\n' if _DEBUG_: print(line) # Write new OPF to temp directory open(opfout, 'wb').write(newopf.encode('utf-8')) # Delete the the toc.ncx file from the temp directory os.remove(ncxfile) # Build the new epub from the tmp structure and save to specified location epub_zip_up_book_contents(temp_dir, outpath) # Save last directory accessed to JSON prefs prefs['use_file_path'] = os.path.dirname(outpath) # Save prefs to json bk.savePrefs(prefs) # print ('Path to epub or src {0}'.format(epub)) return 0
def run(bk): def ncx_iter(): # yields manifest id, href for id in sorted(bk._w.id_to_mime): mime = bk._w.id_to_mime[id] if mime == 'application/x-dtbncx+xml': href = bk._w.id_to_href[id] yield id, href if bk.epub_version() == '2.0': print('EPUB2 doesn\'t require any fixes') return 0 navid = None oldnavpath = None for item in bk.manifest_epub3_iter(): prop = item[3] if prop: prop = prop.split(' ') if 'nav' in prop: navid = item[0] oldnavpath = item[1] break if not navid: print('No XHTML TOC') return 1 fpath = None if 'OUTPUTFILE' in os.environ: fpath = os.environ['OUTPUTFILE'] else: # ask the user where he/she wants to store the new epub # TODO use dc:title from the OPF file instead doctitle = "filename" fname = cleanup_file_name(doctitle) + ".epub" localRoot = tkinter.Tk() localRoot.withdraw() fpath = tkinter_filedialog.asksaveasfilename( parent=localRoot, title="Save EPUB As...", initialfile=fname, initialdir=_USER_HOME, defaultextension=".epub" ) # localRoot.destroy() localRoot.quit() if not fpath: print("Saving cancelled by user") return 0 temp_dir = tempfile.mkdtemp() bk.copy_book_contents_to(temp_dir) root = os.path.join(temp_dir, 'OEBPS') # move the toc file to OEBPS root navpath = os.path.basename(oldnavpath) os.rename(os.path.join(root, oldnavpath), os.path.join(root, navpath)) bk._w.id_to_href[navid] = navpath bk._w.modified['OEBPS/content.opf'] = 'file' # update guide reference guide = bk._w.guide for item in guide: index = guide.index(item) if os.path.normpath(item[2]) == os.path.normpath(oldnavpath): item = item[0:2] + tuple([navpath]) guide[index] = item # replace references to nav xhtml for itemid, href in bk.text_iter(): replaceHrefs(root, href, oldnavpath, navpath, 1 if itemid == navid else 0, bk.readfile(itemid)) # same as above, but for ncx toc for itemid, href in ncx_iter(): replaceHrefs(root, href, oldnavpath, navpath, 2, bk.readfile(itemid)) write_file(bk.get_opf(), os.path.join(root, bk._w.opfname)) print('Guide:', bk._w.guide) write_file("application/epub+zip", os.path.join(temp_dir, "mimetype")) print('Saving EPUB to', fpath) epub_zip_up_book_contents(temp_dir, fpath) shutil.rmtree(temp_dir) print("Output Conversion Complete") # Setting the proper Return value is important. # 0 - means success # anything else means failure return 0
def run(bk): # protect against epub3 epubs being sent to ePub3-itizer epubversion = "2.0" if bk.launcher_version() >= 20160102: epubversion = bk.epub_version() if epubversion.startswith("3"): print("Error: ePub3-itizer requires a valid epub 2.0 ebook as input") return -1 prefs = bk.getPrefs() prefs.defaults['lastdir'] = _USER_HOME basepath = prefs['lastdir'] basename = "" if bk.launcher_version() >= 20180122: filepath = bk.get_epub_filepath() if filepath != "": basepath = os.path.dirname(filepath) basename = os.path.basename(filepath) basename = os.path.splitext(basename)[0] + "_epub3.epub" manifest_properties = {} spine_properties = {} mo_properties = {} epub_types = {} temp_dir = tempfile.mkdtemp() # copy all files to a temporary destination folder # to get all fonts, css, images, and etc bk.copy_book_contents_to(temp_dir) # parse all xhtml/html files for mid, href in bk.text_iter(): bookhref = "OEBPS/" + href if bk.launcher_version() >= 20190927: bookhref = bk.id_to_bookpath(mid) print("..converting: ", href, " with manifest id: ", mid) data, mprops, sprops, etypes = convert_xhtml(bk, mid, bookhref) # store away manifest and spine properties and any links # to epub:types for later use in opf3 if len(sprops) > 0: spine_properties[mid] = " ".join(sprops) if len(mprops) > 0: manifest_properties[mid] = " ".join(mprops) if len(etypes) > 0: epub_types[mid] = etypes # write out modified file bookhref = "OEBPS/" + href if bk.launcher_version() >= 20190927: bookhref = bk.id_to_bookpath(mid) write_file(data, bookhref, temp_dir, unquote_filename=True) # detect smil files # this will be broken in Sigil 1.0 which no longer moves anything # and therefore has no firm locations for anything anymore # so we should be updating these inside Sigil itself (I think) # when we do move things. Not sure really so I will disable this # until I can follow what is exactly being updated and why # for mid, href, mt in bk.manifest_iter(): # if mt == "application/smil+xml": # bookhref = "OEBPS/" + href # if bk.launcher_version() >= 20190927: # bookhref = bk.id_to_bookpath(mid) # print("..patching: ", bookhref, " with manifest id: ", mid) # data, text_ids, audio_ids, duration = patch_smil(bk, mid, bookhref) # # store mo properties to add # # <meta property="media:duration" ...> elements # # and media-overlay attributes to opf3 # # text_ids: list of manifest ids of text files referenced by the smil file # # audio_ids: list of manifest ids of audio files referenced by the smil file # # duration: float, the duration (in seconds) of the smil file # mo_properties[mid] = { # "href": bookhref, # "text_ids": text_ids, # "audio_ids": audio_ids, # "duration": duration # } # # write out modified file # write_file(data, bookhref, temp_dir, unquote_filename=True) # now convert the opf opfbookhref = "OEBPS/content.opf" if bk.launcher_version() >= 20190927: opfbookhref = bk.get_opfbookpath() print("..converting: ", opfbookhref) # first create a list of all ids used in the epub2 opf manifest to help # prevent id clashes when generating new metadta ids for refines in the new opf man_ids = [] for (id, href, mime) in bk.manifest_iter(): man_ids.append(id) # now parse opf2 converting it to opf3 format # while merging in previously collected spine and manifest properties opf2 = bk.readotherfile(opfbookhref) opfconv = Opf_Converter(opf2, spine_properties, manifest_properties, mo_properties, man_ids) lang = opfconv.get_lang() uid = opfconv.get_uid() opf3 = opfconv.get_opf3() guide_info = opfconv.get_guide() # It is possible that the original EPUB2 <guide> contains references # to files not in the spine; # putting those "dangling" references in the EPUB3 navigation document # will result in validation error: # RSC-011 "Found a reference to a resource that is not a spine item.". # Hence, we must check that the referenced files are listed in the spine. guide_info_in_spine = [] spine_hrefs = [t[2] for t in bk.spine_iter()] for gtyp, gtitle, ghref in guide_info: if ghref in spine_hrefs: guide_info_in_spine.append((gtyp, gtitle, ghref)) else: print( "..info: the EPUB2 <guide> contains a reference to a resource that is not a spine item: '", ghref, "', not adding it to the guide landmark in nav.xhtml") # now convert all guide hrefs from opf relative to book hrefs new_guide_info = [] for gtyp, gtitle, ghref in guide_info_in_spine: gbookhref = "OEBPS/" + href if bk.launcher_version() >= 20190927: ahref, asep, afrag = ghref.partition('#') opf_base = bk.get_startingdir(opfbookhref) gbookhref = bk.build_bookpath(ahref, opf_base) + asep + afrag new_guide_info.append((gtyp, gtitle, gbookhref)) guide_info_in_spine = new_guide_info write_file(opf3, opfbookhref, temp_dir) # need to take info from the old opf2 guide, epub_type semantics info # and toc.ncx to create a valid "nav.xhtml" # and update it to remove any doctype ncxbookhref = "OEBPS/toc.ncx" if bk.launcher_version() >= 20190927: ncxid = bk.gettocid() ncxbookhref = bk.id_to_bookpath(ncxid) print("..parsing: ", ncxbookhref) doctitle, toclist, pagelist = parse_ncx(bk, ncxbookhref, temp_dir, uid) # now build up a nav # place the new nav.xhtml right beside the current opf navbookhref = "OEBPS/nav.xhtml" if bk.launcher_version() >= 20190927: opfbookpath = bk.get_opfbookpath() navbookhref = "nav.xhtml" base = bk.get_startingdir(opfbookpath) navbookhref = bk.build_bookpath("nav.xhtml", base) print("..creating: ", navbookhref) navdata = build_nav(bk, navbookhref, doctitle, toclist, pagelist, guide_info_in_spine, epub_types, lang) write_file(navdata, navbookhref, temp_dir) # finally ready to build epub print("..creating: epub3") data = "application/epub+zip" write_file(data, "mimetype", temp_dir) # ask the user where he/she wants to store the new epub if basename == "": if doctitle is None or doctitle == "": doc = "filename" basename = cleanup_file_name(doctitle) + "_epub3.epub" localRoot = tkinter.Tk() localRoot.withdraw() if sys.platform.startswith('darwin'): # localRoot is is an empty topmost root window that is hidden by withdrawing it # but localRoot needs to be centred, and lifted and focus_force used # so that its child dialog will inherit focus upon launch localRoot.overrideredirect(True) # center on screen but make size 0 to hide the empty localRoot w = localRoot.winfo_screenwidth() h = localRoot.winfo_screenheight() x = int(w / 2) y = int(h / 2) localRoot.geometry('%dx%d+%d+%d' % (0, 0, x, y)) localRoot.deiconify() localRoot.lift() localRoot.focus_force() fpath = tkinter_filedialog.asksaveasfilename(parent=localRoot, title="Save ePub3 as ...", initialfile=basename, initialdir=basepath, defaultextension=".epub") # localRoot.destroy() localRoot.quit() if not fpath: shutil.rmtree(temp_dir) print("ePub3-itizer plugin cancelled by user") return 0 epub_zip_up_book_contents(temp_dir, fpath) shutil.rmtree(temp_dir) prefs['lastdir'] = os.path.dirname(fpath) bk.savePrefs(prefs) print("Output Conversion Complete") # Setting the proper Return value is important. # 0 - means success # anything else means failure return 0
def run(bk): # protect against epub3 epubs being sent to ePub3-itizer epubversion = "2.0" if bk.launcher_version() >= 20160102: epubversion = bk.epub_version() if epubversion.startswith("3"): print("Error: ePub3-itizer requires a valid epub 2.0 ebook as input") return -1 manifest_properties = {} spine_properties = {} mo_properties = {} epub_types = {} temp_dir = tempfile.mkdtemp() # copy all files to a temporary destination folder # to get all fonts, css, images, and etc bk.copy_book_contents_to(temp_dir) # parse all xhtml/html files for mid, href in bk.text_iter(): print("..converting: ", href, " with manifest id: ", mid) data, mprops, sprops, etypes = convert_xhtml(bk, mid, href) # store away manifest and spine properties and any links # to epub:types for later use in opf3 if len(sprops) > 0: spine_properties[mid] = " ".join(sprops) if len(mprops) > 0: manifest_properties[mid] = " ".join(mprops) if len(etypes) > 0: epub_types[mid] = etypes # write out modified file write_file(data, href, temp_dir, unquote_filename=True) # detect smil files for mid, href, mt in bk.manifest_iter(): if mt == "application/smil+xml": print("..patching: ", href, " with manifest id: ", mid) data, text_ids, audio_ids, duration = patch_smil(bk, mid, href) # store mo properties to add # <meta property="media:duration" ...> elements # and media-overlay attributes to opf3 # text_ids: list of manifest ids of text files referenced by the smil file # audio_ids: list of manifest ids of audio files referenced by the smil file # duration: float, the duration (in seconds) of the smil file mo_properties[mid] = { "href": href, "text_ids": text_ids, "audio_ids": audio_ids, "duration": duration } # write out modified file write_file(data, href, temp_dir, unquote_filename=True) print("..converting: OEBPS/content.opf") # first create a list of all ids used in the epub2 opf manifest to help # prevent id clashes when generating new metadta ids for refines in the new opf man_ids = [] for (id, href, mime) in bk.manifest_iter(): man_ids.append(id) # now parse opf2 converting it to opf3 format # while merging in previously collected spine and manifest properties opf2 = bk.readotherfile("OEBPS/content.opf") opfconv = Opf_Converter(opf2, spine_properties, manifest_properties, mo_properties, man_ids) guide_info = opfconv.get_guide() lang = opfconv.get_lang() opf3 = opfconv.get_opf3() write_file(opf3, "content.opf", temp_dir) # It is possible that the original EPUB2 <guide> contains references # to files not in the spine; # putting those "dangling" references in the EPUB3 navigation document # will result in validation error: # RSC-011 "Found a reference to a resource that is not a spine item.". # Hence, we must check that the referenced files are listed in the spine. guide_info_in_spine = [] spine_hrefs = [t[2] for t in bk.spine_iter()] for gtyp, gtitle, ghref in guide_info: if ghref in spine_hrefs: guide_info_in_spine.append((gtyp, gtitle, ghref)) else: print( "..info: the EPUB2 <guide> contains a reference to a resource that is not a spine item: '", ghref, "', not adding it to the guide landmark in nav.xhtml") # need to take info from the old opf2 guide, epub_type semantics info # and toc.ncx to create a valid "nav.xhtml" # and update it to remove any doctype print("..parsing: OEBPS/toc.ncx") doctitle, toclist, pagelist = parse_ncx(bk, temp_dir) # now build up a nav print("..creating: OEBPS/nav.xhtml") navdata = build_nav(doctitle, toclist, pagelist, guide_info_in_spine, epub_types, lang) write_file(navdata, "nav.xhtml", temp_dir) # finally ready to build epub print("..creating: epub3") data = "application/epub+zip" write_file(data, "mimetype", temp_dir, in_oebps=False) # ask the user where he/she wants to store the new epub # TODO use dc:title from the OPF file instead if doctitle is None or doctitle == "": doctitle = "filename" fname = cleanup_file_name(doctitle) + "_epub3.epub" localRoot = tkinter.Tk() localRoot.withdraw() if sys.platform.startswith('darwin'): # localRoot is is an empty topmost root window that is hidden by withdrawing it # but localRoot needs to be centred, and lifted and focus_force used # so that its child dialog will inherit focus upon launch localRoot.overrideredirect(True) # center on screen but make size 0 to hide the empty localRoot w = localRoot.winfo_screenwidth() h = localRoot.winfo_screenheight() x = int(w / 2) y = int(h / 2) localRoot.geometry('%dx%d+%d+%d' % (0, 0, x, y)) localRoot.deiconify() localRoot.lift() localRoot.focus_force() fpath = tkinter_filedialog.asksaveasfilename(parent=localRoot, title="Save ePub3 as ...", initialfile=fname, initialdir=_USER_HOME, defaultextension=".epub") # localRoot.destroy() localRoot.quit() if not fpath: shutil.rmtree(temp_dir) print("ePub3-itizer plugin cancelled by user") return 0 epub_zip_up_book_contents(temp_dir, fpath) shutil.rmtree(temp_dir) print("Output Conversion Complete") # Setting the proper Return value is important. # 0 - means success # anything else means failure return 0
def run(bk): # check if inifile exists if not os.path.isfile(ini_path): print("Borkify.ini not found. Using default settings.") write_ini(ini_path) # run plugin version check href = 'http://www.mobileread.com/forums/showpost.php?p=' '3138237&postcount=1' _latest_pattern = re.compile(r'Current Version:\s*"([^&]*)&') plugin_xml_path = os.path.abspath( os.path.join(bk._w.plugin_dir, 'Borkify', 'plugin.xml')) plugin_version = ET.parse(plugin_xml_path).find('.//version').text try: latest_version = None if PY2: response = urllib.urlopen(href) else: response = urllib.request.urlopen(href) m = _latest_pattern.search(response.read().decode('utf-8', 'ignore')) if m: latest_version = (m.group(1).strip()) if latest_version and latest_version != plugin_version: restype = 'info' filename = linenumber = None message = '*** An updated plugin version is available: v' + \ latest_version + ' ***' bk.add_result(restype, filename, linenumber, message) except: pass # read inifile read_ini(ini_path) # Extract book temp_dir = tempfile.mkdtemp() bk.copy_book_contents_to(temp_dir) # create mimetype file os.chdir(temp_dir) mimetype = open("mimetype", "w") mimetype.write("application/epub+zip") mimetype.close() # parse all xhtml/html files for mid, href in bk.text_iter(): print("..converting: ", href, " with manifest id: ", mid) data = borkify_xhtml(bk, mid, href) # write out modified file destdir = "" filename = unquote(href) if "/" in href: destdir, filename = unquote(filename).split("/") fpath = os.path.join(temp_dir, "OEBPS", destdir, filename) with open(fpath, "wb") as f: f.write(data.encode('utf-8')) # finally ready to build epub print("..creating 'borkified' ePUB") data = "application/epub+zip" fpath = os.path.join(temp_dir, "mimetype") with open(fpath, "wb") as f: f.write(data.encode('utf-8')) # ask the user where he/she wants to store the new epub doctitle = "dummy" fname = cleanup_file_name(doctitle) + "_borkified.epub" localRoot = tkinter.Tk() localRoot.withdraw() fpath = tkinter_filedialog.asksaveasfilename(parent=localRoot, title="Save ePUB as ...", initialfile=fname, initialdir=_USER_HOME, defaultextension=".epub") # localRoot.destroy() localRoot.quit() if not fpath: ignore_errors = sys.platform == 'win32' shutil.rmtree(temp_dir, ignore_errors) print("Borkify plugin cancelled by user") return 0 epub_zip_up_book_contents(temp_dir, fpath) ignore_errors = sys.platform == 'win32' shutil.rmtree(temp_dir, ignore_errors) print("Output Conversion Complete") # Setting the proper Return value is important. # 0 - means success # anything else means failure return 0
def run(bk): global prefs prefs = bk.getPrefs() # set default preference values if 'use_file_path' not in prefs: prefs['use_file_path'] = expanduser('~') if 'azw3_epub_version' not in prefs: prefs['azw3_epub_version'] = "2" # A, F, 2 or 3 if 'use_hd_images' not in prefs: prefs['use_hd_images'] = True if 'use_src_from_dual_mobi' not in prefs: prefs['use_src_from_dual_mobi'] = True if 'asin_for_kindlegen_plugin' not in prefs: prefs['asin_for_kindlegen_plugin'] = False if 'preserve_kindleunpack_meta' not in prefs: prefs['preserve_kindleunpack_meta'] = False if 'last_time_checked' not in prefs: prefs['last_time_checked'] = str(datetime.now() - timedelta(hours=7)) if 'last_online_version' not in prefs: prefs['last_online_version'] = '0.1.0' chk = UpdateChecker(prefs['last_time_checked'], prefs['last_online_version'], bk._w) update_available, online_version, time = chk.update_info() # update preferences with latest date/time/version prefs['last_time_checked'] = time if online_version is not None: prefs['last_online_version'] = online_version if update_available: title = 'Plugin Update Available' msg = 'Version {} of the {} plugin is now available.'.format(online_version, bk._w.plugin_name) update_msgbox(title, msg) if _DEBUG_: print('Python sys.path', sys.path) print('Default AZW3 epub version:', prefs['azw3_epub_version']) inpath = fileChooser() if inpath == '' or not os.path.exists(inpath): print('No input file selected!') bk.savePrefs(prefs) return 0 print ('Path to Kindlebook {0}'.format(inpath)) from mobi_stuff import mobiProcessor, topaz if topaz(inpath): print('Kindlebook is in Topaz format: can\'t open!') bk.savePrefs(prefs) return -1 mobionly = False mp = mobiProcessor(inpath, prefs['azw3_epub_version'], prefs['use_hd_images']) # Save last directory accessed to JSON prefs prefs['use_file_path'] = pathof(os.path.dirname(inpath)) if mp.isEncrypted: print('Kindlebook is encrypted: can\'t open!') bk.savePrefs(prefs) return -1 if mp.isPrintReplica: print('Kindlebook is a Print Replica: can\'t open!') bk.savePrefs(prefs) return -1 if not mp.isComboFile and not mp.isKF8: mobionly = True with make_temp_directory() as temp_dir: TWEAK = True asin = None if not mobionly: epub, opf, src = mp.unpackEPUB(temp_dir) if src is not None and isEPUB(src) and prefs['use_src_from_dual_mobi']: print ('Using included kindlegen sources.') epub = src else: # If user requested no tweaks through preferences, use standard epub from KindleUnpack if not prefs['asin_for_kindlegen_plugin'] and not prefs['preserve_kindleunpack_meta']: TWEAK = False elif prefs['asin_for_kindlegen_plugin']: if opf is not None: # Get asin from metadata and put it in a dc:meta that the Kindlegen plugin can use. asin = get_asin(opf) if asin is not None: asin = unicode_str(asin) else: TWEAK = False if TWEAK: # Modify the opf with the requested tweaks and build a new epub if tweak_opf(opf, asin, preserve_comments=prefs['preserve_kindleunpack_meta']): os.remove(epub) with temp_epub_handle(delete=False) as new_epub: epub_zip_up_book_contents(os.path.join(temp_dir,'mobi8'), new_epub) epub = new_epub else: from quickepub import QuickEpub mobidir, mobi_html, mobi_opf, mobiBaseName = mp.unpackMOBI(temp_dir) if not prefs['asin_for_kindlegen_plugin'] and not prefs['preserve_kindleunpack_meta']: TWEAK = False elif prefs['asin_for_kindlegen_plugin']: if mobi_opf is not None: # Get asin from metadata and put it in a dc:meta that the Kindlegen plugin can use. asin = get_asin(mobi_opf) if asin is not None: asin = unicode_str(asin) else: TWEAK = False if TWEAK: if not tweak_opf(mobi_opf, asin, preserve_comments=prefs['preserve_kindleunpack_meta']): print('OPF manipulation failed!') return -1 qe = QuickEpub(mobidir, mobi_html, mobi_opf) epub = qe.makeEPUB() # Save prefs to json bk.savePrefs(prefs) print ('Path to epub or src {0}'.format(epub)) with file_open(epub,'rb')as fp: data = fp.read() bk.addotherfile('dummy.epub', data) return 0
def run(bk): # protect against epub3 epubs being sent to ePub3-itizer epubversion = "2.0" if bk.launcher_version() >= 20160102: epubversion = bk.epub_version() if epubversion.startswith("3"): print("Error: ePub3-itizer requires a valid epub 2.0 ebook as input") return -1 manifest_properties= {} spine_properties = {} mo_properties = {} epub_types = {} temp_dir = tempfile.mkdtemp() # copy all files to a temporary destination folder # to get all fonts, css, images, and etc bk.copy_book_contents_to(temp_dir) # parse all xhtml/html files for mid, href in bk.text_iter(): print("..converting: ", href, " with manifest id: ", mid) data, mprops, sprops, etypes = convert_xhtml(bk, mid, href) # store away manifest and spine properties and any links # to epub:types for later use in opf3 if len(sprops) > 0: spine_properties[mid] = " ".join(sprops) if len(mprops) > 0: manifest_properties[mid] = " ".join(mprops) if len(etypes) > 0: epub_types[mid] = etypes # write out modified file write_file(data, href, temp_dir, unquote_filename=True) # detect smil files for mid, href, mt in bk.manifest_iter(): if mt == "application/smil+xml": print("..patching: ", href, " with manifest id: ", mid) data, text_ids, audio_ids, duration = patch_smil(bk, mid, href) # store mo properties to add # <meta property="media:duration" ...> elements # and media-overlay attributes to opf3 # text_ids: list of manifest ids of text files referenced by the smil file # audio_ids: list of manifest ids of audio files referenced by the smil file # duration: float, the duration (in seconds) of the smil file mo_properties[mid] = { "href": href, "text_ids": text_ids, "audio_ids": audio_ids, "duration": duration } # write out modified file write_file(data, href, temp_dir, unquote_filename=True) print("..converting: OEBPS/content.opf") # now parse opf2 converting it to opf3 format # while merging in previously collected spine and manifest properties opf2 = bk.readotherfile("OEBPS/content.opf") opfconv = Opf_Converter(opf2, spine_properties, manifest_properties, mo_properties) guide_info = opfconv.get_guide() lang = opfconv.get_lang() opf3 = opfconv.get_opf3() write_file(opf3, "content.opf", temp_dir) # It is possible that the original EPUB2 <guide> contains references # to files not in the spine; # putting those "dangling" references in the EPUB3 navigation document # will result in validation error: # RSC-011 "Found a reference to a resource that is not a spine item.". # Hence, we must check that the referenced files are listed in the spine. guide_info_in_spine = [] spine_hrefs = [t[2] for t in bk.spine_iter()] for gtyp, gtitle, ghref in guide_info: if ghref in spine_hrefs: guide_info_in_spine.append((gtyp, gtitle, ghref)) else: print( "..info: the EPUB2 <guide> contains a reference to a resource that is not a spine item: '", ghref, "', not adding it to the guide landmark in nav.xhtml" ) # need to take info from the old opf2 guide, epub_type semantics info # and toc.ncx to create a valid "nav.xhtml" # and update it to remove any doctype print("..parsing: OEBPS/toc.ncx") doctitle, toclist, pagelist = parse_ncx(bk, temp_dir) # now build up a nav print("..creating: OEBPS/nav.xhtml") navdata = build_nav(doctitle, toclist, pagelist, guide_info_in_spine, epub_types, lang) write_file(navdata, "nav.xhtml", temp_dir) # finally ready to build epub print("..creating: epub3") data = "application/epub+zip" write_file(data, "mimetype", temp_dir, in_oebps=False) # ask the user where he/she wants to store the new epub # TODO use dc:title from the OPF file instead if doctitle is None or doctitle == "": doctitle = "filename" fname = cleanup_file_name(doctitle) + "_epub3.epub" localRoot = tkinter.Tk() localRoot.withdraw() fpath = tkinter_filedialog.asksaveasfilename( parent=localRoot, title="Save ePub3 as ...", initialfile=fname, initialdir=_USER_HOME, defaultextension=".epub" ) # localRoot.destroy() localRoot.quit() if not fpath: shutil.rmtree(temp_dir) print("ePub3-itizer plugin cancelled by user") return 0 epub_zip_up_book_contents(temp_dir, fpath) shutil.rmtree(temp_dir) print("Output Conversion Complete") # Setting the proper Return value is important. # 0 - means success # anything else means failure return 0