packages feed

intricacy-0.8.0: Mundanities.hs

-- This file is part of Intricacy
-- Copyright (C) 2013 Martin Bays <mbays@sdf.org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of version 3 of the GNU General Public License as
-- published by the Free Software Foundation, or any later version.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see http://www.gnu.org/licenses/.

module Mundanities where
import           Control.Applicative
import           Control.Arrow
import           Control.Monad
import           Control.Monad.Catch    (MonadMask, catch, handle)
import           Control.Monad.IO.Class (MonadIO)
import qualified Data.ByteString        as BS
import qualified Data.ByteString.Char8  as BSC
import           Data.List
import           Data.Maybe
import           Paths_intricacy
import           System.Directory
import           System.Environment     (getEnv)
import           System.FilePath

catchIO :: IO a -> (IOError -> IO a) -> IO a
catchIO = catch

ignoreIOErr :: (MonadIO m, MonadMask m, Monoid a) => m a -> m a
ignoreIOErr = handle ((\_ -> return mempty) :: (Monad m, Monoid a) => IOError -> m a)

ignoreIOErrAlt :: (MonadIO m, MonadMask m, Alternative f) => m (f a) -> m (f a)
ignoreIOErrAlt = handle ((\_ -> return empty) :: (Monad m, Alternative f) => IOError -> m (f a))

unlessIOErr :: (MonadIO m, MonadMask m) => m Bool -> m Bool
unlessIOErr = (fromMaybe False <$>) . ignoreIOErrAlt . (Just <$>)

readReadFile :: (Read a) => FilePath -> IO (Maybe a)
readReadFile file = ignoreIOErrAlt $ tryRead . BSC.unpack <$> BS.readFile file

tryRead :: (Read a) => String -> Maybe a
tryRead = (fst <$>) . listToMaybe . reads

readStrings :: FilePath -> IO [String]
readStrings file = ignoreIOErr $ lines . BSC.unpack <$> BS.readFile file

writeReadFile :: (Show a) => FilePath -> a -> IO ()
writeReadFile file x = do
    mkdirhierto file
    BS.writeFile file $ BSC.pack $ show x

writeStrings :: FilePath -> [String] -> IO ()
writeStrings file x = do
    mkdirhierto file
    BS.writeFile file $ BSC.pack $ unlines x

confFilePath :: FilePath -> IO FilePath
confFilePath str = (++(pathSeparator:str)) <$>
    catchIO (getEnv "INTRICACY_PATH")
        (const $ getAppUserDataDirectory "intricacy")

getDataPath :: FilePath -> IO FilePath
getDataPath = getDataFileName

makeConfDir :: IO ()
makeConfDir = confFilePath "" >>= createDirectoryIfMissing False

fileExists :: FilePath -> IO Bool
fileExists = unlessIOErr . doesFileExist

mkdirhierto :: FilePath -> IO ()
mkdirhierto = mkdirhier . takeDirectory

mkdirhier :: FilePath -> IO ()
mkdirhier = createDirectoryIfMissing True

getDirContentsRec :: FilePath -> IO [FilePath]
getDirContentsRec path = ignoreIOErr $ do
    contents <- map ((path++[pathSeparator])++) . filter ((/='.').head) <$> getDirectoryContents path
    annotated <- (\p -> (,) p <$> doesDirectoryExist p) `mapM` contents
    let (dirs,files) = join (***) (map fst) $ partition snd annotated
    (files++) . concat <$> getDirContentsRec `mapM` dirs

fullLockPath path = if isAbsolute path
    then return path
    else do
        homePath <- getHomeDirectory
        locksPath <- confFilePath "locks"
        return $ if take 2 path == "~/"
            then homePath </> drop 2 path
            else locksPath </> path