hakyll/src/Hakyll/Core/ResourceProvider/Modified.hs

84 lines
3.3 KiB
Haskell
Raw Normal View History

2012-11-08 11:45:26 +00:00
--------------------------------------------------------------------------------
2012-11-09 15:34:45 +00:00
module Hakyll.Core.ResourceProvider.Modified
2012-11-08 11:45:26 +00:00
( resourceModified
, resourceModificationTime
) where
--------------------------------------------------------------------------------
2012-11-09 15:34:45 +00:00
import Control.Applicative ((<$>), (<*>))
import Control.Monad (when)
import qualified Crypto.Hash.MD5 as MD5
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
2012-11-08 11:45:26 +00:00
import Data.IORef
2012-11-09 15:34:45 +00:00
import qualified Data.Map as M
import Data.Time (UTCTime)
import System.Directory (getModificationTime)
2012-11-08 11:45:26 +00:00
--------------------------------------------------------------------------------
2012-11-09 15:34:45 +00:00
import Hakyll.Core.Identifier
import Hakyll.Core.ResourceProvider.Internal
import Hakyll.Core.ResourceProvider.MetadataCache
import Hakyll.Core.Store (Store)
import qualified Hakyll.Core.Store as Store
2012-11-08 11:45:26 +00:00
--------------------------------------------------------------------------------
-- | A resource is modified if it or its metadata has changed
2012-11-13 12:13:17 +00:00
resourceModified :: ResourceProvider -> Identifier -> IO Bool
2012-11-08 11:45:26 +00:00
resourceModified rp r
| not exists = return False
| otherwise = do
cache <- readIORef cacheRef
2012-11-09 15:34:45 +00:00
case M.lookup normalized cache of
2012-11-08 11:45:26 +00:00
Just m -> return m
Nothing -> do
-- Check if the actual file was modified, and do a recursive
-- call to check if the metadata file was modified
m <- (||)
2012-11-09 15:34:45 +00:00
<$> fileDigestModified store (toFilePath r)
2012-11-08 11:45:26 +00:00
<*> resourceModified rp (resourceMetadataResource r)
2012-11-09 15:34:45 +00:00
modifyIORef cacheRef (M.insert normalized m)
2012-11-08 11:45:26 +00:00
2012-11-08 12:50:08 +00:00
-- Important! (But ugly)
2012-11-08 11:45:26 +00:00
when m $ resourceInvalidateMetadataCache rp r
return m
where
2012-11-13 12:13:17 +00:00
normalized = setVersion Nothing r
2012-11-09 15:34:45 +00:00
exists = resourceExists rp r
store = resourceStore rp
cacheRef = resourceModifiedCache rp
2012-11-08 11:45:26 +00:00
--------------------------------------------------------------------------------
-- | Utility: Check if a the digest of a file was modified
fileDigestModified :: Store -> FilePath -> IO Bool
fileDigestModified store fp = do
-- Get the latest seen digest from the store, and calculate the current
-- digest for the
lastDigest <- Store.get store key
newDigest <- fileDigest fp
if Store.Found newDigest == lastDigest
-- All is fine, not modified
then return False
-- Resource modified; store new digest
else do
Store.set store key newDigest
return True
where
key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
--------------------------------------------------------------------------------
-- | Utility: Retrieve a digest for a given file
fileDigest :: FilePath -> IO B.ByteString
fileDigest = fmap MD5.hashlazy . BL.readFile
--------------------------------------------------------------------------------
2012-11-13 12:13:17 +00:00
resourceModificationTime :: Identifier -> IO UTCTime
2012-11-09 15:34:45 +00:00
resourceModificationTime = getModificationTime . toFilePath