¿Cómo convertir un paquete epub a epub normal?

Tengo algunos archivos epub en mi iCloud Drive que son esencialmente paquetes. Puedo mostrar el contenido del paquete y luego me muestra una jerarquía de archivos y carpetas.

¿Cómo puedo convertir esta estructura en un epub estándar que cualquier lector normal de epub pueda entender?

(esta puede ser una respuesta) ¿Ha intentado insertar directamente el ePub desde su unidad iCloud en su lector de ePub?
Sí, probé ese @Brick, sin embargo, aparecen como carpetas como se indicó anteriormente ...
Como en, ¿se muestra correctamente según lo previsto en el lector?
No, aparecen como una carpeta en lugar de un libro. Simplemente dan una jerarquía de carpetas. Pensé que tal vez una carpeta epub solo necesitaría ser comprimida y luego renombrada apropiadamente tal vez ...

Respuestas (6)

Cómo importa iBooks un archivo ePub:

Un .epubarchivo, como se indica en otras respuestas, es esencialmente un archivo comprimido. Cuando iBooks importa el .epubarchivo, el .epubarchivo que almacena es un archivo sin comprimir. Esto explica por qué tiene la Show Package Contentsopción que le permite explorar los archivos "descomprimidos". Sin embargo, simplemente comprimir el paquete no siempre funciona.

Volviendo a crear el .epubarchivo desde el paquete :

A mano:

  1. Right clicken el .epubarchivo y haga clic en Show Package Contents.
  2. Seleccione todo el contenido ( CMD+ A) → Right clickCompress.
  3. Esto creará un .ziparchivo. ¡Simplemente cambia la extensión de .zipa .epuby listo! El archivo se ha convertido en un documento ePub .

Automatización:

Tenía más de 2000 .epub paquetes que quería convertir en .epub archivos , por lo que el método anterior no era factible. Para evitar el trabajo manual, escribí un script que esencialmente ejecuta el método anterior en todos los archivos. Usé el código de shell simple y elegante proporcionado por Matthias aquí y lo envolví en un pythonscript compartido a continuación:

# Convert epub packages to epub files
import os
import subprocess

filenames = []
path_to_files = ""
#   Function to store all filenames in a list
def extract_filename(path_to_files):    # "/Users/****/Desktop/Old_epubs"
    os.chdir(path_to_files)
    books = os.getcwd()
    for f in os.listdir(books):
        f_name, f_ext = os.path.splitext(f)
        if f_ext == ".epub":
            filenames.append(f_name)

    filenames.sort()

#   Function to generate new epub files
def create_epub(path_to_new_files): # "/Users/****/Desktop/new_epubs/"
    total_files = len(filenames)
    for i in range(total_files):
        epub_path = "cd " + path_to_files
        filename = filenames[i] + ".epub"
        zipping = " zip -X -r " + path_to_new_files + filename + " mimetype *"
        plist = "rm iTunesMetadata.plist"
        comm = epub_path + filename + "; " + plist + "; " + zipping
        p1 = subprocess.run(comm, capture_output = True, text = True, shell = True)
        success = p1.returncode
        if success == 0:
            rem_files = total_files - i + 1
            print("File #", i+1, " has been processed successfully. Remaining files: ", rem_files)

#   Enter the paths
extract_filename("/Users/****/Desktop/Books")   # Path to directory containing epub packages
create_epub("/Users/****/Desktop/new_epubs/")   # Path to store new epub files in

La extract_filenamefunción lleva patha un directorio que contiene los .epub paquetes que deben convertirse. [ADVERTENCIA] Lo mejor es trabajar en una copia de los .epubpaquetes en caso de que algo salga mal. Para estar seguro, simplemente copie los paquetes en un directorio diferente y trabaje en eso.

La create_epubfunción lleva patha un directorio donde desea almacenar los archivos generados. Luego ejecuta un shellcomando para abrir cada .epub paquete y generar un .epub archivo .


¡Espero que esto ayude! Ciertamente resolvió un gran dolor de cabeza mío.

FWIW, aquí hay un comando de shell que funciona:

 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 *

Que yo sepa, no es necesario desactivar la compresión ( -0). epubcheckno tiene quejas. Sin embargo, puede haber diferencias entre las versiones de la especificación epub. Mi prueba fue con un archivo epub 3.0.

✊🏽 Lo Mejor ✊🏽
Esta solución para mí!
¡Esto funcionó para mí! Por curiosidad, ¿por qué quitar iTunesMetadata.plist?

