2

I have some epub files in my iCloud Drive that are essentially packages. I can show package contents and then it shows me a hierarchy of files and folders.

How can I convert this structure to a standard epub that any regular epub reader will understand?

  • (this may be an answer) Have you tried directly inserting the ePub from your iCloud drive into your ePub reader? – Brick May 21 '16 at 3:24
  • Yes, I've tried that @Brick, however they show up as folders as noted above... – ylluminate May 21 '16 at 3:25
  • As in, does it properly display as intended in the reader? – Brick May 21 '16 at 3:26
  • No, they show up as a folder instead of a book. They simply give a folder hierarchy. I had figured that perhaps an epub folder would just need to be compressed and then renamed appropriately perhaps... – ylluminate May 21 '16 at 5:10
1

An ePub file is essentially just a zipped folder, though it has a mimetype file inside which apparently needs to not be compressed.

This would imply that it's not completely straightforward to recreate with a simple zip app. However, it may be simpler than that.
Let's assume nothing has actually unpacked it, merely got confused about how to deal with it. Work on a copy.

Two things to try...

  1. Try just renaming it, change .epub to .zip, then change it back again, see if it's recognised correctly.

  2. Open it in Calibre
    You than have a myriad ways to deal with it, simplest is see if it can talk to your ebook reader via OPDS. Calibre can run its own local server on your wifi & you can copy books over very simply.
    If still no joy, get Calibre to convert it to an ePub [again] This is a great method for fixing a file, as it can re-examine it, fix fonts, bad hyphenations, all kinds of issues.

Calibre itself is too big a subject to really cover in a simple QA, but there are reams of data about it on the site itself & at http://www.mobileread.com/forums/ including sections for most major e-readers too.

  • Very interesting, thanks. I'm glad you confirmed my suspicion re: the compression. Are you aware of any method to do this via the shell off the top? I'm assuming that this will be pretty quick and easy with a simple incantation if I can fiddle around and either find one or come up with one. – ylluminate May 21 '16 at 14:40
  • I did find this - mobileread.com/forums/showthread.php?t=29057 - though I'm no expert when it comes to Terminal. – Tetsujin May 21 '16 at 14:43
2

Reproduction of the problem:

  1. A ePub file named, say, book.epub is a file (-rw-r--r--).
  2. Open book.epub using iBooks app.
  3. Take out the cached file stored in ~/Library/Containers/com.apple.BKAgentService/Data/Documents/iBooks/Books/, which has been renamed to another name such as A22DFAF7E75C21D979C375B1AD07008F.epub and becomes a directory (drwxr-xr-x@).

Steps of the work-around that works on my Mac:

  1. Change extension of A22DFAF7E75C21D979C375B1AD07008F.epub from .epub to .zip.
  2. Go into the zip package and zip up all the contents inside into a new .zip file, say, Archive.zip.
  3. Drag out the new .zip file and change extension back to .epub.
  4. The Archive.epub file is a file (-rw-r--r--).
1

FWIW, here's a shell command that works:

 cd my-broken.epub

 # iTunes/Books seems to add a file 
 # 'iTunesMetadata.plist', and it produces a warning.
 # May also contain private data, so better delete it.

 rm iTunesMetadata.plist 

 zip -X -r ../fixed.epub mimetype *

As far as I can tell, compression does not need to be deactivated (-0). epubcheck has no complaints. There might be differences between versions of the epub spec, however. My test was with an epub 3.0 file.

0

I've taken some of the comments here and provided a Jupyter notebook that does this for a backup of say a Books directory:

import pathlib
import glob
import os
import zipfile

# Extract the relevant components of a full path
def pathComponents(fullpath):
    path = pathlib.Path(fullpath)
    name = path.name
    stem = path.stem
    suffix = path.suffix
    parent = path.parent
    return name, stem, suffix, parent

# Get directories in your path that have a .epub suffix
def getePubDirs(path):
    epubSearch = os.path.join(path, "*" + "." + "epub")
    eDirs=[]
    for p in glob.glob(epubSearch):
        if (os.path.isdir(p)):    # Only if it's an epub directory
            eDirs.append(p)
    return eDirs

def createZipFile(fname, files):
    zFile = zipfile.ZipFile(fname, mode='w', compression=zipfile.ZIP_DEFLATED)
    for f in files:
        zFile.write(f)
    zFile.close()

def convertDirToePub(dirname):
    name, stem, suffix, parent = pathComponents(dirname)        # get dirname details
    newdirname = zFile = str(parent) + "/" + name + ".ori"
    zFile = str(parent) + "/" + stem + ".epub"
    os.rename(dirname,newdirname)     # rename the epub dir so the epub can take its old name
    # get all the files within the epub directory
    os.chdir(newdirname) # We need to be in directory so the resultant epub paths are correct
    everything = [os.path.join(r,file) for r,d,f in os.walk(".") for file in f]
    createZipFile(zFile, everything)  # Create a zip file containing all those files
    os.chdir(parent)

dirtoconvert='/Users/<username>/tmp/Booksdir'

eDirs = getePubDirs(dirtoconvert)
totalDirs=len(eDirs)
print(totalDirs, "docs to convert")
ctr=1
for i in eDirs:
    print(ctr, "of", totalDirs, ": Converting ", i)
    convertDirToePub(i)
    ctr = ctr + 1
print("Done!")
  • 1
    Great stuff. I've inlined your code directly into the answer so people don't have to hope to another site for it and it doesn't get lost in case the link breaks. – nohillside Jul 11 at 11:12
  • Thanks @nohillside. By the way, upping the answer if you think it's worth it, might help get it some visibility :) – Jon M Jul 12 at 7:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .