module Data.TTask.File.File ( Success(..) , readActiveProject , writeActiveProject , activeProjectName , setActiveProject , initDirectory , initProjectFile , findProjects ) where import Control.Applicative import Control.Exception import Control.Monad import Data.Maybe import Data.TTask.Types import Data.TTask.Command import qualified Data.TTask.File.Compatibility as C import Safe import qualified System.IO.Strict as S import System.Directory import System.FilePath data Success = Success | Failure deriving (Show, Read, Eq) writeProject :: String -> Project -> IO () writeProject fn pj = writeFile fn $ show pj readProject :: String -> IO (Maybe Project) readProject fn = do d <- S.readFile fn return $ readMay d readActiveProject :: IO (Maybe Project) readActiveProject = do dir <- projectsDirectory mfn <- activeProjectName mpj <- readProject . (dir ) >$< mfn case mpj of Just _ -> return mpj Nothing -> do s <- fmap return . S.readFile . (dir ) >$< mfn C.resolution >$< s writeActiveProject :: Project -> IO Success writeActiveProject pj = do dir <- projectsDirectory mfn <- activeProjectName res <- sequence $ writeProject <$> fmap (dir ) mfn <*> pure pj case res of Just _ -> return Success Nothing -> return Failure ---- workDirectory :: IO String workDirectory = do homeDir <- getHomeDirectory return $ homeDir ".ttask" projectsDirectory :: IO String projectsDirectory = do homeDir <- getHomeDirectory return $ homeDir ".ttask" "projects" activeMemoryFile :: IO String activeMemoryFile = do workDir <- workDirectory return $ workDir "active" activeProjectName :: IO (Maybe String) activeProjectName = do fn <- activeMemoryFile exist <- doesFileExist fn if exist then readFile fn >>= return . Just else do writeFile fn "" return Nothing setActiveProject :: String -> IO Success setActiveProject id = do fn <- activeMemoryFile files <- findProjects if elem id files then do writeFile fn id return Success else return Failure ---- initDirectory :: IO () initDirectory = do workDirectory >>= createDirectoryIfMissing False projectsDirectory >>= createDirectoryIfMissing False initProjectFile :: String -> String -> IO () initProjectFile id name = do pj <- newProject name fn <- projectsDirectory >>= return . ( id) writeProject fn $ pj _ <- setActiveProject id --ファイル作成直後なので成功している気持ち…… return () findProjects :: IO [String] findProjects = do files <- getDirectoryContentsMay =<< projectsDirectory return . filter (\s -> s /= "." && s /= "..") $ fromMaybe [] files getDirectoryContentsMay :: String -> IO (Maybe [String]) getDirectoryContentsMay path = (return . Just =<< getDirectoryContents path) `catch` through where through :: SomeException -> IO (Maybe a) through _ = return Nothing ---- -- util infixl 8 >$< (>$<) :: (Monad m, Monad t, Traversable t) => (a -> m (t b)) -> t a -> m (t b) f >$< x = join <$> sequence (f <$> x)