|
Packit |
4b2029 |
{-# LANGUAGE RankNTypes #-}
|
|
Packit |
4b2029 |
module Data.Conduit.Filesystem
|
|
Packit |
4b2029 |
( sourceDirectory
|
|
Packit |
4b2029 |
, sourceDirectoryDeep
|
|
Packit |
4b2029 |
) where
|
|
Packit |
4b2029 |
|
|
Packit |
4b2029 |
import Data.Conduit
|
|
Packit |
4b2029 |
import Control.Monad.Trans.Resource (MonadResource)
|
|
Packit |
4b2029 |
import Control.Monad.IO.Class (liftIO)
|
|
Packit |
4b2029 |
import System.FilePath (())
|
|
Packit |
4b2029 |
import qualified Data.Streaming.Filesystem as F
|
|
Packit |
4b2029 |
|
|
Packit |
4b2029 |
-- | Stream the contents of the given directory, without traversing deeply.
|
|
Packit |
4b2029 |
--
|
|
Packit |
4b2029 |
-- This function will return /all/ of the contents of the directory, whether
|
|
Packit |
4b2029 |
-- they be files, directories, etc.
|
|
Packit |
4b2029 |
--
|
|
Packit |
4b2029 |
-- Note that the generated filepaths will be the complete path, not just the
|
|
Packit |
4b2029 |
-- filename. In other words, if you have a directory @foo@ containing files
|
|
Packit |
4b2029 |
-- @bar@ and @baz@, and you use @sourceDirectory@ on @foo@, the results will be
|
|
Packit |
4b2029 |
-- @foo/bar@ and @foo/baz@.
|
|
Packit |
4b2029 |
--
|
|
Packit |
4b2029 |
-- Since 1.1.0
|
|
Packit |
4b2029 |
sourceDirectory :: MonadResource m => FilePath -> Producer m FilePath
|
|
Packit |
4b2029 |
sourceDirectory dir =
|
|
Packit |
4b2029 |
bracketP (F.openDirStream dir) F.closeDirStream go
|
|
Packit |
4b2029 |
where
|
|
Packit |
4b2029 |
go ds =
|
|
Packit |
4b2029 |
loop
|
|
Packit |
4b2029 |
where
|
|
Packit |
4b2029 |
loop = do
|
|
Packit |
4b2029 |
mfp <- liftIO $ F.readDirStream ds
|
|
Packit |
4b2029 |
case mfp of
|
|
Packit |
4b2029 |
Nothing -> return ()
|
|
Packit |
4b2029 |
Just fp -> do
|
|
Packit |
4b2029 |
yield $ dir fp
|
|
Packit |
4b2029 |
loop
|
|
Packit |
4b2029 |
|
|
Packit |
4b2029 |
-- | Deeply stream the contents of the given directory.
|
|
Packit |
4b2029 |
--
|
|
Packit |
4b2029 |
-- This works the same as @sourceDirectory@, but will not return directories at
|
|
Packit |
4b2029 |
-- all. This function also takes an extra parameter to indicate whether
|
|
Packit |
4b2029 |
-- symlinks will be followed.
|
|
Packit |
4b2029 |
--
|
|
Packit |
4b2029 |
-- Since 1.1.0
|
|
Packit |
4b2029 |
sourceDirectoryDeep :: MonadResource m
|
|
Packit |
4b2029 |
=> Bool -- ^ Follow directory symlinks
|
|
Packit |
4b2029 |
-> FilePath -- ^ Root directory
|
|
Packit |
4b2029 |
-> Producer m FilePath
|
|
Packit |
4b2029 |
sourceDirectoryDeep followSymlinks =
|
|
Packit |
4b2029 |
start
|
|
Packit |
4b2029 |
where
|
|
Packit |
4b2029 |
start :: MonadResource m => FilePath -> Producer m FilePath
|
|
Packit |
4b2029 |
start dir = sourceDirectory dir =$= awaitForever go
|
|
Packit |
4b2029 |
|
|
Packit |
4b2029 |
go :: MonadResource m => FilePath -> Producer m FilePath
|
|
Packit |
4b2029 |
go fp = do
|
|
Packit |
4b2029 |
ft <- liftIO $ F.getFileType fp
|
|
Packit |
4b2029 |
case ft of
|
|
Packit |
4b2029 |
F.FTFile -> yield fp
|
|
Packit |
4b2029 |
F.FTFileSym -> yield fp
|
|
Packit |
4b2029 |
F.FTDirectory -> start fp
|
|
Packit |
4b2029 |
F.FTDirectorySym
|
|
Packit |
4b2029 |
| followSymlinks -> start fp
|
|
Packit |
4b2029 |
| otherwise -> return ()
|
|
Packit |
4b2029 |
F.FTOther -> return ()
|