Dedupe path pieces in yesod-static

This commit is contained in:
Michael Snoyman 2013-04-18 22:59:40 +03:00
parent 13715075f4
commit 91757320f3

View File

@ -61,6 +61,8 @@ import Language.Haskell.TH.Syntax
import Crypto.Conduit (hashFile, sinkHash) import Crypto.Conduit (hashFile, sinkHash)
import Crypto.Hash.MD5 (MD5) import Crypto.Hash.MD5 (MD5)
import Control.Monad.Trans.State
import Control.Monad.IO.Class (liftIO)
import qualified Data.ByteString.Base64 import qualified Data.ByteString.Base64
import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Char8 as S8
@ -157,18 +159,34 @@ notHidden s =
_ -> True _ -> True
getFileListPieces :: Prelude.FilePath -> IO [[String]] getFileListPieces :: Prelude.FilePath -> IO [[String]]
getFileListPieces = flip go id getFileListPieces = flip evalStateT M.empty . flip go id
where where
go :: String -> ([String] -> [String]) -> IO [[String]] go :: String
-> ([String] -> [String])
-> StateT (M.Map String String) IO [[String]]
go fp front = do go fp front = do
allContents <- filter notHidden `fmap` getDirectoryContents fp allContents <- liftIO $ filter notHidden `fmap` getDirectoryContents fp
let fullPath :: String -> String let fullPath :: String -> String
fullPath f = fp ++ '/' : f fullPath f = fp ++ '/' : f
files <- filterM (doesFileExist . fullPath) allContents files <- liftIO $ filterM (doesFileExist . fullPath) allContents
let files' = map (front . return) files let files' = map (front . return) files
dirs <- filterM (doesDirectoryExist . fullPath) allContents files'' <- mapM dedupe files'
dirs <- liftIO $ filterM (doesDirectoryExist . fullPath) allContents
dirs' <- mapM (\f -> go (fullPath f) (front . (:) f)) dirs dirs' <- mapM (\f -> go (fullPath f) (front . (:) f)) dirs
return $ concat $ files' : dirs' return $ concat $ files'' : dirs'
-- Reuse data buffers for identical strings
dedupe :: [String] -> StateT (M.Map String String) IO [String]
dedupe = mapM dedupe'
dedupe' :: String -> StateT (M.Map String String) IO String
dedupe' s = do
m <- get
case M.lookup s m of
Just s' -> return s'
Nothing -> do
put $ M.insert s s m
return s
-- | Template Haskell function that automatically creates routes -- | Template Haskell function that automatically creates routes
-- for all of your static files. -- for all of your static files.