on 89f324f help sign in
82 lines 3.3 kB history raw
1--------------------------------------------------------------------------------
2module Hakyll.Core.Resource.Modified
3 ( resourceModified
4 , resourceModificationTime
5 ) where
8--------------------------------------------------------------------------------
9import Control.Applicative ((<$>), (<*>))
10import Control.Monad (when)
11import qualified Crypto.Hash.MD5 as MD5
12import qualified Data.ByteString as B
13import qualified Data.ByteString.Lazy as BL
14import Data.IORef
15import qualified Data.Map as M
16import Data.Time (UTCTime)
17import System.Directory (getModificationTime)
20--------------------------------------------------------------------------------
21import Hakyll.Core.Resource
22import Hakyll.Core.Resource.MetadataCache
23import Hakyll.Core.Resource.Provider.Internal
24import Hakyll.Core.Store (Store)
25import qualified Hakyll.Core.Store as Store
28--------------------------------------------------------------------------------
29-- | A resource is modified if it or its metadata has changed
30resourceModified :: ResourceProvider -> Resource -> IO Bool
31resourceModified rp r
32 | not exists = return False
33 | otherwise = do
34 cache <- readIORef cacheRef
35 case M.lookup r cache of
36 Just m -> return m
37 Nothing -> do
38 -- Check if the actual file was modified, and do a recursive
39 -- call to check if the metadata file was modified
40 m <- (||)
41 <$> fileDigestModified store (unResource r)
42 <*> resourceModified rp (resourceMetadataResource r)
43 modifyIORef cacheRef (M.insert r m)
45 -- Important!
46 when m $ resourceInvalidateMetadataCache rp r
48 return m
49 where
50 exists = resourceExists rp r
51 store = resourceStore rp
52 cacheRef = resourceModifiedCache rp
55--------------------------------------------------------------------------------
56-- | Utility: Check if a the digest of a file was modified
57fileDigestModified :: Store -> FilePath -> IO Bool
58fileDigestModified store fp = do
59 -- Get the latest seen digest from the store, and calculate the current
60 -- digest for the
61 lastDigest <- Store.get store key
62 newDigest <- fileDigest fp
63 if Store.Found newDigest == lastDigest
64 -- All is fine, not modified
65 then return False
66 -- Resource modified; store new digest
67 else do
68 Store.set store key newDigest
69 return True
70 where
71 key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
74--------------------------------------------------------------------------------
75-- | Utility: Retrieve a digest for a given file
76fileDigest :: FilePath -> IO B.ByteString
77fileDigest = fmap MD5.hashlazy . BL.readFile
80--------------------------------------------------------------------------------
81resourceModificationTime :: Resource -> IO UTCTime
82resourceModificationTime = getModificationTime . unResource