dbmonitor-0.1.0: src/Monitor/Configuration/Read.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ImplicitParams #-}
module Monitor.Configuration.Read
( readMonitor
, notHidden
, isCheck
, collectMonitors
)
where
import Control.Concurrent
import System.Directory
import System.FilePath
import System.FSNotify
import Monitor.Configuration.Config
import Monitor.DataModel
collectMonitors :: FilePath -> IO [FilePath]
collectMonitors configDir = do
mDatabaseDirs <- listDirectory configDir
relativePaths <- filterM doesDirectoryExist
(map (configDir </>) . filter notHidden $ mDatabaseDirs)
currentDir <- getCurrentDirectory
return $ map (currentDir </>) relativePaths
tryReadConfig :: (?mutex :: Mutexes) => FilePath -> MVar () -> String -> IO Settings
tryReadConfig dir configChange tgvar = do
takeMVar configChange
readConfig dir configChange tgvar
readConfig :: (?mutex :: Mutexes) => FilePath -> MVar () -> String -> IO Settings
readConfig dir configChange tgvar = do
let configPath = dir </> configName
configExists <- doesFileExist configPath
if configExists
then do
mSettings <- readSettings dir tgvar configPath
case mSettings of
Nothing -> tryReadConfig dir configChange tgvar
Just cfg -> return cfg
else tryReadConfig dir configChange tgvar
modifiedCfg :: MVar () -> Event -> IO ()
modifiedCfg mvar _ = putMVar mvar ()
readConfigTillSuccess :: (?mutex :: Mutexes)
=> WatchManager -> FilePath -> String -> MVar () -> IO Settings
readConfigTillSuccess cfgManager dir tgvar configChange = do
removeWatch <- watchDir cfgManager dir (const True)
(modifiedCfg configChange)
cfg <- readConfig dir configChange tgvar
logMessage $ "Successfully read configuration at " <> dir
removeWatch
return cfg
notHidden :: FilePath -> Bool
notHidden ('.':_) = False
notHidden _ = True
isCheck :: FilePath -> Bool
isCheck f = notHidden f && not (representsConfigName f) -- && takeExtension f == ".sql"
readInitialData :: FilePath -> IO [FilePath]
readInitialData dir = do
contents <- listDirectory dir
files <- filterM doesFileExist . map (dir </>) . filter isCheck $ contents
subdirs <- filterM doesDirectoryExist . map (dir </>) . filter notHidden $ contents
relativePaths <- case subdirs of
[] -> return files
lst -> mapM (readInitialData) lst
>>= \nested -> return (files ++ concat nested)
currentDir <- getCurrentDirectory
return $ map (currentDir </>) relativePaths
readMonitor :: (?mutex :: Mutexes) => FilePath -> String -> IO (Settings, [FilePath])
readMonitor dir tgvar = do
configReadMVar <- newEmptyMVar
cfg <- withManager (\cfgManager -> readConfigTillSuccess cfgManager dir tgvar configReadMVar)
checks <- readInitialData dir
return (cfg, checks)