packages feed

epub-tools-4.0: src/app/EpubTools/EpubMeta/Import.hs

module EpubTools.EpubMeta.Import
  ( importOpf )
  where

import Codec.Archive.Zip (Entry (..), addEntryToArchive, findEntryByPath,
  readEntry, toArchive)
import Codec.Epub.IO ( getPkgPathXmlFromBS, writeArchive )
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Data.List (foldl')
import System.Directory (copyFile, removeFile)

import EpubTools.EpubMeta.Opts (Backup (BackupSuffix, NoBackup),
  EpubPath (..), ImportPath (..))
import EpubTools.EpubMeta.Util (EM, liftIO, throwError)


importOpf :: ImportPath -> Backup -> EpubPath -> EM ()

importOpf (ImportPath pathToNewOpf) NoBackup (EpubPath zipPath) = do
  -- Make new file into a Zip Entry
  tempEntry <- liftIO $ readEntry [] pathToNewOpf

  -- Read the zip archive in, we'll need it in several steps
  strictBytes <- liftIO $ BS.readFile zipPath

  -- The path in the book where new file must go
  (pathToOldFile, _) <- getPkgPathXmlFromBS strictBytes

  -- Adjust the entry's path
  let newOpfEntry = tempEntry { eRelativePath = pathToOldFile }

  -- Bytes of existing archive already loaded, make an Archive from that
  let oldArchive = toArchive . BL.fromChunks $ [strictBytes]

  -- Make an entry from the existing mimetype file
  mimeEntry <- maybe
    (throwError "Something went wrong: This epub has no mimetype, which shouldn't be possible. Original file unchanged.")
    return $ findEntryByPath "mimetype" oldArchive

  -- Add the two entries back to the archive in this order to preserve the
  -- mimetype as the first one
  let newArchive = foldl' (flip id) oldArchive
        [addEntryToArchive newOpfEntry, addEntryToArchive mimeEntry]

  -- We're ready to write the new zip archive, delete the old one
  liftIO $ removeFile zipPath

  -- Write the new archive out
  liftIO $ writeArchive zipPath newArchive

importOpf importPath (BackupSuffix suffix) epubPath@(EpubPath zipPath) = do
  liftIO $ copyFile zipPath (zipPath ++ suffix)
  importOpf importPath NoBackup epubPath