diff --git a/imgs_2_epub.py b/imgs_2_epub.py index cc0be0b..397965f 100644 --- a/imgs_2_epub.py +++ b/imgs_2_epub.py @@ -8,6 +8,25 @@ import uuid import zipfile import threading + +### PREP + +debug = False + +settings={} + +def roman(int): + m = ["", "m", "mm", "mmm"] + c = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"] + x = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"] + i = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"] + + thous = m[int // 1000] + hunds = c[(int%1000)//100] + tens = x[(int%100)//10] + ones = i[int%10] + + return (thous+hunds+tens+ones) processDone = False loadmsg="" @@ -38,12 +57,6 @@ def endLoadPrint(msg): donemsg = msg processDone = True time.sleep(0.2) - -### PREP - -debug = False - -settings={} ## DEFINE PATHS @@ -127,9 +140,10 @@ def promptMeta(tochange, question, good, bad, invalidMsg): if settings["identifier"] == "": settings.update({"identifier": "uuid:"+ str(uuid.uuid4())}) while True: - promptMeta("pageStart", "\nOn what image does your book start couting pages? (Ex: Image 2 = Page 1, Image 15 = Page 13): ", False, False, "\nInvalid page!") + promptMeta("pageStart", "\nWhat does your book consider 'Page 1'? (0 = Cover, 1 = 'Page 1', etc.): ", False, False, "\nInvalid page!") if settings["pageStart"].isdigit() == True: break else: print("\nInvalid Page!") +settings.update({"pageStart": int(settings["pageStart"])-1}) promptMeta("legacy", "\nWould you like to enable legacy compatability? (May be needed for old ePub readers) (y/n): ", ("y", "n"), False, "\nInvalid choice! Please type 'y' or 'n'.") @@ -138,10 +152,9 @@ def promptMeta(tochange, question, good, bad, invalidMsg): settings.update({"chapters": []}) if settings["toc"] == "y": - print("\n") while True: while True: - chapter = input("What page does your (next) chapter start? (Leave blank to end): ") + chapter = input("\nWhat page does Chapter "+str(len(settings["chapters"])+1)+" start? (Leave blank to end): ") if debug == True: print("CHAPTER: "+chapter) if chapter != "": if chapter.isdigit(): @@ -152,6 +165,20 @@ def promptMeta(tochange, question, good, bad, invalidMsg): break if debug == True: print("CHAPTERS: "+str(settings["chapters"])) + if len(settings["chapters"]) > 0: promptMeta("chapName", "\nWould you like to give your chapter custom names? (y/n): ", ("y", "n"), False, "\nInvalid choice! Please type 'y' or 'n'.") + + settings.update({"chapterNames": []}) + if settings["chapName"] == "y": + for i in range(len(settings["chapters"])): + name = input("\nPlease give a custom name to Chapter "+str(i+1)+" (Leave blank to skip): ") + if name != "": + settings["chapterNames"].append(name) + else: + settings["chapterNames"].append("Chapter "+str(i+1)) + else: + for i in range(len(settings["chapters"])): + settings["chapterNames"].append("Chapter "+str(i+1)) + promptMeta("dir", "\nWhich way should your ePub be read? (Left-to-right for english and similar languages) (ltr/rtl): ", ("ltr", "rtl"), False, "Not a direction! Please type 'ltr' or 'rtl'") promptMeta("optionalMeta", "\nWould you like to include additional metadata, such as authors?\n(It is heavily reccommended to add this metadata in in a seperate app like Calibre or Sigil instead)\n(y/n): ", ("y", "n"), False, "Please put 'y' or 'n'.") @@ -288,13 +315,14 @@ def create_file(path, write): startLoadPrint("Creating files") for i in range(len(imgs)): - if imgs[i].endswith((".jpg", ".jpeg", ".jpe", ".jif", ".jfif", ".jfi")): mediatype = "jpeg" - elif imgs[i].endswith((".png")): mediatype = "png" - elif imgs[i].endswith((".gif")): mediatype = "gif" - elif imgs[i].endswith(("webp")): mediatype = "webp" + pageImg = Image.open(os.path.join(settings["epub_path"], settings["filename"],"OEBPS","images",imgs[i])) + if pageImg.format == "JPEG": mediatype = "jpeg" + elif pageImg.format == "PNG": mediatype = "png" + elif pageImg.format == "GIF": mediatype = "gif" + elif pageImg.format == "WebP": mediatype = "webp" page_num = i - width, height = Image.open(os.path.join(settings["epub_path"], settings["filename"],"OEBPS","images",imgs[i])).size - if settings["pageStart"] != 2: page_num -= int(settings["pageStart"])-1 + width, height = pageImg.size + page_num -= int(settings["pageStart"]) if i == 0: title = "Cover" file_name = "cover.xhtml" @@ -303,26 +331,29 @@ def create_file(path, write): if len(settings["chapters"]) == 0: navigation += "\n
  • \n Cover\n
  • \n" manifestXHTML += f" \n \n" spine += " \n" - pagelist.append("Cover") + if page_num < 1: + pagelist.append(roman(page_num+settings["pageStart"]+1)) + else: + pagelist.append(str(page_num)) elif page_num < 1: - title = f"Before Page (Page {page_num}}})" - file_name = f"pg_{str(i)}.xhtml" - xhtml_code = f"\n
    \n \"Before\n
    \n" - stylesheet += f"body.body_{str(i)} {{ width: {str(width)}px; height: {str(height)}px; margin: 0; }}\nimg.image_{str(i)} {{ position: absolute; height: {str(height)}px; top: 0px; left: 0px; margin: 0; z-index: 0; }}\n\n" + title = f"Page {roman(page_num+settings['pageStart']+1)}" + file_name = f"pg_{roman(page_num+settings['pageStart']+1)}.xhtml" + xhtml_code = f"\n
    \n \"Page\n
    \n" + stylesheet += f"body.body_{str(page_num)} {{ width: {str(width)}px; height: {str(height)}px; margin: 0; }}\nimg.image_{str(page_num)} {{ position: absolute; height: {str(height)}px; top: 0px; left: 0px; margin: 0; z-index: 0; }}\n\n" manifestXHTML += f" \n \n" spine += f" \n" - pagelist.append(str(page_num)) + pagelist.append(roman(page_num+settings["pageStart"]+1)) else: title = "Page "+str(page_num) - file_name = f"pg_{str(i)}.xhtml" - xhtml_code = f"\n
    \n \"{str(page_num)}\"\n
    \n" - stylesheet += f"body.body_{str(i)} {{ width: {str(width)}px; height: {str(height)}px; margin: 0; }}\nimg.image_{str(i)} {{ position: absolute; height: {str(height)}px; top: 0px; left: 0px; margin: 0; z-index: 0; }}\n\n" + file_name = f"pg_{str(page_num)}.xhtml" + xhtml_code = f"\n
    \n \"{str(page_num)}\"\n
    \n" + stylesheet += f"body.body_{str(page_num)} {{ width: {str(width)}px; height: {str(height)}px; margin: 0; }}\nimg.image_{str(page_num)} {{ position: absolute; height: {str(height)}px; top: 0px; left: 0px; margin: 0; z-index: 0; }}\n\n" manifestXHTML += f" \n \n" spine += f" \n" pagelist.append(str(page_num)) xhtml_code = f"\n\n\n\n\n\n{title}\n\n\n{xhtml_code}\n" file_path = os.path.join(settings["epub_path"], settings["filename"], "OEBPS", file_name) - + pageImg.close() create_file(file_path, xhtml_code) ## STYLESHEET.CSS @@ -330,13 +361,13 @@ def create_file(path, write): create_file(os.path.join(settings["epub_path"], settings["filename"],"OEBPS","stylesheet.css"), stylesheet) ## NAVIGATION DOCUMENT (NAV.XHTML) -for i in range(len(settings["chapters"])): navigation += f"\n
  • \n Chapter {i+1}\n
  • \n" +for i in range(len(settings["chapters"])): navigation += f"\n
  • \n {settings['chapterNames'][i]}\n
  • \n" navigation += "\n \n \n \n\n" @@ -353,14 +384,21 @@ def create_file(path, write): ## TABLE OF CONTENTS/NCX (LEGACY) if settings["legacy"] == "y": - ncxLegacy = f"\n\n\n \n \n \n \n \n \n \n {settings['title']}\n \n \n \n \n Cover\n \n \n \n" - for i in range(len(settings["chapters"])): - ncxLegacy += f" \n \n Chapter {str(i+1)}\n \n \n \n " + ncxLegacy = f"\n\n \n \n \n \n \n \n \n {settings['title']}\n \n \n" + if len(settings["chapters"]) == 0: + ncxLegacy += " \n \n Cover\n \n \n \n" + else: + for i in range(len(pagelist)): + for j in range(len(settings["chapters"])): + if pagelist[i] == settings["chapters"][j]: + ncxLegacy += f" \n \n {settings['chapterNames'][j]}\n \n \n \n" ncxLegacy += " \n \n \n Pages\n \n" + if len(settings["chapters"]) != 0: + ncxLegacy += " \n \n Cover\n \n \n \n" for i in range(len(pagelist)): - if i == 0: ncxLegacy += f" \n \n Cover\n \n \n \n" - else: ncxLegacy += f" \n \n {str(i)}\n \n \n \n" + if pagelist[i] not in settings["chapters"] and i != 0: + ncxLegacy += f" \n \n {pagelist[i]} of {(len(pagelist)-settings['pageStart'])-1}\n \n \n \n" ncxLegacy += " \n" create_file(os.path.join(settings["epub_path"], settings["filename"],"OEBPS","toc.ncx"), ncxLegacy)