2013-11-12 18:54:02 +00:00
|
|
|
{- Win32-notify interface
|
|
|
|
-
|
2015-01-21 16:50:09 +00:00
|
|
|
- Copyright 2013 Joey Hess <id@joeyh.name>
|
2013-11-12 18:54:02 +00:00
|
|
|
-
|
2014-05-10 14:01:27 +00:00
|
|
|
- License: BSD-2-clause
|
2013-11-12 18:54:02 +00:00
|
|
|
-}
|
|
|
|
|
2019-11-21 19:38:06 +00:00
|
|
|
module Utility.DirWatcher.Win32Notify (watchDir) where
|
2013-11-12 18:54:02 +00:00
|
|
|
|
2023-03-21 22:22:41 +00:00
|
|
|
import Common
|
2013-11-12 18:54:02 +00:00
|
|
|
import Utility.DirWatcher.Types
|
2023-03-03 16:58:39 +00:00
|
|
|
import qualified Utility.RawFilePath as R
|
2013-11-12 18:54:02 +00:00
|
|
|
|
|
|
|
import System.Win32.Notify
|
2023-03-06 16:15:53 +00:00
|
|
|
import System.PosixCompat.Files (isRegularFile)
|
2013-11-12 18:54:02 +00:00
|
|
|
|
2014-03-05 21:44:14 +00:00
|
|
|
watchDir :: FilePath -> (FilePath -> Bool) -> Bool -> WatchHooks -> IO WatchManager
|
|
|
|
watchDir dir ignored scanevents hooks = do
|
2013-11-12 18:54:02 +00:00
|
|
|
scan dir
|
|
|
|
wm <- initWatchManager
|
2014-12-29 21:25:59 +00:00
|
|
|
void $ watchDirectory wm dir True [Create, Delete, Modify, Move] dispatch
|
2013-11-12 21:17:50 +00:00
|
|
|
return wm
|
2013-11-12 18:54:02 +00:00
|
|
|
where
|
2014-12-29 21:25:59 +00:00
|
|
|
dispatch evt
|
2013-11-12 18:54:02 +00:00
|
|
|
| ignoredPath ignored (filePath evt) = noop
|
2013-11-12 21:17:50 +00:00
|
|
|
| otherwise = case evt of
|
|
|
|
(Deleted _ _)
|
2013-11-12 18:54:02 +00:00
|
|
|
| isDirectory evt -> runhook delDirHook Nothing
|
|
|
|
| otherwise -> runhook delHook Nothing
|
2013-11-12 21:17:50 +00:00
|
|
|
(Created _ _)
|
2013-11-12 18:54:02 +00:00
|
|
|
| isDirectory evt -> noop
|
|
|
|
| otherwise -> runhook addHook Nothing
|
2013-11-12 21:17:50 +00:00
|
|
|
(Modified _ _)
|
2013-11-12 18:54:02 +00:00
|
|
|
| isDirectory evt -> noop
|
|
|
|
{- Add hooks are run when a file is modified for
|
2023-03-14 02:39:16 +00:00
|
|
|
- compatibility with INotify, which calls the add
|
2013-11-12 18:54:02 +00:00
|
|
|
- hook when a file is closed, and so tends to call
|
|
|
|
- both add and modify for file modifications. -}
|
|
|
|
| otherwise -> do
|
2013-11-12 21:17:50 +00:00
|
|
|
runhook addHook Nothing
|
|
|
|
runhook modifyHook Nothing
|
2013-11-12 18:54:02 +00:00
|
|
|
where
|
|
|
|
runhook h s = maybe noop (\a -> a (filePath evt) s) (h hooks)
|
|
|
|
|
|
|
|
scan d = unless (ignoredPath ignored d) $
|
2023-08-15 16:57:41 +00:00
|
|
|
mapM_ go =<< emptyWhenDoesNotExist (dirContentsRecursiveSkipping (const False) False d)
|
2013-11-12 18:54:02 +00:00
|
|
|
where
|
|
|
|
go f
|
|
|
|
| ignoredPath ignored f = noop
|
|
|
|
| otherwise = do
|
|
|
|
ms <- getstatus f
|
|
|
|
case ms of
|
|
|
|
Nothing -> noop
|
|
|
|
Just s
|
2023-03-01 19:55:58 +00:00
|
|
|
| isRegularFile s ->
|
2014-03-05 21:44:14 +00:00
|
|
|
when scanevents $
|
|
|
|
runhook addHook ms
|
2013-11-12 18:54:02 +00:00
|
|
|
| otherwise ->
|
|
|
|
noop
|
|
|
|
where
|
|
|
|
runhook h s = maybe noop (\a -> a f s) (h hooks)
|
|
|
|
|
2023-03-06 16:15:53 +00:00
|
|
|
getstatus = catchMaybeIO . R.getFileStatus . toRawFilePath
|
2013-11-12 18:54:02 +00:00
|
|
|
|
|
|
|
{- Check each component of the path to see if it's ignored. -}
|
|
|
|
ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool
|
|
|
|
ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
|