Un archivo ePub es esencialmente solo una carpeta comprimida, aunque tiene un archivo tipo MIME dentro del cual aparentemente no es necesario comprimirlo.

Esto implicaría que no es completamente sencillo recrearlo con una simple aplicación zip. Sin embargo, puede ser más simple que eso.
Supongamos que nada lo ha desempacado realmente, simplemente se confundió acerca de cómo lidiar con eso. Trabaja en una copia.

Dos cosas para probar...

  1. Intente simplemente cambiarle el nombre, cambie .epub a .zip, luego vuelva a cambiarlo, vea si se reconoce correctamente.

  2. Ábralo en Calibre.
    Tiene una miríada de formas de manejarlo, lo más simple es ver si puede hablar con su lector de libros electrónicos a través de OPDS. Calibre puede ejecutar su propio servidor local en su wifi y puede copiar libros de manera muy simple.
    Si todavía no está contento, haga que Calibre lo convierta a un ePub [otra vez] Este es un gran método para reparar un archivo, ya que puede volver a examinarlo, corregir fuentes, guiones incorrectos, todo tipo de problemas.

Calibre en sí mismo es un tema demasiado amplio para cubrirlo realmente en un simple control de calidad, pero hay montones de datos al respecto en el sitio mismo y en http://www.mobileread.com/forums/ , incluidas secciones para la mayoría de los principales lectores electrónicos. .

Muy interesante, gracias. Me alegro de que hayas confirmado mi sospecha sobre: ​​la compresión. ¿Conoce algún método para hacer esto a través del caparazón de la parte superior? Supongo que esto será bastante rápido y fácil con un encantamiento simple si puedo jugar y encontrar uno o pensar en uno.
Encontré esto: mobileread.com/forums/showthread.php?t=29057 , aunque no soy un experto en lo que respecta a Terminal.
Sé que han pasado 5 años, pero simplemente cambiar el nombre de .epub.zip a .epub me lo arregló.

Reproducción del problema:

  1. Un archivo ePub llamado, digamos, book.epubes un archivo ( -rw-r--r--).
  2. Abrir book.epubusando la aplicación iBooks.
  3. Saque el archivo en caché almacenado en ~/Library/Containers/com.apple.BKAgentService/Data/Documents/iBooks/Books/, que ha sido renombrado a otro nombre como A22DFAF7E75C21D979C375B1AD07008F.epuby se convierte en un directorio ( drwxr-xr-x@).

Pasos de la solución alternativa que funciona en mi Mac:

  1. Cambiar extensión de A22DFAF7E75C21D979C375B1AD07008F.epubde .epuba .zip.
  2. Vaya al paquete zip y comprima todo el contenido en un .ziparchivo nuevo, por ejemplo, Archive.zip.
  3. Arrastre el nuevo .ziparchivo y cambie la extensión de nuevo a .epub.
  4. El Archive.epubarchivo es un archivo ( -rw-r--r--).

Tomé algunos de los comentarios aquí y proporcioné un cuaderno Jupyter que hace esto para una copia de seguridad de, por ejemplo, un directorio de Libros:

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!")

He adaptado los métodos compartidos aquí y he creado el siguiente script de shell.

Es bastante simple ya que no toma ningún argumento, simplemente se ejecuta desde el directorio en el que se ejecuta.
El script agrega un fixeddirectorio si aún no hay uno, donde coloca los archivos corregidos.

Puede agregarlo a un archivo, es decir fix_epub.sh, . O agréguelo a su archivo .bashrc/ .zshrcetc., envolviéndolo en una función. He agregado ejemplos para cada uno a continuación.

Luego desde su terminal, cd <epub-path>a su carpeta .epub y ya sea;

  1. Usando el archivo shell
    a. ejecutar touch fix_epub.shy agregar su código al archivo.
    b. correr sh fix_epub.sh_
  2. Usando una función de shell
    a. ejecutar fix_epub(suponiendo que ya lo haya agregado a .bashrc).

Guiones

fix_epub.sh

#!/bin/bash

mkdir -p fixed

find . -name "*.epub" | while read -r file; do
  (cd "$file" || exit && \
  find . -iname 'iTunesMetadata*.plist' -delete && \
  zip -r -X "../fixed/$file" mimetype .)
done

.bashrc

function fix_epub () {
  mkdir -p fixed

  find . -name "*.epub" | while read -r file; do
    (cd "$file" || exit && \
    find . -iname 'iTunesMetadata*.plist' -delete && \
    zip -r -X "../fixed/$file" mimetype .)
  done
}