@@ -1,5 +1,6 @@
11--------------------------------------------------------------------------------
2−{-# LANGUAGE CPP #-}
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE DeriveDataTypeable #-}
34module Hakyll.Core.Provider.Modified
45 ( resourceModified
56 , resourceModificationTime
@@ -9,12 +10,12 @@ module Hakyll.Core.Provider.Modified
910--------------------------------------------------------------------------------
1011import Control.Applicative ((<$>), (<*>))
1112import Control.Monad (when)
12−import qualified Crypto.Hash.MD5 as MD5
13−import qualified Data.ByteString as B
14−import qualified Data.ByteString.Lazy as BL
13+import Data.Binary (Binary (..))
1514import Data.IORef
1615import qualified Data.Map as M
17−import Data.Time (UTCTime)
16+import Data.Time (Day (..), UTCTime (..),
17+ secondsToDiffTime)
18+import Data.Typeable (Typeable)
1819import System.Directory (getModificationTime)
1920
2021
@@ -48,7 +49,7 @@ resourceModified p r
4849 -- Check if the actual file was modified, and do a recursive
4950 -- call to check if the metadata file was modified
5051 m <- (||)
51− <$> fileDigestModified store filePath
52+ <$> fileModified store filePath
5253 <*> resourceModified p (resourceMetadataResource r)
5354 modifyIORef cacheRef (M.insert normalized m)
5455
@@ -65,37 +66,50 @@ resourceModified p r
6566
6667
6768--------------------------------------------------------------------------------
68−-- | Utility: Check if a the digest of a file was modified
69−fileDigestModified :: Store -> FilePath -> IO Bool
70−fileDigestModified store fp = do
71− -- Get the latest seen digest from the store, and calculate the current
72− -- digest for the
73− lastDigest <- Store.get store key
74− newDigest <- fileDigest fp
75− if Store.Found newDigest == lastDigest
69+-- | Utility: Check if a file was modified recently
70+fileModified :: Store -> FilePath -> IO Bool
71+fileModified store fp = do
72+ lastModified <- Store.get store key
73+ newModified <- BinaryTime <$> fileModificationTime fp
74+ if maybe False (>= newModified) (Store.toMaybe lastModified)
7675 -- All is fine, not modified
7776 then return False
7877 -- Resource modified; store new digest
7978 else do
80− Store.set store key newDigest
79+ Store.set store key newModified
8180 return True
8281 where
8382 key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
8483
8584
8685--------------------------------------------------------------------------------
87−-- | Utility: Retrieve a digest for a given file
88−fileDigest :: FilePath -> IO B.ByteString
89−fileDigest = fmap MD5.hashlazy . BL.readFile
86+resourceModificationTime :: Provider -> Identifier -> IO UTCTime
87+resourceModificationTime p i = fileModificationTime $ resourceFilePath p i
9088
9189
9290--------------------------------------------------------------------------------
93−resourceModificationTime :: Provider -> Identifier -> IO UTCTime
94−resourceModificationTime p i = do
91+fileModificationTime :: FilePath -> IO UTCTime
92+fileModificationTime fp = do
9593#if MIN_VERSION_directory(1,2,0)
96− getModificationTime $ resourceFilePath p i
94+ getModificationTime fp
9795#else
98− ct <- toCalendarTime =<< getModificationTime (resourceFilePath p i)
96+ ct <- toCalendarTime =<< getModificationTime fp
9997 let str = formatCalendarTime defaultTimeLocale "%s" ct
10098 return $ readTime defaultTimeLocale "%s" str
10199#endif
100+
101+
102+--------------------------------------------------------------------------------
103+-- | Because UTCTime doesn't have a Binary instance...
104+newtype BinaryTime = BinaryTime UTCTime
105+ deriving (Eq, Ord, Typeable)
106+
107+
108+--------------------------------------------------------------------------------
109+instance Binary BinaryTime where
110+ put (BinaryTime (UTCTime (ModifiedJulianDay d) dt)) =
111+ put d >> put (floor dt :: Integer)
112+
113+ get = fmap BinaryTime $ UTCTime
114+ <$> (ModifiedJulianDay <$> get)
115+ <*> (secondsToDiffTime <$> get)