packages feed

epub-metadata 2.0.2 → 2.1.0

raw patch · 5 files changed

+42/−59 lines, 5 filesdep +bytestringdep +zip-archivedep −LibZipsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring, zip-archive

Dependencies removed: LibZip

API changes (from Hackage documentation)

- Codec.Epub.IO: extractFileFromZip :: (MonadIO m, MonadError String m) => FilePath -> FilePath -> m String
- Codec.Epub.IO: opfPath :: (MonadError String m, MonadIO m) => FilePath -> m String
+ Codec.Epub.IO: opfContents :: (MonadError String m, MonadIO m) => FilePath -> m String

Files

Setup.hs view
@@ -4,35 +4,15 @@ -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info> -import Control.Monad ( unless ) import Distribution.Simple import System.Cmd ( system )-import System.Directory ( createDirectoryIfMissing )-import System.FilePath-import System.Posix.Files ( createSymbolicLink, fileExist )   main = defaultMainWithHooks (simpleUserHooks -   { postBuild = customPostBuild-   , runTests = testRunner+   { runTests = testRunner    } )     where-      -- Create symlink to the binary after build for developer -      -- convenience-      customPostBuild _ _ _ _ = do-         let binDir = "bin"-         let binName = "epubmeta"-         let destPath = binDir </> binName--         createDirectoryIfMissing True binDir--         linkExists <- fileExist destPath-         unless linkExists $ do-            createSymbolicLink-               (".." </> "dist" </> "build" </> binName </> binName)-               destPath-       -- Target for running all unit tests       testRunner _ _ _ _ = do          system $ "runhaskell -isrc testsuite/runtests.hs"
epub-metadata.cabal view
@@ -1,5 +1,5 @@ name:                epub-metadata-version:             2.0.2+version:             2.1.0 cabal-version:       >= 1.2 build-type:          Simple license:             BSD3@@ -17,7 +17,7 @@                      utility to dump OPF package data to stdout in a                       human-readable form. category:            Codec, Text-tested-with:         GHC>=6.12.1+tested-with:         GHC >= 6.12.3  library    exposed-modules:  Codec.Epub.IO,@@ -35,8 +35,8 @@                      Codec.Epub.Opf.Package.Spine,                      Codec.Epub.Opf.Parse    hs-source-dirs:   src-   build-depends:    base >= 3 && < 5, containers, hxt >= 9, LibZip, -                     mtl, regex-compat+   build-depends:    base >= 3 && < 5, bytestring, containers,+                     hxt >= 9, mtl, regex-compat, zip-archive    ghc-options:      -Wall  executable           epubmeta
src/Codec/Epub/IO.hs view
@@ -5,17 +5,15 @@ {-# LANGUAGE FlexibleContexts #-}  {- | Functions for doing some disk IO with ePub documents--   Note that these functions do their work by using the external -   unzip utility. -} module Codec.Epub.IO-   ( extractFileFromZip, opfPath )+   ( opfContents )    where -import Codec.Archive.LibZip+import Codec.Archive.Zip import Control.Arrow.ListArrows ( (>>>), deep ) import Control.Monad.Error+import qualified Data.ByteString.Lazy.Char8 as B import Text.Regex import Text.XML.HXT.Arrow.XmlArrow ( getAttrValue, hasName, isElem ) import Text.XML.HXT.Arrow.XmlState ( no, runX, withValidate )@@ -34,37 +32,43 @@    (mkRegexWithOpts "<!DOCTYPE [^>]*>" False True)) ""  -{- | Extract a file from a zipfile.--}-extractFileFromZip :: (MonadIO m, MonadError String m)-   => FilePath    -- ^ path to zip file-   -> FilePath    -- ^ path within zip file to extract-   -> m String    -- ^ contents of expected file-extractFileFromZip zipPath filePath = do-   result <- liftIO $ catchZipError-      (fmap Right $ withArchive [] zipPath $ fileContents [] filePath)-      (return . Left)--   output <- either (throwError . show) return result--   return . removeEncoding . removeDoctype $ output+-- | Extract a file from a zip archive throwing an error on failure+fileFromArchive :: MonadError String m =>+   FilePath -> Archive -> m String+fileFromArchive filePath archive = do+   let mbEntry = findEntryByPath filePath archive+   maybe+      (throwError $ "Unable to locate file " ++ filePath)+      (return . B.unpack . fromEntry) mbEntry  --- | Get the path within an ePub file to the OPF Package Document-opfPath :: (MonadError String m, MonadIO m)+-- | Get the contents of the OPF Package Document from an ePub file+opfContents :: (MonadError String m, MonadIO m)    => FilePath    -- ^ path to ePub zip file-   -> m String    -- ^ path within ePub to the OPF Package Document-opfPath zipPath = do-   containerContents <- extractFileFromZip zipPath-      "META-INF/container.xml"+   -> m String    -- ^ contents of the OPF Package Document+opfContents zipPath = do+   {- We need to first extract the container.xml file+      It's required to have a certain path and name in the epub+      and contains the path to what we really want, the .opf file.+   -}+   zipFileBytes <- liftIO $ B.readFile zipPath+   let archive = toArchive zipFileBytes +   let containerPath = "META-INF/container.xml"+   containerDoc <- fileFromArchive containerPath archive+    result <- liftIO $ runX (-      readString [withValidate no] containerContents+      readString [withValidate no] containerDoc       >>> deep (isElem >>> hasName "rootfile")       >>> getAttrValue "full-path"       ) -   case result of+   rootPath <- case result of       (p : []) -> return p-      _        -> throwError-         "ERROR: rootfile full-path missing from META-INF/container.xml"+      _        -> throwError $+         "ERROR: rootfile full-path missing from " ++ containerPath++   -- Now that we have the path to the .opf file, extract it+   rootDoc <- fileFromArchive rootPath archive++   return . removeEncoding . removeDoctype $ rootDoc
src/Codec/Epub/Opf/Cli/Opts.hs view
@@ -52,5 +52,5 @@          , "Options:"          ]       footer = init $ unlines-         [ "Version 2.0.2  Dino Morelli <dino@ui3.info>"+         [ "Version 2.1.0  Dino Morelli <dino@ui3.info>"          ]
src/Codec/Epub/Opf/Parse.hs view
@@ -251,9 +251,9 @@    XML string -} parseXmlToOpf :: (MonadIO m) => String -> m [Package]-parseXmlToOpf opfContents =+parseXmlToOpf contents =    liftIO $ runX (-      readString [withValidate no] opfContents+      readString [withValidate no] contents       >>> propagateNamespaces       >>> getBookData       )@@ -263,8 +263,7 @@ parseEpubOpf :: (MonadIO m, MonadError String m) =>    FilePath -> m Package parseEpubOpf zipPath = do-   opfContents <- extractFileFromZip zipPath =<< opfPath zipPath-   result <- parseXmlToOpf opfContents+   result <- opfContents zipPath >>= parseXmlToOpf     case result of       (em : []) -> return em