Fixing Epub Files from Apple Books
Wherein we fix some Apple Walled Garden shit
I have a rather-large collection of ebooks in the .epub format that I've gathered over the years and have imported these into Apple's Books app so that they're available for reading on my various devices thanks to iCloud syncing. However, recently it occured to me that I don't have a proper backup of all these books.
So, I decided I'd copy them from iCloud to a local folder and import them into the Calibre ebook management software so that I could properly-tag them with the correct metadata, etc., and have a backup of the collection.
My first hurdle was figuring out where MacOS stores the books...they're not actually a "Books" folder that's readily-exposed in iCloud drive. A bit of research and exploring lead me to finding the correct folder (at least on MacOS Sequoia (15.5):
/Users/{username}/Library/Mobile Documents/iCloud~com~apple~iBooks/Documents/The trick is, you can't actually navigate to this path in Finder...you have to use Go-->Go To Folder... in the Finder menubar and paste this path there, substituting your own username in for {username}, of course.
Once I found this path, I proceeded to copy the contents to a temporary folder on my NAS. This took a bit as iCloud had to pull down the originals from the cloud, but once complete, I was ready to import to a new Calibre library.
Except epub files wouldn't import.
WTF?
Time to do some research.
After a bit of sleuthing, I discovered that Apple, in its infinite wisdom, does something weird to .epub files when you import them to Books. An .epub file is basically a zipped file with a folder structure inside that contains the contents of the book. You can read about this structure here or read the full spec here. Apple unzips this file and then stores the contents as a structured directory inside a package that they "helpfully" add an .epub extension to.
So, the solution is to re-zip all of these packages into a proper zip file with an .epub extension.
Here's how:
Open terminal and navigate to the folder where you've temporarily stored the .epub files you want to fix (do not do this fix in the source iCloud folder...you'll destroy your Books library).
Make sure you're you're using the bash shell (this might work in zsh, but I didn't try as I prefer bash from my Unix/Linux days) by entering the following command in the terminal:
bashThen copy/paste this script into terminal, click Enter and let it run:
for dir in *.epub; do
echo "Processing $dir"
cd "$dir"
# Create a zip: mimetype must be first and uncompressed
zip -X0 "../$dir.zip" mimetype
# Add the rest
zip -Xr9D "../$dir.zip" * -x mimetype
cd ..
mv "$dir.zip" "${dir}.fixed.epub"
doneThis will take a while to churn through your files (or not, if you only have a few). You'll know it's done when you get a new command prompt and it stops outputting status messages.
This script rezips all the files in the folder that are .epub files, outputting a new .epub file with an infix of .fixed. so that you can determine which files are ready to be imported to Calibre (or used in any e-reader of your choice).