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
Example #2
0
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
Example #3
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
Example #4
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
Example #5
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
Example #6
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
Example #7
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*&quot;([^&]*)&')
    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
Example #9
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