-- Copyright: 2008-2011 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli import Codec.Epub.Opf.Format.Package import Codec.Epub.Opf.Package import Codec.Epub.Opf.Parse import Control.Monad import Control.Monad.Trans import System.Directory ( doesFileExist, renameFile ) import System.Environment ( getArgs ) import System.Exit import System.IO ( BufferMode ( NoBuffering ) , hSetBuffering, stdout, stderr ) import Text.Printf import EpubName.Formatters ( tryFormatting ) import EpubName.Opts ( Options (..), parseOpts, usageText ) import EpubName.Util {- Construct additional verbose output -} formatF :: (String, Package) -> String formatF (fmtUsed, _) = printf "\n formatter: %s" fmtUsed formatFM :: (String, Package) -> String formatFM (fmtUsed, pkg) = printf "\n formatter: %s\n%s" fmtUsed (formatPackage False pkg) {- Format output for a book that was processed -} makeOutput :: Options -> (FilePath, FilePath, String, Package) -> String makeOutput opts (oldPath, newPath, fmtUsed, pkg) = printf "%s -> %s%s" oldPath newPath (additional (optVerbose opts) (fmtUsed, pkg)) where additional Nothing = const "" additional (Just 1) = formatF additional _ = formatFM {- Process an individual epub book file -} processBook :: Options -> FilePath -> IO Bool processBook opts oldPath = do result <- runEN opts $ do pkg <- parseEpubOpf oldPath let md = opMeta pkg (fmtUsed, newPath) <- tryFormatting (oldPath, md) when (not $ optOverwrite opts) $ do fileExists <- liftIO $ doesFileExist newPath when fileExists $ throwError $ printf "ERROR: File %s already exists!" newPath unless (optNoAction opts) $ liftIO $ renameFile oldPath newPath return (oldPath, newPath, fmtUsed, pkg) let (success, report) = either ((,) False) (\r -> (True, makeOutput opts r)) result putStrLn report return success main :: IO () main = do -- No buffering, it messes with the order of output mapM_ (flip hSetBuffering NoBuffering) [ stdout, stderr ] (opts, paths) <- getArgs >>= parseOpts >>= either exitWith return ec <- if ((optHelp opts) || (null paths)) then do putStrLn usageText return ExitSuccess else do when (optNoAction opts) (putStrLn "No-action specified") codes <- mapM (processBook opts) paths case all id codes of True -> return ExitSuccess False -> return . ExitFailure $ 2 exitWith ec