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