2014-04-09 04:54:27 +00:00
|
|
|
module Propellor.Property.Scheduled
|
|
|
|
( period
|
2014-04-09 05:15:11 +00:00
|
|
|
, periodParse
|
2014-04-09 04:54:27 +00:00
|
|
|
, Recurrance(..)
|
|
|
|
, WeekDay
|
|
|
|
, MonthDay
|
|
|
|
, YearDay
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Propellor
|
|
|
|
import Utility.Scheduled
|
|
|
|
|
|
|
|
import Data.Time.Clock
|
|
|
|
import Data.Time.LocalTime
|
|
|
|
import qualified Data.Map as M
|
|
|
|
|
|
|
|
-- | Makes a Property only be checked every so often.
|
|
|
|
--
|
|
|
|
-- This uses the description of the Property to keep track of when it was
|
|
|
|
-- last run.
|
|
|
|
period :: Property -> Recurrance -> Property
|
2014-04-18 08:48:49 +00:00
|
|
|
period prop recurrance = flip describe desc $ adjustProperty prop $ \satisfy -> do
|
2014-04-10 21:22:32 +00:00
|
|
|
lasttime <- liftIO $ getLastChecked (propertyDesc prop)
|
|
|
|
nexttime <- liftIO $ fmap startTime <$> nextTime schedule lasttime
|
|
|
|
t <- liftIO localNow
|
2014-04-09 04:54:27 +00:00
|
|
|
if Just t >= nexttime
|
|
|
|
then do
|
2014-04-18 08:48:49 +00:00
|
|
|
r <- satisfy
|
2014-04-10 21:22:32 +00:00
|
|
|
liftIO $ setLastChecked t (propertyDesc prop)
|
2014-04-09 04:54:27 +00:00
|
|
|
return r
|
|
|
|
else noChange
|
|
|
|
where
|
|
|
|
schedule = Schedule recurrance AnyTime
|
2014-04-09 05:15:11 +00:00
|
|
|
desc = propertyDesc prop ++ " (period " ++ fromRecurrance recurrance ++ ")"
|
|
|
|
|
|
|
|
-- | Like period, but parse a human-friendly string.
|
|
|
|
periodParse :: Property -> String -> Property
|
|
|
|
periodParse prop s = case toRecurrance s of
|
|
|
|
Just recurrance -> period prop recurrance
|
2014-04-18 07:59:06 +00:00
|
|
|
Nothing -> property "periodParse" $ do
|
2014-04-10 21:22:32 +00:00
|
|
|
liftIO $ warningMessage $ "failed periodParse: " ++ s
|
2014-04-09 05:15:11 +00:00
|
|
|
noChange
|
2014-04-09 04:54:27 +00:00
|
|
|
|
|
|
|
lastCheckedFile :: FilePath
|
|
|
|
lastCheckedFile = localdir </> ".lastchecked"
|
|
|
|
|
|
|
|
getLastChecked :: Desc -> IO (Maybe LocalTime)
|
|
|
|
getLastChecked desc = M.lookup desc <$> readLastChecked
|
|
|
|
|
|
|
|
localNow :: IO LocalTime
|
|
|
|
localNow = do
|
|
|
|
now <- getCurrentTime
|
|
|
|
tz <- getTimeZone now
|
|
|
|
return $ utcToLocalTime tz now
|
|
|
|
|
|
|
|
setLastChecked :: LocalTime -> Desc -> IO ()
|
|
|
|
setLastChecked time desc = do
|
|
|
|
m <- readLastChecked
|
|
|
|
writeLastChecked (M.insert desc time m)
|
|
|
|
|
|
|
|
readLastChecked :: IO (M.Map Desc LocalTime)
|
|
|
|
readLastChecked = fromMaybe M.empty <$> catchDefaultIO Nothing go
|
|
|
|
where
|
2014-04-11 05:53:37 +00:00
|
|
|
go = readish <$> readFileStrict lastCheckedFile
|
2014-04-09 04:54:27 +00:00
|
|
|
|
|
|
|
writeLastChecked :: M.Map Desc LocalTime -> IO ()
|
|
|
|
writeLastChecked = writeFile lastCheckedFile . show
|