module Webrexp.DirectoryNode( DirectoryNode
, toDirectoryNode
, currentDirectoryNode
) where
import Control.Exception
import Control.Monad.IO.Class
import System.Directory
import System.FilePath
import Webrexp.GraphWalker
import Webrexp.ResourcePath
import Webrexp.UnionNode
import Webrexp.WebContext
type FileName = String
newtype FullPath = FullPath String
deriving (Eq, Show)
data DirectoryNode =
Directory FullPath FileName
| File FullPath FileName
deriving (Eq, Show)
extractPath :: DirectoryNode -> FilePath
extractPath (Directory (FullPath a) _) = a
extractPath (File (FullPath a) _) = a
buildParentList :: FilePath -> [DirectoryNode]
buildParentList path = map directoryze nameFullName
where directoryList = splitDirectories path
nameFullName = zip directoryList $ scanl1 (</>) directoryList
directoryze (name, whole) =
Directory (FullPath whole) name
toDirectoryNode :: FilePath -> IO (Maybe (NodeContext DirectoryNode ResourcePath))
toDirectoryNode path = do
existing <- doesFileExist path
dirExist <- doesDirectoryExist path
let (wholePath, fname) = splitFileName path
parentPath = buildParentList wholePath
case (existing, dirExist) of
(_, True) -> return . Just $ NodeContext
{ parents = MutableHistory $ reverse parentPath
, this = Directory (FullPath path) fname
, rootRef = Local . extractPath $ head parentPath
}
(True, _) -> return . Just $ NodeContext
{ parents = MutableHistory $ reverse parentPath
, this = File (FullPath path) fname
, rootRef = Local . extractPath $ head parentPath
}
_ -> return Nothing
currentDirectoryNode :: IO (NodeContext DirectoryNode ResourcePath)
currentDirectoryNode = do
cwd <- getCurrentDirectory
node <- toDirectoryNode cwd
case node of
Nothing -> error "currentDirectoryNode : node is not a directory/file o_O"
Just s -> return s
instance PartialGraph DirectoryNode ResourcePath where
dummyElem = undefined
isResourceParseable _ (Local _) _ = True
isResourceParseable _ _ _ = False
parseResource _ _ _ = Nothing
instance GraphWalker DirectoryNode ResourcePath where
attribOf _ _ = Nothing
nameOf (Directory _ name) = Just name
nameOf (File _ name) = Just name
valueOf (File (FullPath fpath) _) = fpath
valueOf (Directory (FullPath fpath) _) = fpath
indirectLinks (File _ _) = []
indirectLinks (Directory _ _) = []
accessGraph _ _ = return AccessError
isHistoryMutable _ = True
childrenOf (File _ _) = return []
childrenOf (Directory (FullPath path) _) =
liftIO $ listDirectory path
listDirectory :: FilePath -> IO [DirectoryNode]
listDirectory fpath = do
content <- try $ getDirectoryContents fpath
case content of
Left (_ :: IOError) -> return []
Right lst ->
mapM (\path -> do
let wholePath = fpath </> path
isDir <- doesDirectoryExist wholePath
let f = if isDir then Directory else File
return $ f (FullPath wholePath) path)
$ filter (\a -> a /= "." && a /= "..") lst