@@ -1,5 +1,6 @@
1--------------------------------------------------------------------------------
1--------------------------------------------------------------------------------
2−{-# LANGUAGE CPP #-}
2+{-# LANGUAGE CPP #-}
3+{-# LANGUAGE DeriveDataTypeable #-}
3module Hakyll.Core.Provider.Modified
4module Hakyll.Core.Provider.Modified
4 ( resourceModified
5 ( resourceModified
5 , resourceModificationTime
6 , resourceModificationTime
@@ -9,12 +10,12 @@ module Hakyll.Core.Provider.Modified
9--------------------------------------------------------------------------------
10--------------------------------------------------------------------------------
10import Control.Applicative ((<$>), (<*>))
11import Control.Applicative ((<$>), (<*>))
11import Control.Monad (when)
12import Control.Monad (when)
12−import qualified Crypto.Hash.MD5 as MD5
13+import Data.Binary (Binary (..))
13−import qualified Data.ByteString as B
14−import qualified Data.ByteString.Lazy as BL
15import Data.IORef
14import Data.IORef
16import qualified Data.Map as M
15import qualified Data.Map as M
17−import Data.Time (UTCTime)
16+import Data.Time (Day (..), UTCTime (..),
18+import Data.Typeable (Typeable)
18import System.Directory (getModificationTime)
19import System.Directory (getModificationTime)
@@ -48,7 +49,7 @@ resourceModified p r
48 -- Check if the actual file was modified, and do a recursive
49 -- Check if the actual file was modified, and do a recursive
49 -- call to check if the metadata file was modified
50 -- call to check if the metadata file was modified
51− <$> fileDigestModified store filePath
52+ <$> fileModified store filePath
52 <*> resourceModified p (resourceMetadataResource r)
53 <*> resourceModified p (resourceMetadataResource r)
53 modifyIORef cacheRef (M.insert normalized m)
54 modifyIORef cacheRef (M.insert normalized m)
@@ -65,37 +66,50 @@ resourceModified p r
67--------------------------------------------------------------------------------
68--------------------------------------------------------------------------------
68−-- | Utility: Check if a the digest of a file was modified
69+-- | Utility: Check if a file was modified recently
69−fileDigestModified :: Store -> FilePath -> IO Bool
70+fileModified :: Store -> FilePath -> IO Bool
70−fileDigestModified store fp = do
71+fileModified store fp = do
71− -- Get the latest seen digest from the store, and calculate the current
73− lastDigest <- Store.get store key
72+ lastModified <- Store.get store key
74− newDigest <- fileDigest fp
73+ newModified <- BinaryTime <$> fileModificationTime fp
75− if Store.Found newDigest == lastDigest
74+ if maybe False (>= newModified) (Store.toMaybe lastModified)
76 -- All is fine, not modified
75 -- All is fine, not modified
77 then return False
76 then return False
78 -- Resource modified; store new digest
77 -- Resource modified; store new digest
80− Store.set store key newDigest
79+ Store.set store key newModified
81 return True
80 return True
83 key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
82 key = ["Hakyll.Core.Resource.Provider.fileModified", fp]
86--------------------------------------------------------------------------------
85--------------------------------------------------------------------------------
87−-- | Utility: Retrieve a digest for a given file
86+resourceModificationTime :: Provider -> Identifier -> IO UTCTime
88−fileDigest :: FilePath -> IO B.ByteString
87+resourceModificationTime p i = fileModificationTime $ resourceFilePath p i
89−fileDigest = fmap MD5.hashlazy . BL.readFile
92--------------------------------------------------------------------------------
90--------------------------------------------------------------------------------
93−resourceModificationTime :: Provider -> Identifier -> IO UTCTime
91+fileModificationTime :: FilePath -> IO UTCTime
94−resourceModificationTime p i = do
92+fileModificationTime fp = do
95#if MIN_VERSION_directory(1,2,0)
93#if MIN_VERSION_directory(1,2,0)
96− getModificationTime $ resourceFilePath p i
94+ getModificationTime fp
98− ct <- toCalendarTime =<< getModificationTime (resourceFilePath p i)
96+ ct <- toCalendarTime =<< getModificationTime fp
99 let str = formatCalendarTime defaultTimeLocale "%s" ct
97 let str = formatCalendarTime defaultTimeLocale "%s" ct
100 return $ readTime defaultTimeLocale "%s" str
98 return $ readTime defaultTimeLocale "%s" str
102+--------------------------------------------------------------------------------
103+-- | Because UTCTime doesn't have a Binary instance...
104+newtype BinaryTime = BinaryTime UTCTime
105+ deriving (Eq, Ord, Typeable)
108+--------------------------------------------------------------------------------
109+instance Binary BinaryTime where
110+ put (BinaryTime (UTCTime (ModifiedJulianDay d) dt)) =
111+ put d >> put (floor dt :: Integer)
113+ get = fmap BinaryTime $ UTCTime
114+ <$> (ModifiedJulianDay <$> get)
115+ <*> (secondsToDiffTime <$> get)