Skip to content

Instantly share code, notes, and snippets.

@coodoo
Last active December 11, 2017 01:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coodoo/3be2e687b37e1ae4a10b8ca0a28616a8 to your computer and use it in GitHub Desktop.
Save coodoo/3be2e687b37e1ae4a10b8ca0a28616a8 to your computer and use it in GitHub Desktop.
module Main where
import Control.Monad.State
import System.Directory
import System.Exit
import System.FilePath
import Data.Time
data File = File
{ name :: FilePath
, date :: UTCTime
, size :: Integer
, content :: String
} deriving (Show)
data Dir = Dir
{ dirName :: FilePath
, dirDate :: UTCTime
, dirContent :: [FilePath]
} deriving (Show)
data Order = Desc | Asc
deriving (Eq)
k :: FilePath -> IO ([Dir], [File])
k root = do
isDir <- doesDirectoryExist root
unless isDir $ die "not a dir"
execStateT (list root) ([],[])
partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])
partitionM _ [] = return ([], [])
partitionM f (x:xs) = do
res <- f x
(as, bs) <- partitionM f xs
return ([x | res] ++ as, [x | not res] ++ bs)
list :: FilePath -> StateT ([Dir], [File]) IO ()
list path = do
dir <-
liftIO $
do
children <- listDirectory path
dt <- getModificationTime path
return Dir {dirName = path, dirContent = children, dirDate = dt}
modify (\(ds, fs) -> (dir : ds, fs))
let
filteredFiles = filter (not . (`elem` [".DS_Store", ".config", ".stack"])) $ dirContent dir
fullPaths = map (path </>) filteredFiles
(dirs, files) <- liftIO $ partitionM doesDirectoryExist fullPaths
forM_ dirs list
forM_ files $ \f -> do
file <- liftIO $ do
s <- getFileSize f
dt <- getModificationTime f
c <- readFile f
return File {name = f, date = dt, size = s, content = c}
modify (\(ds, fs) -> (ds, file:fs))
pretty :: Show a => [a] -> Order -> String -> IO ()
pretty src rev prefix = do
putStrLn $ "\n" ++ prefix ++ "\n"
if rev == Desc
then mapM_ print $ reverse src
else mapM_ print src
main :: IO ()
main = do
(d, f) <- k "aaa"
pretty d Desc "DIR:"
pretty f Asc "FILE:"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment