@@ -1,48 +1,40 @@
1−--------------------------------------------------------------------------------
2−-- | Interval-based implementation of preview polling
3−{-# LANGUAGE CPP #-}
41module Hakyll.Preview.Poll
5− ( previewPoll
2+ ( watchUpdates
63 ) where
74
8−
95--------------------------------------------------------------------------------
10−import Control.Applicative ((<$>))
11−import Control.Concurrent (threadDelay)
12−import Control.Monad (filterM)
13−#if MIN_VERSION_directory(1,2,0)
14−import Data.Time (getCurrentTime)
15−#else
16−import System.Time (getClockTime)
17−#endif
18−import System.Directory (doesFileExist, getModificationTime)
19−
6+import Filesystem.Path.CurrentOS (decodeString, encodeString)
7+import System.FSNotify (startManagerConf, watchTree,
8+ Event(..), WatchConfig(..))
209
2110--------------------------------------------------------------------------------
2211import Hakyll.Core.Configuration
2312
2413
14+
2515--------------------------------------------------------------------------------
26−-- | A preview thread that periodically recompiles the site.
27−previewPoll :: Configuration -- ^ Configuration
28− -> IO [FilePath] -- ^ Updating action
29− -> IO () -- ^ Can block forever
30−previewPoll _ update = do
31−#if MIN_VERSION_directory(1,2,0)
32− time <- getCurrentTime
33−#else
34− time <- getClockTime
35−#endif
36− loop time =<< update
16+-- | A thread that watches for updates in a 'providerDirectory' and recompiles
17+-- a site as soon as any changes occur
18+watchUpdates :: Configuration -> IO () -> IO ()
19+watchUpdates conf update = do
20+ _ <- update
21+ manager <- startManagerConf (Debounce 0.1)
22+ watchTree manager path (not . isRemove) update'
3723 where
38− delay = 1000000
39− loop time files = do
40− threadDelay delay
41− files' <- filterM doesFileExist files
42− filesTime <- case files' of
43− [] -> return time
44− _ -> maximum <$> mapM getModificationTime files'
45−
46− if filesTime > time || files' /= files
47− then loop filesTime =<< update
48− else loop time files'
24+ path = decodeString $ providerDirectory conf
25+ update' evt = do
26+ ignore <- shouldIgnoreFile conf $ eventPath evt
27+ if ignore then return () else update
28+
29+
30+eventPath :: Event -> FilePath
31+eventPath evt = encodeString $ evtPath evt
32+ where
33+ evtPath (Added p _) = p
34+ evtPath (Modified p _) = p
35+ evtPath (Removed p _) = p
36+
37+
38+isRemove :: Event -> Bool
39+isRemove (Removed _ _) = True
40+isRemove _ = False